使用Logbook和ZeroMQ,为什么我需要等待才能传递消息?

3
代码描述: 我的代码很简单,它启动了一个基于socket的消息处理器ZeroMQHandler(使用pyzmq库中的Logbook)。记录器(log)贯穿整个应用程序。最后,处理器关闭端口。而.push().pop_application()方法代替了with handler.applicationbound(): 和缩进。
目的: 我正在测试这种基于队列的消息传递,看它是否可以成为一种低影响力的异步日志记录解决方案。 我需要每秒记录大约15,000条消息。 我更喜欢使用Python,但如果不行的话,我就会在C ++中编写记录器并将其句柄公开给Python。
问题: 问题在于,如果我在打开处理器(socket)后不等待四分之一秒或更长时间,程序就不会执行任何消息(测试程序执行时间小于0.25秒)。我认为这是ZeroMQ套接字或类似的东西所需的设置时间。因此,我想知道是否有人有类似的经验,也许这在任何地方都有记录,但我自己似乎无法弄清楚。我想知道为什么需要这样做。 谢谢任何帮助。
我的工作代码如下:
from logbook.queues import ZeroMQHandler
from logbook import Logger
import time

addr='tcp://127.0.0.1:5053'
handler = ZeroMQHandler(addr)
time.sleep(0.25) ################################################# THIS ! ####

log = Logger("myLogbook")
handler.push_application()

log.info("start of program")
foo()
log.info("end of program")

handler.close()
handler.pop_application()

接收器,在不同的Python内核中运行(用于测试,将输出发送到标准输出):

from logbook.queues import ZeroMQSubscriber
from logbook import Logger, StreamHandler
import sys
import time
addr='tcp://127.0.0.1:5053'
print("ZeroMQSubscriber begin with address {}".format(addr))
subscriber = ZeroMQSubscriber(addr)
handler = StreamHandler(sys.stdout)

log = Logger("A receiver")
handler.push_application()


try:
    i=0
    while True:
        i += 1
        record = subscriber.recv(2)
        if not record:
            pass # timeout
        else:
            print("got message!")
            log.handle(record)
except KeyboardInterrupt:
    print("C-C caught, program end after {} iterations".format(i))    
handler.pop_application()
1个回答

1
ZeroMQ确实需要一些时间来创建Context()实例,并请求操作系统分配内存绑定资源以生成I/O线程,这也需要额外的时间。接下来,每个Socket()实例化都会消耗一些附加开销时间。
在本机API文档和教育资源中都有明确说明,异步信令/消息框架确实需要一些时间,才能在“本地”和“远程”Context()实例中处理任何API请求,并最终标记为可读交付给某些ZeroMQ可扩展正式通信原型的“远程”端。
因此,毫不奇怪,即使是更多层次的抽象(由logbook.queue.ZeroMQSubscriber、logbook.queue.ZeroMQHandler类编码)重新包装使用ZeroMQ工具,也只会增加额外的{设置和运行}开销,因此服务的已知异步性只会增加。
如果您的应用程序需要任何一对双方之间进行任何形式的相互再确认,以确保它们已达到“准备好运行”状态(RTO状态),最好引入某种智能协调策略,而不是盲目相信,并依靠足够长的.sleep()来希望事情有足够的时间安定下来并进入RTO状态。
在分布式系统中,最好明确表述,而不是保持乐观的希望。

结语:

鉴于您的持续吞吐量应该安全地保持在预期的阈值<= 66 [us / message]以下,并且仍然保持在此范围内,我也对适当的Context()参数化提出了兴趣,以确保在实际硬件和系统资源规划下顺利处理所需的工作负载。

默认值并非铁板钉钉,不应成为依赖的关键点。


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