rabbitmq持久连接实现方式

近期在使用rabbitmq时检测到生产环境频繁报错::

{"message":"Broken pipe or closed connection","context":{"exception":{"class":"PhpAmqpLib\\Exception\\AMQPConnectionClosedException","message":"Broken pipe or closed connection"
}}

排查后基本确定是消费端进程在开启消费阻塞等待后,SLB出于资源的有效利用考虑会对空闲的TCP连接进行回收,这样进程所持有的socket文件资源描述符就会找不到,报错发生在这段代码(php-amqp-lib库):

if (!is_resource($this->sock) || feof($this->sock)) {
                $this->close();
                throw new AMQPConnectionClosedException('Broken pipe or closed connection');
            }

事实上,队列消费端常驻进程会在很多情况下断掉tcp连接,例如出现网络抖动等非人为因素,为了保持tcp的持久连接,rabbitmq提供了两种方式:

  1. 心跳检测

心跳检测是rabbitmq保持持久连接的一种实现方式,开启心跳后客户端会在每心跳超时时间/2内发送一个心跳包到服务端,证明是处于有效连接的,如果超过这个时间没有收到心跳,客户端就会自动发起重连。

new AMQPStreamConnection($host, $port, $user, $password, $vhost, false, 'AMQPLAIN', null, 'en_US', 10.0, $rwTimeout, null, false, $heartBeat);

通过以上方式可以设置心跳时间,默认为60s;开启心跳后问题解决,没有出现进程断掉的报错。

  1. tcp keepalive

tcp keepalive在内部也实现了类似心跳的机制,建议两者选择其一就行,实现方式:

public function __construct(
        $host,
        $port,
        $user,
        $password,
        $vhost = '/',
        $insist = false,
        $login_method = 'AMQPLAIN',
        $login_response = null,
        $locale = 'en_US',
        $connection_timeout = 3.0,
        $read_write_timeout = 3.0,
        $context = null,
        $keepalive = false,
        $heartbeat = 0,
        $channel_rpc_timeout = 0.0,
        $ssl_protocol = null
    ) 

在实例化AMQPStreamConnection对象时,$keepalive参数设置为true即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值