ZeroMq:打开的文件太多.在同一对象上连续增长的fd使用数

ZeroMq: Too many open files.. Number of fd usage growing continuosly on the same object

本文关键字:连续 fd 对象 文件 太多 ZeroMq      更新时间:2023-10-16

通过包括2个zeromq订阅者和1个zerommq请求套接字的同一类对象,我在不同的线程中创建对象。我使用inproc zeromq套接字,它们属于同一个ZContext。

每次创建对象时,服务器(操作Centos7(系统中打开的文件(lsof|wc-l(的数量都会递增。在创建第一个对象之后,打开的文件#增加了300,而第二个对象将打开的文件号增加了304并持续增长。

由于我的程序在运行时可以使用其中的许多对象,这可能会导致zeromq出现太多打开文件错误,即使我将限制设置为524288(ulimit-n(。随着对象数量的增加,每个对象对打开文件限制的消耗要大得多,其中一些对象的消耗量约为1500。

在运行时,我的程序崩溃了,因为在创建许多对象和线程在对象上执行工作(向另一个服务器或客户端发送消息(时出现了太多打开文件错误。

我该如何克服这一点?

示例代码:

void Agent::run(void *ctx) {
zmq::context_t *_context = (zmq::context_t *) ctx;
zmq::socket_t dataSocket(*(_context),ZMQ_SUB);
zmq::socket_t orderRequestSocket(*(_context),ZMQ_REQ);//REQ
std::string bbpFilter = "obprice.1;
std::string bapFilter = "obprice.2"
std::string orderFilter = "order";
dataSocket.connect("inproc://ordertrade_publisher");   
dataSocket.connect("inproc://orderbook_prices_pub");      
orderRequestSocket.connect("inproc://frontend_oman_agent");    
int rc;
try {         
zmq::message_t filterMessage;
zmq::message_t orderMessage;
rc = dataSocket.recv(&filterMessage);
dataSocket.recv(&orderMessage); 
//CALCULATION AND SEND ORDER
// end:
return;
}
catch(std::exception& e) {
std::cerr<< "Exception:" << e.what() << std::endl;        
Order.cancel_order(orderRequestSocket);
return;
}
}

我也遇到了这个问题。我不确定我是否有解决方案,但我看到上下文(zmq::context_t(具有最大数量的套接字。详见zmq_ctx_set。此限制默认为ZMQ_MAX_SOCKETS_DFLT,看起来是1024。

您可能只需要增加上下文可以拥有的套接字数量,尽管我怀疑可能存在一些泄漏(至少在我的情况下(。


更新:

我能够通过插座选项的组合修复我的泄漏:

  • ZMQ_RCVTIMEO-我已经在使用它来避免在另一端不在的情况下永远等待。我的系统只通过在套接字上发出一个请求,然后关闭它来处理这个问题
  • ZMQ_LINGER-设置为0,这样套接字就不会等待发送失败的消息。默认行为是无限延迟。这可能是你问题的关键
  • ZMQ_IMMEDIATE-此选项将消息排队限制为仅完成连接。如果没有队列,套接字就不需要逗留

我不能确定我是否需要逗留和立即,但它们似乎都适合我的用例;他们可能会帮助你的。设置了这些选项后,我打开的文件数量不会无限增长。