我只是在学习rabbitMQ而且遇到了一个问题.
使用http://pecl.php.net/package/amqp 1.4版(现在最新版)和RabbitMQ 3.3.1版.我们必须使用php5-fpm和与amqp-> pconnect()的持久连接.
过了一会儿(我想65500个请求)会出现问题,停止所有写入"
无法创建频道.连接没有剩余的开放信道插槽
"
从我在源中读到的是因为每个tcp连接都有一个自动增量通道ID达到其最大值.这是因为每个请求都必须使用该通道,并且无法使用相同的通道(我无法找到进入php-amqp通道类的方法使其持久化)并且脚本无法通信(使用相同的实例)通道作为php对象).
降低php-fpm生命周期不是一个选项,要么通过另一个技术/库等解耦application-rabbitmq通信.
有没有简单的方法来解决这个问题?
从理论上讲,它应该是每个线程一个通道(在这种情况下是php5-fpm worker)但是如何使用这个库来实现呢?
我现在使用的代码(类似)
$this->con = new AMQPConnection(array(
'host' => $this->con_params['host'],
'port' => $this->con_params['port'],
'vhost' => $this->con_params['vhost'],
'login' => $this->con_params['user'],
'password' => $this->con_params['pass'],
'read_timeout' => 1,//seconds
'write_timeout' => 1,//seconds
'connect_timeout' => 1,//seconds
));
$this->con->pconnect();
$channel = new AMQPChannel($this->con);
$queue = new AMQPQueue($channel);
$queue->setName($queueName);
$queue->setFlags(AMQP_DURABLE);
//$queue->declareQueue();//make sure it exists
$exchange = new AMQPExchange($channel);
$exchange->setName($exchangeName);
$exchange->setFlags(AMQP_DURABLE);
$exchange->setType(AMQP_EX_TYPE_DIRECT);
//$exchange->declareExchange();
$this->queues[$queueName]->bind($exchangeName);
Run Code Online (Sandbox Code Playgroud)
谢谢 !!
简短回答:不要使用具有php-amqp扩展名的持久连接并且使用常规connect()性能降级来打开连接即使在高负载(例如2k + req/sec)也不应该是显着的.
答案很长:
在php-amqp extension(#define DEFAULT_CHANNELS_PER_CONNECTION 255)中,每个连接限制同时存在硬编码的最大同时打开的通道.封闭渠道在关闭后会尝试重复使用.
但是在一个物理连接中,rabbitmq-c(aka librabbitmq)还有另一个限制,即最大通道数 - #define AMQP_DEFAULT_MAX_CHANNELS 0这意味着没有应用自定义限制,因此应用了协议限制.根据规范(第4.9节限制),协议限制为:
每个连接的通道数:16位通道号.
这是根据维基百科 Unsigned: From 0 to 65,535.在AMQP中,0从不用作通道号并被解释为错误.
因此,当您在本地关闭所有通道但未关闭时,RabbitMQ将继续通道编号序列,因此它将达到指定的上限.
除非关闭连接,否则没有其他方法可以摆脱这种行为.
另外,我建议你不要使用持久连接,因为它有潜在的内存泄漏,一般来说有点不稳定.有计划从php-amqp中彻底删除持久性.
| 归档时间: |
|
| 查看次数: |
7978 次 |
| 最近记录: |