Python 用PyZMQ限制队列长度

Python 用PyZMQ限制队列长度,python,zeromq,pyzmq,Python,Zeromq,Pyzmq,我想限制Python应用程序中ZeroMQ消息队列所消耗的内存量。我知道设置高水位线会限制发送方排队的数量,但有没有办法控制接收方排队的数量?Python ZeroMQ绑定似乎将其设置为无限 我的测试场景:我有两个用于测试的python终端。一个是接收器: Python 2.5.1 (r251:54863, Aug 25 2008, 20:50:04) [GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2 Type "help", "copyrig

我想限制Python应用程序中ZeroMQ消息队列所消耗的内存量。我知道设置高水位线会限制发送方排队的数量,但有没有办法控制接收方排队的数量?Python ZeroMQ绑定似乎将其设置为无限

我的测试场景:我有两个用于测试的python终端。一个是接收器:

Python 2.5.1 (r251:54863, Aug 25 2008, 20:50:04) 
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> import zmq
>>> context = zmq.Context()
>>> socket = context.socket(zmq.PULL)
>>> socket.setsockopt(zmq.RCVBUF, 256)
>>> socket.bind("tcp://127.0.0.1:12345")
另一个是发送者:

Python 2.5.1 (r251:54863, Aug 25 2008, 20:50:04) 
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> import zmq
>>> context=zmq.Context()
>>> socket = context.socket(zmq.PUSH)
>>> socket.setsockopt(zmq.SNDBUF, 2048)
>>> socket.setsockopt(zmq.HWM, 1)
>>> socket.connect("tcp://127.0.0.1:12345")
>>> num = 0
>>> while True:
...  print num
...  socket.send(str(num))
...  num = num + 1
... 

我在接收方运行了几次
socket.recv()
,以确保队列正常工作,但除此之外,让两个终端就坐在那里。发送循环似乎从不阻塞,接收提示似乎占用了越来越多的内存。

与ZeroMQ的文档相反,需要在
侧和
侧设置高水位线。一旦我改变了
,效果就更好了。新的
PULL
代码为:

Python 2.5.1 (r251:54863, Aug 25 2008, 20:50:04) 
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> import zmq
>>> context=zmq.Context()
>>> socket = context.socket(zmq.PULL)
>>> socket.setsockopt(zmq.RCVBUF, 256)
>>> socket.setsockopt(zmq.HWM, 1)
>>> socket.bind("tcp://127.0.0.1:12345")

实际上,文件上说:

“当ZMQ_推送插座由于以下原因进入异常状态: 达到所有下游节点的高水位线,或 根本没有下游节点,那么任何zmq_都会在服务器上发送(3)个操作 插座应阻塞,直到异常状态结束或至少一个 下游节点可用于发送;消息不可用 丢弃。”


这直接说明您可以(也应该)为下游节点设置高水位线(也称为pull),并且可能意味着将其设置在push端不会产生任何效果(尽管我怀疑这不是真的,因为仍然存在下游节点可用但消息传入速度快于发送速度的情况)

使用
zmq.SNDBUF
zmq.RCVBUF
选项,您可以


另外,我在Receiver端使用
zmq.CONFLATE
选项将ZeroMQ队列大小限制为1:

下面是一个ZMQ
推/拉的示例:

发送方(
zmq.PUSH
):
Getter(
zmq.PULL
):
我使用了这个属性,但得到了一个错误:
AttributeError:module'zmq'没有属性'HWM'
,所以我使用了
zmq.SNDHWM
zmq.RCVHWM
def create_pub_socket(ip, port):
    try:
        context = zmq.Context()
        socket = context.socket(zmq.PUSH)
        socket.setsockopt(zmq.SNDHWM, 1)
        zmq_address = "tcp://{}:{}".format(ip, port)
        socket.connect(zmq_address)
        return socket

    except zmq.ZMQError as exp:
        print(exp)
        return False

sock = create_push_socket('127.0.0.1', 5558)
if sock:
    sock.send_json({'a': 1})
def listen(self):
    sock = None
    try:
        context = zmq.Context()
        sock = context.socket(zmq.PULL)
        sock.setsockopt(zmq.RCVHWM, 1)
        sock.setsockopt(zmq.CONFLATE, 1)  # last msg only.
        sock.bind("tcp://*:5558")

    except zmq.ZMQError:
        logger.captureException()

    configs = None
    while configs is None:
        if sock:
            configs = sock.recv_json()
            time.sleep(1e-1)
        else:
            time.sleep(5)
            listen()  # Recursive.
listen()