我应该为每个线程创建一个连接吗?

时间:2017-12-19 14:06:12

标签: java multithreading rabbitmq

我正在运行2个多线程程序。

来自第一个程序的每个线程充当生产者并将消息写入队列,而来自第二个程序的每个线程充当消费者并从同一队列中读取消息。

在这两个项目中,我创建了一个连接工厂,如下所示:

ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setAutomaticRecoveryEnabled(true);
factory.setRequestedChannelMax(0);
factory.setUsername("user");
factory.setPassword("password");

但是我不确定下一步的推荐方法。

  1. 我应该在每个线程的开头创建一个新连接,如:

    Connection connection = factory.newConnection();
    

    然后为每个请求创建一个新的频道,如:

    Channel channel = connection.createChannel();
    
  2. 或者我应该只创建一个连接,让线程共享相同的连接,然后为每个请求创建一个新的通道。

  3. 我知道连接是套接字线程安全连接,应该仔细创建。我只是询问在我的程序中是否有推荐的方法,因为通常文档会包含一种处理连接和套接字的推荐方法,但我在RabbitMQ的文档中找不到这样的答案。

2 个答案:

答案 0 :(得分:3)

使用您的选项2. Rabbit MQ可以在每个进程共享一个连接,因此除非您连接到多个代理或具有极端负载配置文件,否则在您的进程中的所有线程之间共享一个长期存在的连接就足够了。要获得连接relatively expensive (80% of the way down),因此短暂的连接会妨碍生产者的表现。

连接是thread safe - 在内部,RabbitMQ客户端在一个连接上复用多个通道,允许同时使用连接。

即。您可以将Connection用作"频道工厂" 。但是,频道不是线程安全的,因此您通常会创建一个短期频道,产生一条消息,并关闭制作人的频道(频道很便宜)。

根据建议,在生产者上,而不是直接将消息发送到队列,而是将消息发布到Exchange(即跳到'publish-subscribe'教程)。这样,除了MSMQ / MQSeries等旧中间件使用的经典点对点机制之外,您还可以使用其他路由拓扑。

答案 1 :(得分:-1)

如文档中所述:

  • For Connection:
  

当前实现对于客户端API处的代码是线程安全的   level,实际上是内部线程安全的,除了RPC中的代码   调用。   https://www.rabbitmq.com/releases/rabbitmq-java-client/current-javadoc/com/rabbitmq/client/Connection.html

  • 对于频道:
  

根据经验,在线程之间共享Channel实例是   要避免的事情。应用程序应该更喜欢使用频道   每个线程而不是跨多个共享相同的频道   线程。

     

https://www.rabbitmq.com/api-guide.html部分频道和   并发注意事项(线程安全)

因此,Connection是线程安全的,Channel不是