消费者拒绝消息的方法:一、从RabbitMQ服务器断开连接。RabbitMQ将把消息重新入队并发送给另一个消费者。好处:所有RabbitMQ版本都支持。缺点:这样连接/断开连接的方式会额外增加RabbitMQ的负担。二、RabbitMQ 2.0.0或以上版本可使用AMQP的basic.reject命令。如果把reject命令的requeue参数设置为true,RabbitMQ会将消息重新发送给下一个订阅的消费者。如果设置为false,则会立即把消息从队列中移除,而不会把它发送给新的消费者(比如检测到一条格式错误的消息时)。你也可以通过对消息确认的方式来简单地忽略该消息。
4)队列
消费者从特定队列接收消息的方式:通过AMQP的basic.consume命令订阅;通过AMQP的basic.get命令从队列获得单条消息。
如果队列当前无人订阅,则消息会在队列中等待。当队列拥有多个消费者时,队列收到的消息将以循环的方式发送给消费者(负载均衡)。每条消息只会发送给一个订阅的消费者。
如何创建队列:通过AMQP的queue.declare命令。如果不指定队列名称,Rabbit会分配一个随机名称并在declare命令的响应中返回。如果消息不能丢失,则生产者和消费者都应该尝试去创建队列(发送出去的消息如果路由到了不存在的队列,Rabbit会忽略它们)。如果可以丢失,或你实现了一种方法来重新发布未处理的消息,则可以只让消费者创建队列。
5)交换器和绑定
生产者把消息发布到交换器上。然后,根据确定的规则(路由键),RabbitMQ将决定消息该投递到哪个队列。队列通过路由键绑定到交换器。当你把消息发送到代理服务器时,消息将拥有一个路由键(可能为空),RabbitMQ会将其和绑定使用的路由键进行匹配。如果匹配,则消息将投递到相应的队列。如果路由的消息不匹配任何绑定模式,则消息将进入“黑洞”。
有如下四种类型的交换器,每种类型实现了不同的路由算法:
(1)direct:如果路由键匹配,消息就被投递到对应的队列。服务器必须实现direct类型交换器,包含一个空白字符串名称的默认交换器。
(2)fanout:把消息投递给所有附加在此交换器上的队列(广播)。
(3)topic:使得来自不同源头的消息能够到达同一个队列。
(4)headers:允许你匹配AMQP消息的header而非路由键。除此之外,它和direct完全一致,但性能会差很多,因此不太实用,而且几乎再也用不到了。
6)虚拟主机(vhost):每一个RabbitMQ服务器都能创建虚拟消息服务器,我们称之为虚拟主机。
每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器和绑定。更重要的是,它拥有自己的权限机制(AMQP并没有指定权限控制是在vhost级别还是在服务器端级别实现。这留给了服务器的开发者去决定。在RabbitMQ的例子中,权限控制以vhost为单位)。这使得你能安全地使用一个RabbitMQ服务器来服务众多应用程序,因为各个vhost实例间实现了逻辑上的分离。另外,它还能避免队列和交换器的命名冲突。
当你在Rabbit里创建一个用户时,用户通常会被指派给至少一个vhost,并且只能访问被指派vhost内的队列、交换器和绑定。
创建vhost:rabbitmqctl add_vhost [vhost_name]。vhost创建成功后,就可以连接上去并添加队列和交换器了。
删除vhost:rabbitmqctl delete_vhost [vhost_name]。
查看Rabbit服务器上运行哪些vhost:rabbitmqctl list_vhosts。
参考资料:
《RabbitMQ实战:高效部署分布式消息队列》