java - ZeroMQ 多线程 : create sockets on-demand or use sockets object pool?

标签 java multithreading sockets connection-pooling zeromq

我正在构建一个利用 ZeroMQ N 对 N 发布/订阅模型的 POC。在我们的应用程序服务器中,当为 http 请求提供服务时,如果线程从数据库中提取数据,它会使用该数据更新本地内存缓存实例。为了同步应用服务器集群中的其他内存缓存实例,请求线程使用 ZMQ 发布器发送一条包含数据的消息...所以问题是:关于最小化套接字,什么策略最有效当应用程序有许多依赖套接字发送消息的线程时创建/销毁开销?我们是否共享一个套接字池,我们是否为每个线程创建/销毁套接字等?

策略 1 - 线程管理的发布者套接字
在这种方法中,每个线程 T1T2T3 通过创建套接字对象(发布者)来管理它的生命周期,使连接,发送消息,最后关闭套接字。基于this ,这当然是最安全的方法,但我们担心重复创建、连接和销毁套接字时的开销;如果开销对性能产生负面影响,我们希望避免它。

enter image description here

策略 2 - 发布者套接字对象池
在这种方法中,父进程(应用程序服务器)在启动时初始化 ZMQ 发布者池。当一个线程需要一个发布者时,它从对象池中获取一个,发送它的消息,然后将发布者返回到池中;相对于使用发布者的线程,创建、连接和销毁套接字的过程被消除了,但是对池的访问是同步的,以避免任何两个线程同时使用同一个发布者对象,并且这是可能出现死锁和并发问题的地方。

我们没有分析任何一种方法,因为想先对 SO 测试做一个试金石。关于数量,我们的应用程序不会发布“繁重”,但可能有 100-150 个线程(每个应用程序服务器)同时需要发布一条消息。

ZMQ Publisher Object Pool

因此,重申一下:什么策略是最有效的,当应用程序有许多线程依赖于发布者发送消息时,在强调性能的同时最大限度地减少开销?

最佳答案

如果不提供估计吞吐量的真实数据,就不能真正提出有关性能的问题。我们是在谈论每秒 10 个请求、100、1,000、10K?

如果 HTTP 服务器真的为每个请求创建和销毁线程,那么重复创建 0MQ 套接字会给操作系统带来压力,并且根据请求量和您的进程限制,它会工作,或者会用完处理。您可以简单地测试一下,这是第一步。

然后,共享套接字池(您所说的“ZMQ 发布者”)是令人讨厌的。人们这样做,但套接字不是线程安全的,因此这意味着当您将套接字切换到另一个线程时要非常小心。

如果有办法保持线程持久化,那么每个线程都可以在需要时创建自己的 PUB 套接字,并在它存在时一直持有它。如果没有,那么我的第一个设计无论如何都会创建/销毁套接字,但使用 inproc://将消息发送到单个永久转发器线程(SUB-PUB 代理)。我会对此进行测试,如果它坏了,就去寻找更具异国情调的设计。

一般来说,最好是做出最简单的设计并打破它,而不是过度思考设计过程(尤其是在开始时)。

关于java - ZeroMQ 多线程 : create sockets on-demand or use sockets object pool?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16659577/

相关文章:

android - onUserInteraction() 到底什么时候被调用?

python - 如何只允许一个客户端连接到我的 TCPSocketServer?

java - 如何将此通用类转换为 Parcelable?

java - 在java中声明实例关键字

c++ - Windows 线程等待方法

c++ - unique_ptr 的这两种用法有什么区别?

PostgreSQL 性能调整和最大连接数(实际上)

java - 如果它在生产环境中,调试死锁问题的正确行动计划是什么?

java - ResponseEntity 在 Resttemplate JUNIT 调用中为 null

Android SDK AsyncTask doInBackground 未运行(子类)