kfzteile24 / queue-bundle
在AWS PHP SDK Sqs-和SnsClient之上提供抽象,使其更适合DI(依赖注入)。
1.3.0
2023-07-04 11:00 UTC
Requires
- php: ^7.1
- ext-json: *
- aws/aws-php-sns-message-validator: ^1.6
- aws/aws-sdk-php: ^3.115
- ramsey/uuid: ^3.8
Requires (Dev)
- jms/serializer-bundle: ^3.4
- phpunit/phpunit: ~5.7.5
- symfony/config: ^3.4
- symfony/http-kernel: ^3.4
- symfony/serializer: ^3.4
README
此Bundle是通过重构petsdeli/queue-bundle创建的
安装
- 运行以下命令安装此bundle
composer require kfzteile24/queue-bundle
- 配置您应用程序中希望使用的客户端
# app/config/config.yml kfz24_queue: clients: notify: type: "sns" region: "eu-central-1" resource: "arn:aws:sns:eu-central-1:123456789012:topic" access_key: "AKIAABCDEFGHIJKLMNOP" secret_access_key: "s3CR3t4Cc3S5K3y" one_consumer: type: "sqs" region: "eu-central-1" resource: "https://sqs.eu-central-1.amazonaws.com/123456789012/one-queue" access_key: "AKIAABCDEFGHIJKLMNOP" secret_access_key: "s3CR3t4Cc3S5K3y" another_consumer: type: "sqs" region: "eu-central-1" resource: "https://sqs.eu-central-1.amazonaws.com/123456789012/another-queue" access_key: "AKIAABCDEFGHIJKLMNOP" secret_access_key: "s3CR3t4Cc3S5K3y" large_payload_client: region: "eu-central-1" endpoint: "http://s3-eu-central-1.amazonaws.com/consumer_bucket" bucket: "consumer_bucket" access_key: "AKIAABCDEFGHIJKLMNOP" secret_access_key: "s3CR3t4Cc3S5K3y" use_path_style_endpoint: "true" | "false"
使用方法
从容器中获取您的配置服务
/** @var \Kfz24\QueueBundle\Client\Aws\SnsClient $client */ $client = $container->get('kfz24.queue.client.notify'); $client->send([ 'type' => 'notification', 'data' => [1, 2, 3] ]);
或根据您的需要将它们注入到您的服务中。
<service id="app.consumer_command" class="AppBundle\Command\Consumer"> <argument type="service" id="kfz24.queue.client.one_consumer" /> <tag name="console.command" /> </service>
这是关于什么的?
QueueBundle在AWS PHP SDK SqsClient
和SnsClient
之上提供抽象,并使其更适合DI。抽象的目的是允许比直接使用原始客户端实现有更多的灵活性。
尤其是在您决定将队列配置从例如1个生产者和1个消费者之间的点对点队列更改为点对多点队列设置时,因为您可能需要2个、3个……消费者处理相同的消息。这可以通过创建一个SNS主题并将您喜欢的队列订阅到它来实现,而不是直接向队列发送消息。
在这种情况下,使用本地客户端有一些缺点。它们不共享公共接口,并以类方法的形式公开各自的API方法。例如,向它们发送消息的调用看起来不同
$snsClient = new \Aws\Sns\SnsClient([…]); $sqsClient = new \Aws\Sqs\SqsClient([…]); $result = $snsClient->publish([ 'Message' => 'My Message' ]); $result = $sqsClient->sendMessage([ 'MessageBody' => 'My Message' ]);
这本身就将一个有多个消费者组成的架构决策变成了重构噩梦。但您也需要在消费者端了解您的队列架构。事实上,同一个消息看起来相当不同,取决于它是直接发布到SQS队列还是通过SNS主题转发到那里。假设一个消息
{"foo": "bar"}
当直接发送到队列时,MessageBody
看起来就像您预期的那样
{"foo": "bar"}
但如果消息是通过SNS主题排队,则添加了一个SNS封装,将MessageBody
变成
{ "Type" : "Notification", "MessageId" : "4743aa35-e3cd-4562-bd9e-b25778778206", "TopicArn" : "arn:aws:sns:eu-central-1:123456789012:sns-test", "Message" : "{\"foo\": \"bar\"}", "Timestamp" : "2017-05-23T09:58:23.595Z", "SignatureVersion" : "1", "Signature" : "MDEyMzQ1Njc4OTAwMTIzNDU2Nzg5MDAxMjM0NTY3ODkwMDEyMzQ1Njc4OTAwMTIzNDU2N …", "SigningCertURL" : "https://sns.eu-central-1.amazonaws.com/SimpleNotificationService …", "UnsubscribeURL" : "https://sns.eu-central-1.amazonaws.com/?Action=Unsubscribe&Subsc …", "MessageAttributes" : { "AWS.SNS.MOBILE.MPNS.Type" : {"Type":"String","Value":"token"}, "AWS.SNS.MOBILE.MPNS.NotificationClass" : {"Type":"String","Value":"realtime"}, "AWS.SNS.MOBILE.WNS.Type" : {"Type":"String","Value":"wns/badge"} } }
因此,此bundle的SqsClient
实现检测MessageBody
是否包含SNS封装,如果包含,则首先验证其完整性,然后自动展开其内容。这对您来说是完全透明的。