eduzz / hermes
此库负责封装与队列管理器的连接。主要针对与 RabbitMQ 的使用。
Requires
- php: >=7.0
- ext-bcmath: *
- ext-mbstring: *
- php-amqplib/php-amqplib: ^2.12
Requires (Dev)
- mockery/mockery: ^1.0
- phpunit/phpunit: ^7.0
- dev-master
- dev-feature-retry-operations
- dev-hotfix-add-nack-queue-bind
- dev-feature-add-retry-ttl
- dev-hotfix-composer-version-php-amqplib
- dev-feature-update-php-amqplib
- dev-hotfix-singleton
- dev-hotfix-opening-unnecessary-connections
- dev-feature-add-connection-name-use-laravel-project-name
- dev-feature-add-connection-name
- dev-hotfix-remove-validation
- dev-fix-declare-nack-queue
This package is not auto-updated.
Last update: 2024-09-25 23:34:56 UTC
README
此库负责封装与队列管理器的连接。主要针对与 RabbitMQ 的使用。
** 依赖:PHP 5.3 ** 由于使用了命名空间。
** 依赖:bcmath 和 mbstring ** 由于使用了 php-amqplib 通过 AMQP 0-9-1 协议进行连接。
安装
首先,将 Hermes 的依赖和仓库添加到我们的 composer.json 文件中
{
"require": {
"eduzz/hermes": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "git@github.com:eduzz/hermes.git"
}
]
}
然后,运行以下命令
composer dump-autoload
以更新 composer 缓存
composer install
以安装依赖和 Hermes
PS:在安装 Hermes 的 shell 中,需要确保你有连接到 GitHub 的密钥。
在 Laravel 项目中安装
下一步是将 Hermes 注册到 service providers 列表中,在 config/app.php 中,将 Hermes 添加到 providers 列表中,并将 Hermes facade 添加到 aliases 列表中。
'providers' => [ // ... Eduzz\Hermes\HermesLaravelServiceProvider::class, ],
'aliases' => [ // ... 'Hermes' => Eduzz\Hermes\Facades\HermesFacade::class, ],
我们需要清除缓存,更新我们的包,并发布 Hermes 的配置
php artisan cache:config
composer update
php artisan vendor:publish --tag="config"
如果一切顺利,将显示以下消息
Copied File [/vendor/eduzz/src/Config/hermes.php] To [/config/hermes.php]
因此,需要在 config/hermes.php 文件中的 connection 变量中配置 Hermes,这是您的连接数据所在之处,例如
<?php return [ 'connection' => [ 'host' => env('HERMES_HOST', '127.0.0.1'), 'port' => env('HERMES_PORT', 5672), 'username' => env('HERMES_USERNAME', 'guest'), 'password' => env('HERMES_PASSWORD', 'guest'), 'vhost' => env('HERMES_VHOST', '/'), 'connection_name' => env('HERMES_CONNECTION_NAME', '/'), ] ];
在 Lumen 项目中安装
对于 Lumen 项目的安装,需要手动创建配置文件,在 config 文件夹中添加一个名为 hermes.php 的文件,内容如下
<?php return [ 'connection' => [ 'host' => env('HERMES_HOST', '127.0.0.1'), 'port' => env('HERMES_PORT', 5672), 'username' => env('HERMES_USERNAME', 'guest'), 'password' => env('HERMES_PASSWORD', 'guest'), 'vhost' => env('HERMES_VHOST', '/'), 'connection_name' => env('HERMES_CONNECTION_NAME', '/'), ] ];
然后,在 bootstrap/app.php 文件中注册我们的 service provider,找到注册行并添加
<?php // ... $app->register(Eduzz\Hermes\HermesLaravelServiceProvider::class); // ...
在 bootstrap/app.php 中添加对 Hermes 配置的调用
<?php $app->configure('hermes'); return $app;
在没有 Illuminate 框架的项目中安装
在没有 Laravel/Lumen 的项目中使用 Hermes,需要手动设置配置,例如
<?php require 'vendor/autoload.php'; use Eduzz\Hermes\Hermes; $hermes = new Hermes([ 'host' => '127.0.0.1', 'port' => 5672, 'username' => 'guest', 'password' => 'guest', 'vhost' => '/' ]);
有一个名为 setConfig 的方法,可以在不通过构造函数的情况下更新配置。
使用方法
Hermes 与 rabbitMQ 有两种交互,声明队列,消费队列和发送消息。
发送消息
定义消息
为了定义一个新消息,需要扩展我们的抽象消息
<?php namespace App\HermesMessages; use Eduzz\Hermes\Message\AbstractMessage; class ExampleMessage extends AbstractMessage { public function __construct($id, $message) { parent::__construct( // Sua routing Key 'app.module.action', // Seu payload ['id' => $id, 'message' => $message] ); } }
在您的消息中,无论逻辑如何,都可以传递任何数据,但是 Hermes 消息必须始终接收一个字符串作为 routingKey,第二个参数是任意数据的数组。
在 Laravel/Lumen 中发送消息
我们将使用 Laravel 的依赖注入来实例化 Hermes,并获取 config/hermes.php 文件中的配置,以下是一个使用 Hermes 的 Laravel 控制器示例
<?php namespace App\Http\Controllers; use Illuminate\Routing\Controller as BaseController; use Eduzz\Hermes\Hermes; use App\HermesMessages\ExampleMessage; class Controller extends BaseController { private $hermes; public function __construct(Hermes $hermes) { $this->hermes = $hermes; parent::__construct(); } public function method() { // Sua lógica aqui $this->hermes->publish( new ExampleMessage(5, 'Hello world'), 'my_exchange' // Paramêtro opcional, qual exchange a mensagem deve ir ); } }
publish 方法中的第二个参数(exchange)是可选的,它是消息将发送到的 exchange,默认使用名为 'eduzz' 的 exchange。
在没有框架的情况下使用 Hermes 发送消息
逻辑相同,但是通过构造函数或 setConfig 传递配置,例如:return array( 'connection' => array( 'host' => env('HERMES_HOST', '127.0.0.1'), 'port' => env('HERMES_PORT', 5672), 'username' => env('HERMES_USERNAME', 'guest'), 'password' => env('HERMES_PASSWORD', 'guest'), 'vhost' => env('HERMES_VHOST', '/'). 'connection_name' => env('HERMES_CONNECTION_NAME', '/'), ) );
<?php $hermes->publish( new Message( [ "id" => 123, "name" => "John Doe", "age" => 18 ], 'my_exchange' // Paramêtro opcional, qual exchange a mensagem deve ir ); );
声明和消费队列
添加新的队列
要使用我们交易所(topic)的工作模式消费队列,需要声明一个队列并执行一个'bind'操作。bind操作是将一个队列绑定到一个routingKey上,也就是说,具有某个特定routingKey的消息将会被发送到我们创建的队列中。
我们将使用Hermes来声明一个队列并进行bind操作。
<?php $queueName = $hermes->addQueue( 'queue_name', // Se for uma string vazia, irá criar um nome aleatório true, // Ativa o nack e cria uma fila adicional chamada queue_name.nack, o paramêtro é opcional e o default é a fila ativa true // Parâmetro opcional de fila durável ou não, o padrão é durável ) ->bind( 'my.routing.key', null, // Parâmetro opcional de nome da fila, se for null, irá pegar o nome da última fila criada 'custom_exchange'; // Parâmetro opcional exchange, se não for passado, irá pegar a exchange default 'eduzz' ) ->getLastQueueCreated(); // Retorna o nome da última fila criada
消费队列
为了消费队列,我们需要为我们创建的队列添加一个回调函数,然后调用Hermes的start方法来启动队列的处理。
<?php $hermes->addListenerTo( 'queue_name', function($msg) { echo json_encode($msg->body); }, true // Ativa ou não a opção de errorHandling do Hermes ); $hermes->start();
如果Hermes的errorHandling功能已启用,则连接的队列必须启用nack功能。未捕获的异常将在回调函数中处理,并将消息内容发送到nack队列。
如果nack已启用且errorHandling未启用,则在其回调函数中,需要使用ack和nack方法,例如:
<?php $hermes->addListenerTo( 'queue_name', function($msg) use ($hermes) { try { echo json_encode($msg->body); return $hermes->consumer()->ack($msg); catch(\Exception $e) { return $hermes->consumer()->nack($msg); } }, false // Error handling desativado ); $hermes->start();