RabbitMQ四:Routing

RabbitMQ四:Routing

上一篇博客构建了一个简单的日志系统,能够像多个接受者广播日志信息。

本文将添加一个功能,用以说明RabbitMQ中的Routing
只能订阅一部分消息,例如,我们只能将错误信息写入日志文件(以节省磁盘空间),同时在控制台打印所有日志消息。

直接交换

上一批文章中的日志记录系统向所有消费者广播消息,我们现在希望扩展它以允许根据消息的严重性过滤消息。例如,我们仅将严重错误的日志消息写入磁盘,警告或者信息日志则不写入。

我们将使用直接交换,直接交换背后的路由算法如下:消息进入队列,其绑定密钥与消息的路由密钥完全匹配。

image

如图,orange绑定Q1队列,black和green绑定Q2队列,使用路由密钥orange发布到交换机的消息将被路由到Q1。green和black则被路由到Q2。除此之外的其他消息将被丢弃。

多个绑定

image

使用相同的绑定密钥绑定多个队列是完全合法的。例子中,我们可以在X和Q1之间添加black的绑定。在这种情况下,直接交换将表现得像扇出一样,并将消息广播到所有匹配的队列。路由密钥为black的消息将传送到Q1和Q2。

发送日志

创建一个交换机:

channel.ExchangeDeclare(exchange:“direct_logs”,type:“direct”);

准备好发送消息:

var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: "direct_logs", routingKey: severity, basicProperties: null, body: body);

订阅

接收消息将像上一篇文章一样工作,但有一个例外:我们将为我们感兴趣的每个严重性创建一个新的绑定。

var queueName = channel.QueueDeclare().QueueName;
foreach (var severity in args)
{
    channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: severity);
}

示例

示例代码绑定规则如下:

image

代码:

EmitLogDirect

class EmitLogDirect
{
    static void Main(string[] args)
    {
        var factory = new ConnectionFactory() { HostName = "127.0.0.1" };
        using (var conncetion = factory.CreateConnection())
        using (var channel = conncetion.CreateModel())
        {
            channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");
            var severity = args.Length > 0 ? args[0] : "info";
            var message = (args.Length > 1) ? string.Join(" ", args.Skip(1).ToArray()) : "Hello World!";

            var body = Encoding.UTF8.GetBytes(message);
            channel.BasicPublish(exchange: "direct_logs", routingKey: severity, basicProperties: null, body: body);
            Console.WriteLine($" [x] Sent {severity}:{message}");
        }
        Console.WriteLine(" Press [enter] to exit");
        Console.ReadLine();
    }
}

ReceiveLogsDirect

class ReceiveLogsDirect
{
    static void Main(string[] args)
    {
        var factory = new ConnectionFactory() { HostName = "127.0.0.1" };
        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            channel.ExchangeDeclare(exchange: "direct_logs", type: "direct");
            var queueName = channel.QueueDeclare().QueueName;

            if (args.Length < 1)
            {
                Console.WriteLine($"Usage:{Environment.GetCommandLineArgs()[0]} [info] [warning] [error]");
                Console.WriteLine(" Press [entet] to exit.");
                Console.ReadLine();
                Environment.ExitCode = 1;
                return;
            }

            foreach (var severity in args)
            {
                channel.QueueBind(queue: queueName, exchange: "direct_logs", routingKey: severity);
            }
            Console.WriteLine(" [*] Waiting for message.");

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);
                var routingKey = ea.RoutingKey;
                Console.WriteLine($" [x] Received {routingKey}:{message}");
            };
            channel.BasicConsume(queue: queueName, autoAck: true, consumer: consumer);
            Console.ReadLine();
        }
    }
}

效果如下:

image

Routing

Github

发布了110 篇原创文章 · 获赞 36 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zhaobw831/article/details/81168226