一. Channel
- 在多个线程之间共享channel, 然后并发的pubish数据是不可行的.
原因是同一个channel并行push会导致publisher confirm的错乱; 因此应该每个线程独享自己的channel, 在调用Channel#basicPublish
的代码中显式的使用synchronized(至少应该注意不要共享channel). - 可以使用池化技术, 产生一个channel池, 每个线程从池中获取一个channel, 使用完后归还给池子. 推荐使用已存在的pooling library
- 也不应该对每条消息打开一次channel, 那将毫无效率可言
二. Consumer
-
每个consumer都有一个consumer tag来唯一标识自己. 同样不应该在多个线程之间共享consumer, 否则会使监控数据混乱. consumer tag用来关闭consumer
-
consumer只能对应一个queue, 而publisher可以在同一个connection上的创建多个channel然后并行发送消息; 而Consumer即使使用多个channel并行消费queue, 同一时刻也只会有1个channel可以消费数据(这保证了消息的顺序性)
-
如果想让多个consumer一起消费数据, 那就应该设置多个queue, producer发送到不同queue中, 然后每个consumer消费一个queue
-
其实, 如果rabbitmq真的设计成多个consumer对应1个queue, 就会造成数据乱序, 或者是当ack确认超时, 有吧消息发到另一个consumer, 导致重复消费等一系列问题
网友评论