我正在运行2个多线程程序。
来自第一个程序的每个线程充当生产者并将消息写入队列,而来自第二个程序的每个线程充当消费者并从同一队列中读取消息。
在这两个项目中,我创建了一个连接工厂,如下所示:
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setAutomaticRecoveryEnabled(true);
factory.setRequestedChannelMax(0);
factory.setUsername("user");
factory.setPassword("password");
但是我不确定下一步的推荐方法。
Connection connection = factory.newConnection();
然后为每个请求创建一个新的渠道,如:
Channel channel = connection.createChannel();
我知道连接是套接字线程安全连接,应该仔细创建。我只是询问是否有推荐的方法在我的程序中使用,因为通常文档会包含一种处理连接和套接字的推荐方法,但我在RabbitMQ的文档中找不到这样的答案。
使用您的选项2. Rabbit MQ可以与每个进程共享一个连接,因此除非您连接到多个代理或具有极端负载配置文件,否则在您的进程中的所有线程之间共享一个长期存在的连接就足够了。连接是relatively expensive (80% of the way down)获得,因此短暂的连接将阻碍生产者的表现。
连接是thread safe - 在内部,RabbitMQ客户端在单个连接上复用多个通道,允许并发使用连接。
即您可以将Connection用作“频道工厂”。但是,Channels不是线程安全的,因此您通常会创建一个短期通道,生成一条消息,并关闭生产者的通道(通道很便宜)。
根据建议,在生产者上,而不是直接将消息发送到队列,而是将消息发布到Exchange(即跳转到'publish-subscribe'教程)。这样,除了MSMQ / MQSeries等旧中间件使用的经典点对点机制之外,您还可以使用其他路由拓扑。
如文档中所述:
当前实现对于客户端API级别的代码是线程安全的,并且实际上是内部线程安全的,除了RPC调用中的代码。 https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/Connection.html
根据经验,在线程之间共享Channel实例是值得避免的。应用程序应该更喜欢每个线程使用一个Channel,而不是跨多个线程共享相同的Channel。
https://www.rabbitmq.com/api-guide.html部分频道和并发注意事项(线程安全)
所以,Connection是线程安全的,Channel不是