简体   繁体   English

使用Kombu设置Rabbit MQ心跳

[英]Setting up Rabbit MQ Heartbeat with Kombu

Edit: 编辑:

The main issue is the 3rd party rabbitmq machine seems to kill idle connections every now and then. 主要问题是第三方Rabbitmq机器似乎有时会杀死空闲连接。 That's when I start getting "Broken Pipe" exceptions. 那就是我开始遇到“管道破损”异常的时候。 The only way to gets comms. 获得通讯的唯一方法。 back to normal is for me to kill the processes and restart them. 恢复正常对我来说是杀死进程并重新启动它们。 I assume there's a better way? 我认为有更好的方法吗?

-- -

I'm a little lost here. 我在这里迷路了。 I am connecting to a 3rd party RabbitMQ server to push messages to. 我正在连接到第三方RabbitMQ服务器以将消息推送到。 Every now and then all the sockets on their machine gets dropped and I end up getting a "Broken Pipe" exception. 时不时地删除其计算机上的所有套接字,最后我得到一个“ Broken Pipe”异常。

I've been told to implement a heartbeat check in my code but I'm not sure how exactly. 我被告知要在我的代码中实现心跳检查,但是我不确定该如何执行。 I've found some info here: http://kombu.readthedocs.org/en/latest/changelog.html#version-2-3-0 but no real example code. 我在这里找到了一些信息: http : //kombu.readthedocs.org/en/latest/changelog.html#version-2-3-0,但没有真正的示例代码。

Do I only need to add "?heartbeat=x" to the connection string? 我只需要在连接字符串中添加“?heartbeat = x”? Does Kombu do the rest? Kombu会做剩下的吗? I see I need to call "Connection.heartbeat_check()" at "x/2". 我看到我需要在“ x / 2”处调用“ Connection.heartbeat_check()”。 Should I create a periodic task to call this? 我应该创建一个定期任务来调用吗? How does the connection get re-established? 如何重新建立连接?

I'm using: 我正在使用:

  • celery==3.0.12 芹菜== 3.0.12
  • kombu==2.5.4 海带== 2.5.4

My code looks like this right now. 我的代码现在看起来像这样。 A simple Celery task gets called to send the message through to the 3rd party RabbitMQ server (removed logging and comments to keep it short, basic enough): 调用了一个简单的Celery任务,将消息发送到第三方RabbitMQ服务器(删除了日志和注释,使其简短,足够基本):

class SendMessageTask(Task):
    name = "campaign.backends.send"
    routing_key = "campaign.backends.send"
    ignore_result = True
    default_retry_delay = 60 # 1 minute.
    max_retries = 5

    def run(self, send_to, message, **kwargs):
    payload = "Testing message"

    try:
        conn = BrokerConnection(
        hostname=HOSTNAME,
        port=PORT,
        userid=USER_ID,
        password=PASSWORD,
        virtual_host=VHOST
        )

        with producers[conn].acquire(block=True) as producer:
        publish = conn.ensure(producer, producer.publish, errback=sending_errback, max_retries=3)
        publish(
            body=payload,
            routing_key=OUT_ROUTING_KEY,
            delivery_mode=2,
            exchange=EXCHANGE,
            serializer=None,
            content_type='text/xml',
            content_encoding = 'utf-8'
        )

    except Exception, ex:
        print ex

Thanks for any and all help. 感谢您提供的所有帮助。

While you certainly can add heartbeat support to a producer, it makes more sense for consumer processes. 尽管您当然可以为生产者添加心跳支持,但对于消费者流程而言,这更有意义。

Enabling heartbeats means that you have to send heartbeats regularly, eg if the heartbeat is set to 1 second, then you have to send a heartbeat every second or more or the remote will close the connection. 启用心跳意味着您必须定期发送心跳,例如,如果将心跳设置为1秒,则必须每隔一秒或更长时间发送一次心跳,否则远程将关闭连接。

This means that you have to use a separate thread or use async io to reliably send heartbeats in time, and since a connection cannot be shared between threads this leaves us with async io. 这意味着您必须使用单独的线程或使用异步io才能及时可靠地发送心跳,并且由于无法在线程之间共享连接,因此我们只能使用异步io。

The good news is that you probably won't get much benefit adding heartbeats to a produce-only connection. 好消息是,将心跳添加到仅生产的连接中可能不会带来太多好处。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM