Symfony 是一个流行的 PHP 框架,而 RabbitMQ 是一个常用的消息队列服务器。
Symfony RabbitMQ包(https://github.com/php-amqplib/RabbitMqBundle)
在 AWS 中使用 Symfony 和 RabbitMQ 可以提供以下优势:
- 高效的消息传递:实现异步处理和消息分发,提高系统的性能和可靠性。
- 解耦组件:不同的组件可以通过消息队列进行通信,而无需直接耦合。
- 弹性扩展:根据业务需求轻松扩展消息处理能力。
- 提高可靠性:即使某些组件出现故障,消息仍然可以在队列中等待处理,确保系统的可靠性。
在 AWS 中使用 Symfony 和 RabbitMQ 时,你可以:
- 在 AWS 上部署 Symfony 应用程序。
- 设置和配置 RabbitMQ 服务器,确保其在 AWS 环境中正常运行。
- 使用 Symfony 框架中的相关组件或库与 RabbitMQ 进行集成,发送和接收消息。
请注意,在实际使用中,还需要考虑以下因素:
- 安全性:确保消息的传输和存储是安全的。
- 监控和管理:对消息队列进行监控,以确保其正常运行。
- 错误处理:处理消息传递过程中的错误情况。
以下是一个简单的 Symfony 与 RabbitMQ 集成的示例代码片段,用于发送消息到 RabbitMQ:
```php
<?php
// 引入 Symfony 相关的类
use Symfony\Component\Messenger\Message;
use Symfony\Component\Messenger\MessageBusInterface;
// 创建一个消息对象
$message = new Message('YourMessagePayload');
// 获取消息总线实例
$messageBus = $container->get(MessageBusInterface::class);
// 发送消息
$messageBus->dispatch($message);
?>
```
在上面的代码中,首先创建了一个消息对象`$message`,其中包含要发送的消息内容。然后,通过依赖注入获取了 Symfony 的消息总线实例`$messageBus`,最后使用`dispatch()`方法发送消息。
请注意,这只是一个简单的示例,实际的集成可能需要更多的配置和设置。还需要安装和配置 RabbitMQ,并在 Symfony 中配置消息传递组件。具体的实现可能会因项目的需求和架构而有所不同。
====================================================
我们真的尝试了很多,但它仍然不能得到Symfony RabbitMQ包(https://github.com/php-amqplib/RabbitMqBundle)运行在AWS(与Docker)。AWS只允许AMQPS和端口5671在AWS管理的服务中打开。
这是我们当前的详细配置:
-
old_sound_rabbit_mq: connections: default: # nevermind secure: url: 'amqps://%env(RABBITMQ_USER)%:%env(RABBITMQ_PASSWORD)%@%env(RABBITMQ_HOST)%:%env(RABBITMQ_PORT)%' vhost: '%env(RABBITMQ_VHOST)%' lazy: true connection_timeout: 6 read_write_timeout: 6 ssl_context: verify_peer: false keepalive: true heartbeat: 60 use_socket: true # default false producers: # use 'old_sound_rabbit_mq.[my-producer-name]_producer' service to send data. article_create: connection: secure exchange_options: { name: pimcore.article.create, type: topic } queue_options: name: article_create
请注意,我们使用“url”配置值,因为它似乎是为包设置AMQPS的唯一方法。
docker-compose.yml的相关部分:
-
php-fpm: container_name: php-fpm environment: - RABBITMQ_HOST=my-rabbitmq # usually the docker container (otherwise localhost or server address) - RABBITMQ_PORT=5671 # locally it seems to work with 5672 - RABBITMQ_USER=user - RABBITMQ_PASSWORD=password - RABBITMQ_VHOST=/ rabbitmq: container_name: my-rabbitmq image: rabbitmq:3.8-management ports: - 127.0.0.1:15672:15672 - 127.0.0.1:5672:5672 - 127.0.0.1:5671:5671 environment: - RABBITMQ_DEFAULT_USER=pimcore - RABBITMQ_DEFAULT_PASS=pimcore volumes: - rabbitmq:/var/lib/rabbitmq
以下是从Symfony事件侦听器发送消息的方式:
$this->appKernel->getContainer()->get('old_sound_rabbit_mq.article_create_producer')->publish(
serialize($objToSend),
"article_create",
[
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
'message_id' => md5(uniqid("prefix", true))
]
);
这一切似乎都在本地工作,没有任何问题。在AWS中,我们得到以下错误:
不带插座:
Broken pipe or closed connection
带插座:
[2021-06-08 15:59:45] request.CRITICAL: Uncaught PHP Exception ErrorException: "Warning: socket_recv(): unable to read from socket [104]: Connection reset by peer" at /var/www/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Wire/IO/SocketIO.php line 121 {"exception":"[object] (ErrorException(code: 0): Warning: socket_recv(): unable to read from socket [104]: Connection reset by peer at /var/www/vendor/php-amqplib/php-amqplib/PhpAmqpLib/Wire/IO/SocketIO.php:121)"} []
来源:https://stackoverflow.com/questions/67890842/symfony-rabbitmq-bundle-in-a
最后解决了-您必须定义一个自定义AMQPChannel,其中包含一个带有SSL选项的自定义AMQPConnection,然后将此AMQPChannel设置为生成器:
// SSL
if ($port === 5671) {
$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,
);
$amqpSslConnection = new AMQPSSLConnection(
getenv('RABBITMQ_HOST'),
$port,
getenv('RABBITMQ_USER'),
getenv('RABBITMQ_PASSWORD'),
getenv('RABBITMQ_VHOST'),
$sslOptions
);
$amqpChannel = new AMQPChannel($amqpSslConnection);
$producer->setChannel($amqpChannel);
return $producer;
}