基於Yii2對RabbitMQ的基本用法封裝及佇列實現(一)

so_easy發表於2020-08-28

介紹

該類庫從功能點上實現了RabbitMQ的所有佇列形式,並且結合《RabbitMQ實戰指南》這本書的指導思想和yii2-queue擴充套件的實戰經驗融合在了類庫的封裝。結合Yii2的元件概念,使佇列的實現和使用更加的簡潔輕便。除此之外還實現了RPC佇列,可以實現跨專案呼叫。最後模擬supervisor對RabbitMQ的消費者程式實現了web管理。

關鍵詞

1、普通佇列:相比延時佇列,沒有啟用延時功能。
exchange --rk--> queue

2、延時佇列:相比普通佇列多了個延時功能
exchange --rk-->queue --ttl-> delayQueue

3、備份路由:訊息沒有正常路由到預期的佇列最後透過備份路由到備份佇列
exchange ------>queue
            |
            \_ aeExchange --> aeQueue

4、佇列副本:一個訊息透過exchange路由到不同佇列
         | --rk0 --> queue0
exchange | --rk1---> queue1
         |-- rk2 --> queue2

5、RPC佇列:支援跨專案呼叫

功能點

  • 實現了RabbitMQ的基本佇列型別:普通佇列、延時佇列、優先佇列、Rpc佇列。
  • 實現普通消費者和Rpc消費者
  • 實現了備份路由
  • 支援RabbitMQ的所有繫結型別。
  • 支援不同的消費內容序列化
  • 支援佇列副本
  • 支援事件訂閱
  • 支援單個訊息傳送和批次訊息傳送
  • 新增配套消費者程式管理
  • 結合佇列副本,支援隨機路由和輪詢路由。(後續還會有加權路由以及動態路由!)
  • 等等還在實現中

先談談普通佇列的實現

結合Yii2元件的特性,實現起來也是非常簡單:
step1:在Yii2配置元件

/** 普通佇列定義 */
    'easyQueue' => [
        'class' =>  \pzr\amqp\queue\EasyQueue::class,
        'host' => '127.0.0.1',
        'port' => 5672,
        'user' => 'guest',
        'password' => 'guest',
        'queueName' => 'easy_queue',
        'exchangeName' => 'easy_exchange',
        'routingKey' => 'easy',
        // 'serizer' => \pzr\amqp\serializers\PhpSerializer, //default value
        // 'dulicater' => \pzr\amqp\duplicate\DuplicateRandom, //default value
        // 'duplicate' => 0, //佇列的副本數,不啟用則設定為0
        // priority => 10, //定義優先順序佇列時配置
    ],

step2:在控制器中使用元件

Yii::$app->easyQueue->push(new CountJob([
    'count' => 1,
]);

這裡的CountJob是消費的實體,物件的定義如:

class CountJob extends \pzr\amqp\AmqpJob
{
    public $count;
    public function execute()
    {
        return $this->count;
    }
}

step3:增加消費者
首先是消費者元件的配置:

/** 普通消費者 */
    'consumer' => [
        // 'class' =>  \pzr\amqp\Amqp::class,
        'class' =>  \pzr\amqp\AmqpBase::class,
        'host' => '127.0.0.1',
        'port' => 5672,
        'user' => 'guest',
        'password' => 'guest',
    ],

然後在控制器中呼叫消費者元件:

class AmqpController extends Controller
{
    // 普通消費者定義
    public function actionConsumer($queueName, $qos)
    {
        Yii::$app->consumer->consume($queueName, $qos);
    }
}

最後為了方便測試,可以在cli下啟動消費者程式:

/usr/bin/php yii amqp/consumer queueName qos

為了方便對程式管理可以使用supervisor 。

延時佇列的定義

延時佇列的定義和普通佇列幾乎一樣,只是在配置上稍微不同,如:

'delayQueue' => [
        'class' =>  \pzr\amqp\queue\DelayQueue::class,
        'host' => '127.0.0.1',
        'port' => 5672,
        'user' => 'guest',
        'password' => 'guest',
        'queueName' => '07_14_queue',
        'exchangeName' => '07_14_exchange',
        'exchangeType' => 'topic',
        'routingKey' => '07_14_delay.*.',
        'delayQueueName' => '07_14_delay_queue',
        'delayExchangeName' => '07_14_delay_exchange',
        'delayExchangeType' => 'topic',
        'ttl' => 5000, //ms
        'duplicate' => 2,
        // Other driver options
    ],

以上配置會自動生成普通佇列2個:07_14_queue_007_14_queue_1,並且訊息在普通佇列5000ms之後自動路由到延時佇列07_14_delay_queue

優先佇列定義

優先順序佇列的定義只需在配置上增加一個屬性:priority表示該佇列最大的優先順序。然後在傳送訊息的時候定義每條訊息的優先順序,不超過最大優先順序即可:

Yii::$app->easyQueue->push(new CountJob([
    'count' => 1,
    'priority' => 1
]);

最後

其他的佇列實現也是類似,但是Rpc佇列會和其他的稍有不同。第一節就先講這麼多!感興趣的話可以看看guthub的ReadMe(持續更新中)。有任何問題非常希望指正,提Issue,留言評論!
Composer的資源是(還沒有穩定的版本,努力中):composer require pzr/amqp
下一節說說Rpc佇列的實現!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章