PHP RabbitMQ连接超时题目
题目背景Error: The connection timed out after 3 sec while awaiting incoming data
看到这个报错,我不以为意,认为是我设置的超时时间不敷导致的,那就设置长一点
Error: The connection timed out after 300 sec while awaiting incoming data
当我等待了300秒看到了这个报错,我眉头一皱,此事比不简朴。
错误分析
很显着这个题目有几种可能,我逐一排查
因为我是从测试环境转到生产环境的,代码一样,测试环境没有题目,只是RabbitMQ不一样。
起首测试MQ是否能通
利用telnet 命令测试,发现不能通,原来是生产环境的MQ加了IP限制。把IP加到白名单后能通,但是代码连接仍旧超时。
测试我怀疑是不是给过来的端口不对,因为测试环境的端口是5672,这个是默认端口,而生产环境的端口是5671,修改端口后发现端口不通,连接失败,拒绝连接。那就端口没有题目
接着我认为可能是账号密码不对,修改后发现报错还是超时,说明代码都还没连上RabbitMQ。
https://i-blog.csdnimg.cn/direct/050cde6f9da641eea5e93f8b0993073c.png 连接代码 此时我去网上探求答案,恰巧也有人跟我碰到了类似的题目,在github上向开发者提了Issuses
PHP 致命错误:未捕获的异常“PhpAmqpLib\Exception\AMQPTimeoutException”,并显示消息“在等待传入数据时,连接在 3 秒后超时” ·题目 #839 ·php-amqplib/php-amqplib ·GitHub的
https://i-blog.csdnimg.cn/direct/a44e1ec0c8cd40e19a2b9fba29c54d25.png
此中这个提问跟我碰到的题目完全同等
https://i-blog.csdnimg.cn/direct/6fed1e33d56c4f66bd7209cb6df011c9.png
扩展的开发者也对这个题目进行了答复,从这里我就知道这个题目跟SSL有关系了,同时还提供了样例php-amqplib/demo/ssl_connection.php at master · php-amqplib/php-amqplib · GitHub
https://i-blog.csdnimg.cn/direct/9f52d23ea1034c0fac4fe00129639bc9.png
根据这个样例不丢脸出是要我们利用ssl进行连接,因为MQ的5671端口是支持SSL的。
可是许多人都跟我一样,没有这个证书,或者说纵然有也不知道怎么利用。确实,我也是一脸懵,就像开发者说的,你必要深入学习一下TLS/SSL的工作原理
https://i-blog.csdnimg.cn/direct/619fd8de269342aba2250a1013b7601a.png
固然了,这都不是我们的重点,重点是解决当前碰到的题目。
有了样例,那我们直接拿过来用
$sslOptions = array(
'cafile' => CERTS_PATH . '/ca_certificate.pem',
'local_cert' => CERTS_PATH . '/client_certificate.pem',
'local_pk' => CERTS_PATH . '/client_key.pem',
'verify_peer' => true,
'verify_peer_name' => false,
);
$connection = new AMQPSSLConnection(HOST, 5671, USER, PASS, VHOST, $sslOptions); 此时会发现能连上了,但是运行会提示一个信息
https://i-blog.csdnimg.cn/direct/247f32e6ef87493088917d9e75abab42.png
不是吧!我刚找的解决方案你就打算弃用了,也不难理解。为什么同样是连接却要用两种方法实现,随着我查看源码我就发现了。
先看最开始连接的方法:AMQPStreamConnection
https://i-blog.csdnimg.cn/direct/0b84263d79fa42928d9fda38016df66d.png
一般很少人会去看这个,因为这个方法只有前面4个参数是必填的,背面都有默认值,例如最开始报错超时3秒也是在这设置。这里我们就看到在参数里篇有个$ssl_protocol和?AMQPConnectionConfig $config两个参数,不丢脸出这个就是可以或许支持SSL的,这也是AMQPSSLConnection方法会弃用的缘故原由,不然我本地用着AMQPStreamConnection方法好好的,到其他地方,用不了了。
知道了AMQPStreamConnection可以支持SSL了,我们看一下AMQPConnectionConfig类
https://i-blog.csdnimg.cn/direct/6e656e65d2214db98cfde90ae1f029eb.png
这个类是用来设置连接参数的
https://i-blog.csdnimg.cn/direct/e4eb86c2eb15406bb3cadfcaef1ba57a.png
根据样例我们不难设置这个ssl相关的数据,不过因为我没有证书,所以天然不用去管这个。
接下来回头看看支持SSL的类AMQPSSLConnection
https://i-blog.csdnimg.cn/direct/8c2105fe03f54f93aaee91ce1d75c379.png
对的,你没看错,AMQPSSLConnection继承了AMQPStreamConnection,合着搞了泰半天你们本来就是一起的。这里我们看到$ssl_options参数就是样例中ssl参数设置的位置
https://i-blog.csdnimg.cn/direct/a8f3a2136774493c8c33392348443459.png
弄完之后AMQPSSLConnection又构建父类初始化,就是还是AMQPSSLConnection,把ssl参数加上,加的参数位置是$context,直接把方法拿过来用就可以了
https://i-blog.csdnimg.cn/direct/8502a08129104399b23716bbecb4607c.png
AMQPSSLConnection并没有用AMQPConnectionConfig来设置ssl参数,那我们也可以不用,直接整
解决方案
$sslOptions = array(
'verify_peer' => false,
);
$ssl_context = stream_context_create();
foreach ($sslOptions as $k => $v) {
stream_context_set_option($ssl_context, 'ssl', $k, $v);
}
$connection = new \PhpAmqpLib\Connection\AMQPStreamConnection(
$config['host'],
$config['port'],
$config['user'],
$config['password'],
'/',
false,
'AMQPLAIN',
null,
'en_US',
3.0,
3.0,
$ssl_context
); 看到没,verify_peer设置为false,是不是很眼熟,就是平时我们在https请求时忽略证书校验那样。至于AMQPConnectionConfig类设置参数这个我就不再细细研究了,原理是一样的。
verify_peer:验证证书是否对等,也就是是否必要校验证书的意思,设置为true就是要校验。
要校验就申请CA证书或者自签证书,放在参数里即可。
我这都没给我提供就懒得去折腾了,解决题目即可,碰到题目我们再解决。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]