gpt4 book ai didi

rabbitmq - 如何避免使用 amqp php、持久连接和 php-fpm 的每个 tcp 连接的最大 channel 数

转载 作者:可可西里 更新时间:2023-11-01 14:02:45 25 4
gpt4 key购买 nike

我刚开始学习 rabbitMQ,但遇到了一个问题。

使用 http://pecl.php.net/package/amqp版本 1.4(最新版本)和 RabbitMQ 3.3.1。我们必须使用 php5-fpm 和带有 amqp->pconnect() 的持久连接。

一段时间后(我猜是 65500 个请求)出现一个问题,停止所有写入"

Could not create channel. Connection has no open channel slots remaining

根据我在源代码中读到的内容,因为每个 tcp 连接都有一个达到其最大值的自动增量 channel ID。发生这种情况是因为每个请求都必须使用 channel ,并且无法使用相同的 channel (我找不到进入 php-amqp channel 类以使其持久化的方法)并且脚本无法通信(使用相同的实例作为 php 对象的 channel )。

降低 php-fpm 的生命周期不是一种选择,要么通过另一种技术/库等来解耦应用程序-rabbitmq 通信。

有什么简单的方法可以解决这个问题吗?

理论上它应该是每个线程一个 channel (在这种情况下是 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);

谢谢!!

最佳答案

简短回答:不要使用带有 php-amqp 扩展的持久连接,使用常规的 connect() 打开连接应该不会降低性能即使在高负载下(如 2k+req/sec)也很重要。

长答案:

php-amqp 中每个连接限制同时硬编码了最大同时打开的 channel 数扩展名(#define DEFAULT_CHANNELS_PER_CONNECTION 255)。关闭的 channel 在关闭后尝试重用。

但是rabbitmq-c (aka librabbitmq)还有另外一个限制到一个物理连接内的最大 channel 数 - #define AMQP_DEFAULT_MAX_CHANNELS 0 ,这意味着没有应用自定义限制,因此应用了协议(protocol)限制。根据规范 ( section 4.9 Limitations ),协议(protocol)限制为:

Number of channels per connection: 16-bit channel number.

这是according to wikipedia 无符号:从 0 到 65,535。在 AMQP 中,0 永远不会用作 channel 号并被解释为错误。

因此,当您在本地关闭所有 channel 但未关闭时,RabbitMQ 将继续 channel 编号序列,从而达到指定的上限。

除非关闭您的连接,否则没有其他方法可以摆脱这种行为。

此外,我建议您根本不要使用持久连接,因为它有 potential memory leak。总的来说有点不稳定。有计划从 php-amqp 中完全删除持久性。

关于rabbitmq - 如何避免使用 amqp php、持久连接和 php-fpm 的每个 tcp 连接的最大 channel 数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23864647/

25 4 0
文章推荐: c++ - 如何加速我的内存扫描程序?
文章推荐: php - Form::model 绑定(bind) Laravel 与