我发现了很多关于类似主题的问题,但它们并没有帮助我解决我的问题。
Using :
- Linux Ubuntu 14.04
- 蟒蛇3.4
- zmq : 4.0.4 // pyZMQ 14.3.1
TL;DR
即使设置了 HWM,ZMQ SUB 套接字中的接收器队列也会无限增长。当订阅者比发布者慢时就会发生这种情况。
我可以做什么来预防它?
背景
我在人机交互领域工作。我们有一个巨大的代码库来控制鼠标光标之类的东西。我想在几个模块中“打破它”,与 ZMQ 通信。
它必须具有尽可能小的延迟,但丢弃(丢失)消息并不那么重要。
另一个有趣的方面是可以在节点之间添加“间谍”。因此 PUB/SUB 插座似乎是最合适的。
像这样的东西:
+----------+ +-----------+ +------------+
| | PUB | | PUB | |
| Input | +----+------> | Filter | +----+------> | Output |
| | | SUB | | | SUB | |
+----------+ v +-----------+ v +------------+
+-----+ +-----+
|Spy 1| |Spy 2|
+-----+ +-----+
Problem
一切正常,除了我们添加间谍的时候。
如果我们添加一个间谍来做“繁重的事情”,比如使用 matplotlib 进行实时可视化,我们会注意到绘图中的延迟不断增加。 IE:在上图中,过滤器和输出很快,没有看到延迟,但在 Spy 2 上,运行 20 分钟后延迟可以达到 10 分钟(!!)
看起来接收器上的队列无限增长。
我们研究了 ZMQ 的高水位线 (HWM) 功能,将其设置为低位以丢弃较旧的消息,但没有任何改变。
最少的代码
建筑学 :
+------------+ +-------------+
| | PUB | |
| sender | -------------> | receiver |
| | SUB| |
+------------+ +-------------+
接收器是一个慢速接收器(在第一张图中充当间谍)
Code :
发件人.py
import time
import zmq
ctx = zmq.Context()
sender = ctx.socket(zmq.PUB)
sender.setsockopt(zmq.SNDBUF, 256)
sender.set_hwm(10)
sender.bind('tcp://127.0.0.1:1500')
print(zmq.zmq_version()) ## 4.0.4
print(zmq.__version__) ## 14.3.1
print(sender.get_hwm()) ## 10
i = 0
while True:
mess = "{} {}".format(i, time.time())
sender.send_string(mess)
print("Send : {}".format(mess))
i+= 1
接收者.py:
import time
import zmq
ctx = zmq.Context()
front_end = ctx.socket(zmq.SUB)
front_end.set_hwm(1)
front_end.setsockopt(zmq.RCVBUF, 8)
front_end.setsockopt_string(zmq.SUBSCRIBE, '')
front_end.connect('tcp://127.0.0.1:1500')
print(zmq.zmq_version()) ## 4.0.4
print(zmq.__version__) ## 14.3.1
print(front_end.get_hwm()) ## 1
while True:
mess = front_end.recv_string()
i, t = mess.split(" ")
mess = "{} {}".format(i, time.time() - float(t))
print("received : {}".format(mess))
time.sleep(1) # slow
我认为这不是 ZMQ Pub/Sub 的正常行为。
我尝试在接收器、订户和两者中设置 HWM,但没有任何改变。
我缺少什么?
Edit :
当我解释我的问题时,我认为我没有说清楚。我做了一个移动鼠标光标的实现。输入是在 ZMQ 中以 200Hz 发送的鼠标光标位置(带有.sleep( 1.0 / 200 )
),完成了一些处理并更新了鼠标光标位置(在我的最小示例中没有这种睡眠)。
一切都很顺利,即使是在我发射间谍的时候。然而,间谍的延迟时间却越来越长(因为处理速度很慢)。延迟不会出现在“管道”末尾的光标中。
我认为问题出在缓慢用户排队的消息。
在我的示例中,如果我们杀死发送者并让接收者存活,消息将继续显示,直到显示所有(?)提交的消息。
间谍正在绘制光标的位置以提供一些反馈,有这样的延迟还是很不方便......我只想得到最后发送的消息,这就是我尝试降低 HWM 的原因。