ZeroMq:打开的文件太多。 文件描述符使用数量在同一对象上不断增长。

3

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

每次创建对象时,服务器(操作Centos 7)系统中打开文件的数量(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;
    }
}

欢迎来到SO。你能包含一些相关的代码吗? - Maciej Jureczko
帖子中包含相关代码。@MaciejJureczko - Olkan
在你的函数中,你创建了套接字,但是在返回时没有关闭它们。这可能是你的问题吗?另外,我认为在套接字创建和连接之后,但在接收部分之前应该有一个循环。 - Clonk
@Clonk 在 C++ 代码中,套接字会自动关闭。 - Olkan
1个回答

2

我也遇到了这个问题。我不确定是否有解决方案,但我发现上下文(zmq::context_t)有一个最大套接字数限制。请参阅zmq_ctx_set以获取更多详细信息。此限制默认为ZMQ_MAX_SOCKETS_DFLT,似乎为1024。

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


更新:

我通过套接字选项的组合来修复了泄漏:

  • ZMQ_RCVTIMEO - 我已经在使用它了,以避免如果另一端不存在而永远等待。我的系统通过仅在一个套接字上进行一次请求,然后关闭它来处理这个问题。
  • ZMQ_LINGER - 设置为0,以便套接字不会等待尝试发送失败的消息。默认行为是无限期滞留。这可能是您问题的关键
  • ZMQ_IMMEDIATE - 此选项将消息排队限制为仅完成的连接。没有队列,套接字就不需要滞留。

我不能确定是否需要同时使用linger和immediate,但它们似乎都适用于我的用例;它们可能会有所帮助。设置了这些选项后,我的打开文件数量不会无限增长。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接