amranidev/micro-bus
使用 AWS SNS/SQS 构建 laravel/lumen 微服务应用程序
Requires
- aws/aws-sdk-php: ^3.95
Requires (Dev)
- orchestra/testbench: ^7.5
README
使用 micro-bus 构建 laravel 微服务
什么是 micro-bus?
MicroBus 是一个用于使用事件驱动架构(发布-订阅)和亚马逊云服务(SNS/SQS)构建微服务的 laravel/lumen 包。
什么是事件驱动微服务?
安装。
Laravel。
-
安装包,
composer require amranidev/micro-bus
。 -
发布订阅者配置文件,
php artisan vendor:publish --tag=subscriber
。 -
发布发布者配置文件,
php artisan vendor:publish --tag=publisher
。 -
添加订阅者和发布者环境变量。
- 在
.env
文件中添加。
# Standard SQS keys. SUBSCRIBER_SQS_KEY=<SQS-KEY-AWS> SUBSCRIBER_SQS_SECRET=<SQS-SECRET-AWS> SUBSCRIBER_SQS_PREFIX=https://sqs.<sqs-region>.amazonaws.com/<project-id> SUBSCRIBER_SQS_QUEUE=<QUEUE-NAME-AWS> SUBSCRIBER_SQS_REGION=<SQS-REGION-AWS> PUBLISHER_SNS_KEY=<SNS-KEY-AWS> PUBLISHER_SNS_SECRET=<SNS-KEY-AWS> PUBLISHER_SNS_REGION=<SNS-REGION-AWS> # FIFO SQS Keys. SUBSCRIBER_FIFO_SQS_KEY=<SQS-KEY-AWS> SUBSCRIBER_FIFO_SQS_SECRET=<SQS-SECRET-AWS> SUBSCRIBER_FIFO_SQS_PREFIX=https://sqs.<sqs-region>.amazonaws.com/<project-id> SUBSCRIBER_FIFO_SQS_QUEUE=<QUEUE-NAME-AWS> SUBSCRIBER_FIFO_SQS_REGION=<SQS-REGION-AWS> # SNS Keys. PUBLISHER_SNS_KEY=<SNS-KEY-AWS> PUBLISHER_SNS_SECRET=<SNS-KEY-AWS> PUBLISHER_SNS_REGION=<SNS-REGION-AWS>
- 在
-
在
config/queue.php
中添加队列连接配置。// Standard SQS configuration. 'subscriber' => [ 'driver' => 'subscriber', 'key' => env('SUBSCRIBER_SQS_KEY', 'your-public-key'), 'secret' => env('SUBSCRIBER_SQS_SECRET', 'your-secret-key'), 'prefix' => env('SUBSCRIBER_SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 'queue' => env('SUBSCRIBER_SQS_QUEUE', 'your-queue-name'), 'region' => env('SUBSCRIBER_SQS_REGION', 'us-east-1'), 'retry_after' => 90, ], // FIFO SQS configuration. 'subscriber-fifo' => [ 'driver' => 'subscriber', 'key' => env('SUBSCRIBER_FIFO_SQS_KEY', 'your-public-key'), 'secret' => env('SUBSCRIBER_FIFO_SQS_SECRET', 'your-secret-key'), 'prefix' => env('SUBSCRIBER_FIFO_SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 'queue' => env('SUBSCRIBER_FIFO_SQS_QUEUE', 'your-queue-name'), 'region' => env('SUBSCRIBER_FIFO_SQS_REGION', 'us-east-1'), 'retry_after' => 90, ],
恭喜,您已成功安装 micro-bus 🚀
Lumen。
-
安装包,
composer require amranidev/micro-bus
。 -
添加订阅者和发布者环境变量。
- 在
.env
文件中添加。
SUBSCRIBER_SQS_KEY=<SQS-KEY-AWS> SUBSCRIBER_SQS_SECRET=<SQS-SECRET-AWS> SUBSCRIBER_SQS_PREFIX=https://sqs.<sqs-region>.amazonaws.com/<project-id> SUBSCRIBER_SQS_QUEUE=<QUEUE-NAME-AWS> SUBSCRIBER_SQS_REGION=<SQS-REGION-AWS> PUBLISHER_SNS_KEY=<SNS-KEY-AWS> PUBLISHER_SNS_SECRET=<SNS-KEY-AWS> PUBLISHER_SNS_REGION=<SNS-REGION-AWS>
- 在
-
在根目录中创建
config
文件夹。 -
在配置文件夹中创建
subscriber.php
。
<?php return [ 'subscribers' => [ '__CLASSNAME__' => 'TopicArn' ] ];
- 在配置文件夹中创建
publisher.php
。
<?php return [ 'sns' => [ 'key' => env('PUBLISHER_SNS_KEY'), 'secret' => env('PUBLISHER_SNS_SECRET'), 'region' => env('PUBLISHER_SNS_REGION'), ], 'events' => [ 'user_created' => 'arn:aws:sns:eu-west-1:111111111111:user_created' ] ];
- 在配置文件夹中创建
queue.php
。
从 laravel/laravel 复制相同的 queue.php
并将订阅者配置添加到 connections
中。
'subscriber' => [ 'driver' => 'subscriber', 'key' => env('SUBSCRIBER_SQS_KEY', 'your-public-key'), 'secret' => env('SUBSCRIBER_SQS_SECRET', 'your-secret-key'), 'prefix' => env('SUBSCRIBER_SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), 'queue' => env('SUBSCRIBER_SQS_QUEUE', 'your-queue-name'), 'region' => env('SUBSCRIBER_SQS_REGION', 'us-east-1'), 'retry_after' => 90, ],
- 配置
subscriber
、publisher
、queue
并在bootstrap/app.php
中注册 ServiceProvider。
$app->configure('publisher') $app->configure('subscriber'); $app->configure('queue'); $app->register(Amranidev\MicroBus\MicroBusServiceProvider::class);
恭喜,您已成功在 lumen 中安装 micro-bus 🚀
使用方法。
请注意,您需要在 SNS 中定义您的主题,在 SQS 中创建队列,并将 SNS 主题绑定到队列,AWS 配置不包括在此文档中。
在两个 laravel 节点中安装包后,现在让我们让它们互相通信。基本上,它们可以是同时作为订阅者或发布者,或者,您可以将一个作为订阅者,另一个作为发布者,这完全取决于您。
假设我们有一个名为 A 的 laravel 应用程序和一个名为 B 的 lumen 微服务。
当在 A 中创建用户时,B 需要将用户的电子邮件添加到邮件列表,
在这种情况下 A 是发布者,而 B 是订阅者。
请注意,SNS 配置需要添加到 A,而 SQS 需要添加到 B,请参阅上面的安装步骤。
设置 Laravel 应用程序(微服务 A)。
首先,让我们将我们在 AWS 中创建的主题添加到 A 中,我们需要在 config/publisher.php
中指定一个事件名称 user_created
和 AWS 的 TopicArn。
<?php return [ 'sns' => [ 'key' => env('PUBLISHER_SNS_KEY'), 'secret' => env('PUBLISHER_SNS_SECRET'), 'region' => env('PUBLISHER_SNS_REGION'), ], 'events' => [ 'user_created' => 'arn:aws:sns:eu-west-1:111111111111:user_created' ] ];
在 A 中配置 SNS 后,我们需要添加当用户被创建时向 SNS 发布消息的功能,为了这样做
... Publisher::publish('user_created', $user); ...
或者您可以使用以下方式发布消息
- 服务容器
// Standard SNS. app('sns.connection')->publish('event', $data); // Fifo SNS. app('sns.fifo.connector')->publish('event', $data);
- Artisan 命令
php artisan bus:publish <data> <eventOrTopicname>
设置 Lumen(微服务 B)。
现在,让我们在 B 中创建一个订阅者类,该类将监听 A。
php artisan make:subscriber UserCreated
此命令将在 app/Subscribers/
中为您生成一个作业类。
<?php namespace App\Subscribers; use Amranidev\MicroBus\Sqs\Traits\JobHandler; class UserCreated { use JobHandler; /** * @var mixed */ public $payload; /** * @var \Illuminate\Queue\Jobs\Job */ public $job; /** * Execute the job. * * @return void */ public function handle() { // } }
如你所见,创建的作业有$payload
属性,它仅仅是A将要发布的片段数据,在我们的案例中是$user
。
Handle方法负责执行来自SQS的作业。
/** * Execute the job. * * @return void */ public function handle(MailingList $mailingList) { $user = $this->payload; // MailingList is resolved automatically from the container. $mailingList->addUser($user->name, $user->email); }
在B中,我们需要做的最后一件事是将这个类与config/subscriber.php
中的TopicArn关联起来。
<?php return [ 'subscribers' => [ \App\Subscribers\UserCreated::class => 'arn:aws:sns:eu-west-1:111111111111:user_created' ] ];
然后运行queue:work
命令,php artisan queue:work <connection-name>
。
贡献。
感谢您考虑为这个项目做出贡献!贡献指南可在贡献指南中找到。
替代方案(Google Cloud Platform)。
测试。
- 拉取localstack/localstack docker镜像。
docker pull localstack/localstack
创建一个docker-compose.yml
文件。
version: "3.8" services: localstack: container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}" image: localstack/localstack network_mode: bridge ports: - '4566-4597:4566-4597' environment: - SERVICES=sqs,sns - DEBUG=${DEBUG-} - DATA_DIR=${DATA_DIR-} - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-} - LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY-} # only required for Pro - HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack - DOCKER_HOST=unix:///var/run/docker.sock volumes: - "${TMPDIR:-/tmp}/localstack:/tmp/localstack" - "/var/run/docker.sock:/var/run/docker.sock"
-
运行
docker-compose run
来启动localstack,如果你使用mac,请运行TMPDIR=/private$TMPDIR docker-compose up
。 -
最后运行
phpunit
。