代码说明:
我的代码很简单,它从Logbook库(使用pyzmq)启动 ZeroMQHandler
(基于套接字的消息传递)。 Logger(日志)在整个应用程序中运行。最后,处理程序关闭端口。 .push()
和 .pop_application()
方法代替了
with handler.applicationbound():
并缩进。
目的:
我正在测试这个基于队列的消息传递,看它是否可以成为一个低影响的异步日志记录解决方案。我需要每秒记录大约15 000条消息。我更喜欢使用Python,但我的后备是用C ++编写记录器并将其句柄暴露给python。
问题:
问题是如果在打开处理程序(套接字)之后我不等待四分之一秒或更多,程序执行时没有任何消息通过(测试程序需要少于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内核中运行(用于测试,输出到stdout):
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()
答案 0 :(得分:1)
ZeroMQ确实花了一些时间来创建 Context()
-instance本身,然后要求O / S分配内存限制资源,以产生I / O线程,这还需要一些额外的时间。接下来,每个 Socket()
- 实例化会消耗一些附加开销时间。
在本地API文档和教育资源中都有详细记录,异步信令/消息传递框架确实需要花费一些时间,在任何API请求实际在“local”和“remote”{{}中进行处理之前1}} - 实例,最后被标记为可读的,可用于某些ZeroMQ可扩展形式通信原型的“远程”端。
这就是说,毫无疑问,ZeroMQ工具的更多重新包装使用(由另一级抽象重新包装,编码到 Context()
类中) ,只会添加额外的logbook.queue.ZeroMQSubscriber, logbook.queue.ZeroMQHandler
设置&操作{
- 开销,因此服务的已知异步性只会增长。
如果您的申请需要在任何一对两端之间进行任何形式的相互重新确认,那么他们已达到 R eady- T o- O 强>皮特州( RTO - 状态),最好是引入某种智能对账政策,而不是盲目相信,依靠足够长的}
来希望事情有足够的时间来安顿下来并进入RTO。
在distributed-system中,最好是明确的,而不是保持乐观的希望。
鉴于您的持续吞吐量应安全地降低并且仍然在每个消息发送的预期阈值.sleep()
之下,让我也对正确的 {{1 }} - 参数化,以便在真实的硬件和系统范围的资源规划下顺利地承载您所需的工作量。
默认值不会被打成石头,永远不应该依赖。