如何在python和php中有效地使用ZMQ发送单个消息

时间:2018-03-28 17:21:24

标签: php python sockets zeromq pyzmq

我目前有一个PHP函数:

function sendLocalSocket($message, $port){
    $context = new ZMQContext();
    $socket = $context->getSocket(ZMQ::SOCKET_PUSH);
    $socket->connect("tcp://127.0.0.1:$port");
    $socket->send($message);
}

和python函数:

def create_local_socket(port, pull=False):
    context = zmq.Context()
    if pull:
        # for receiving socket messages
        socket = context.socket(zmq.PULL)
        socket.bind("tcp://127.0.0.1:%d" % port)
    else:
        # for sending socket messages
        socket = context.socket(zmq.PUSH)
        socket.connect("tcp://127.0.0.1:%d" % port)
    return socket

然后发送带有create_local_socket(port).send_json()

的消息

不幸的是,当快速连续调用这两个函数时,这两个函数中的任何一个都会显着地挂起并减慢我系统的其余部分。

我一直在考虑如何为永不终止的python脚本保持套接字打开,但遗憾的是,对于PHP,这是在文件上传后调用的。

问题是这些函数被任意调用 - php脚本每次上传使用相同的端口,但python脚本使用不同的端口(尽管有重复使用)。

我知道php正在挂起,因为python ZMQ监听器记录current time - the time the file was uploaded,这需要更长时间,直到上传的积压消失。我也知道监听器脚本没有挂起,并且在记录接收文件后需要0.2秒。 (但这实际上是一个回溯日志!)

我觉得答案就是坚持这些联系。

编辑1:

尝试:$context = new ZMQContext(1, true);没有帮助。

1 个答案:

答案 0 :(得分:1)

鉴于对每个代码段的每次调用都会产生另一个 Context() - 实例,这构成了合理使用资源的反模式。

关于Zen-of-Zero的温和阅读将很快显示主要原因,为什么构建(半)持久性信令/消息传递层是要走的路,因为资源分配/解除分配总是很昂贵加上留下这么多未终止的实例很快就会耗尽任何可用的资源。

ZeroMQ工具远不是一次性使用的一次性工具。效率与最小化资源相关的开销密切相关,因此最好重新设计从未解除分配的资源池的临时创建,而是在这些资源需要已经处于活动状态并准备好为广告提供服务之前准备好所有需要的工具。特别要求。

产品的适当重新分解有很长时间。

虽然documentation reports有一些持久性辅助作案手法,但在进入这个方向之前应该仔细检查其成本/收益,因为Zen-of-Zero实际上正在考虑任何形式的共享反模式{ {3}}设计实践,并警告:

注意

重要的是要记住,不小心使用持久性套接字会耗尽机器上的可用文件句柄。

function sendLocalSocket( $message,                 //  IS to be get delivered
                          $port                     // WAS reported to be
                          ){                        //     all the time the same 
    $context = new ZMQContext( 2, true );           // MAY try persistent CTX
    $socket = $context->getSocket( ZMQ::SOCKET_PUSH,
                                  "persistLoggerID" // MAY use persistent SOCK
                                   );
    $socket->connect(    "tcp://127.0.0.1:$port" ); // MAY use less expensive TC
    $socket->send(       $message,
                          ZMQ::MODE_NOBLOCK         // USE non-blocking mode
                          );
    $socket->disconnect( "tcp://127.0.0.1:$port" ); // USE .disconnect()
}

最后的注释

任何应用程序的质量,健壮性和性能取决于语言和特定于语言的ZeroMQ绑定如何尊重本机API,并反映使用本机DLL服务而演变的最佳实践。任何“抽象”和/或“自动化”步骤都会降低设计人员对本机API级别上的其他应用步骤的范围和顺序的控制,这看起来很舒服,但这些步骤也减少了设计强大和高性能部署的选项,因为一些原生API调整选项不一定主要在用户应用程序级别可用,一旦被语言特定的ZeroMQ绑定抽象遮蔽了。