这里创建一个direct类型的交换机,两个路由key,一个error,一个info,两个队列,一个队列只绑定error,一个队列绑定error和info,向error和info各发10条消息。
执行代码:
查看RabbitMQ管理界面,direct_errorlog队列10条,而direct_alllog有20条,因为direct_alllog队列两个routingKey的消息都进去了。
点进去看下两个队列绑定的交换机和routingKey
消费者代码:
消费者和工作队列一样,只需根据队列名消费即可,这里只消费direct_errorlog队列作示例
public static void DirectConsumer() { string queueName = "direct_errorlog"; var connection = RabbitMQHelper.GetConnection(); { //创建信道 var channel = connection.CreateModel(); { //创建队列 channel.QueueDeclare(queueName, durable: true, exclusive: false, autoDelete: false, arguments: null); var consumer = new EventingBasicConsumer(channel); ///prefetchCount:1来告知RabbitMQ,不要同时给一个消费者推送多于 N 个消息,也确保了消费速度和性能 ///global:是否设为全局的 ///prefetchSize:单条消息大小,通常设0,表示不做限制 //是autoAck=false才会有效 channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: true); int i = 1; consumer.Received += (model, ea) => { //处理业务 var message = Encoding.UTF8.GetString(ea.Body.ToArray()); Console.WriteLine($"{i},队列{queueName}消费消息长度:{message.Length}"); channel.BasicAck(ea.DeliveryTag, false); //消息ack确认,告诉mq这条队列处理完,可以从mq删除了 i++; }; channel.BasicConsume(queueName, autoAck: false, consumer); } } }
普通场景中推荐使用路由模式,因为路由模式有交换机,有路由key,能够更好的拓展各种应用场景。
(5)主题模式topics(主题)模式跟routing路由模式类似,只不过路由模式是指定固定的路由键 routingKey,而主题模式是可以模糊匹配路由键 routingKey,类似于SQL中 = 和 like 的关系。
P 表示为生产者、 X 表示交换机、C1C2 表示为消费者,红色表示队列。
topics 模式与 routing 模式比较相近,topics 模式不能具有任意的 routingKey,必须由一个英文句点号“.”分隔的字符串(我们将被句点号“.”分隔开的每一段独立的字符串称为一个单词),比如 "lazy.orange.a"。topics routingKey 中可以存在两种特殊字符"*"与“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)。
以上图为例:
如果发送消息的routingKey设置为:
aaa.orange.rabbit,那么消息会路由到Q1与Q2,
routingKey=aaa.orange.bb的消息会路由到Q1,
routingKey=lazy.aa.bb.cc的消息会路由到Q2;
routingKey=lazy.aa.rabbit的消息会路由到 Q2(只会投递给Q2一次,虽然这个routingKey 与 Q2 的两个 bindingKey 都匹配);
没匹配routingKey的消息将会被丢弃。
生产者代码: