PHP7.3 + RabbitMQ 在Thinkphp6中的代码链接部署说明

记录一下php代码如何链接Rabbitmq,扩展采用composer维护,免去服务器安装PHP需要扩展的烦恼。composer包和php扩展安装两者方式的好坏与否这里不做讨论,可以自行百度了解

composer require php-amqplib/php-amqplib

1.配置rabbitmq.config

<?php
// +----------------------------------------------------------------------
// | rabbitMQ 示例配置
// +----------------------------------------------------------------------

return [

    // 连接信息
    'AMQP' => [
        'host'     => env('rabbit.host','127.0.0.1'),
        'port'     => env('rabbit.port','5672'),
        'username' => env('rabbit.username','guest'),
        'password' => env('rabbit.password','guest'),
        'vhost'    => env('rabbit.vhost','/')
    ],

    //topic队列
    'topic_queue' => [
        'exchange_name' => 'topic_exchange',
        'exchange_type' => 'topic',
        'queue_name'    => 'topic_queue',
        'route_key'     => '',
        'consumer_tag'  => 'topic'
    ],

    //机审队列
    'machine_risk_queue' => [
        'exchange_name' => 'topic_exchange',
        'exchange_type' => 'topic',
        'queue_name'    => 'risk_queue',
        'route_key'     => '*.risk',
        'consumer_tag'  => 'risk'
    ],
];

2.Rabbitmq类文件

<?php

namespace app\services;


use PhpAmqpLib\Message\AMQPMessage;
use think\facade\Config;
use think\facade\Log;
use PhpAmqpLib\Exchange\AMQPExchangeType;
use PhpAmqpLib\Connection\AMQPStreamConnection;

class RabbitMqService
{
    /**
     * 消费者
     */
    public function consumer($name, $func = null)
    {
        //获取配置
        $amqp       = Config::get('rabbitmq.AMQP');
        $amqpDefail = Config::get('rabbitmq.' . $name . '_queue');

        //连接
        $connection = new AMQPStreamConnection(
            $amqp['host'],
            $amqp['port'],
            $amqp['username'],
            $amqp['password']
        );
        $amqpDefail['queue_name'] = $amqpDefail['queue_name'].env('domain.app_id');
        $amqpDefail['exchange_name'] = $amqpDefail['exchange_name'].env('domain.app_id');

        //建立通道
        $channel = $connection->channel();

        //流量控制
        $channel->basic_qos(null, 1, null);

        //初始化交换机
        $channel->exchange_declare($amqpDefail['exchange_name'], $amqpDefail['exchange_type'], false, true, false);

        //初始化队列
        $channel->queue_declare($amqpDefail['queue_name'], false, true, false, false);

        //绑定队列与交换机
        $channel->queue_bind($amqpDefail['queue_name'], $amqpDefail['exchange_name'], $amqpDefail['route_key']);

        //消费消息
        $channel->basic_consume($amqpDefail['queue_name'], $amqpDefail['consumer_tag'], false, false, false, false, function ($msg) use ($func) {
            sublog(['消费者1', $msg->body], 'rabbitmq_debug');
            $data = !empty($msg->body) ? json_decode($msg->body, true) : [];
            if (!empty($data)) {
                try {
                    sublog(['消费者2', $data], 'rabbitmq_debug');
                    $func($data);
                    $msg->ack();
                } catch (\Exception $ee) {
                    sublog(['消费者2', $data,$ee->getMessage(), $ee->getFile(), $ee->getLine()], 'rabbitmq_debug_err');
                    $msg->nack(true);
                }
            }

        });

        //退出
        register_shutdown_function([$this, 'shutdown'], $channel, $connection);

        //监听
        while (count($channel->callbacks)) {
            $channel->wait();
        }
    }

    /**
     * 生产者
     * @param $data
     * @param $key
     */
    public function publish($data, $key, $name)
    {
        //获取配置
        $amqp       = Config::get('rabbitmq.AMQP');
        $amqpDefail = Config::get('rabbitmq.' . $name . '_queue');

        //连接
        $connection = new AMQPStreamConnection(
            $amqp['host'],
            $amqp['port'],
            $amqp['username'],
            $amqp['password']
        );
        $amqpDefail['queue_name'] = $amqpDefail['queue_name'].env('domain.app_id');
        $amqpDefail['exchange_name'] = $amqpDefail['exchange_name'].env('domain.app_id');

        //建立通道
        $channel = $connection->channel();


        //推送成功
        $channel->set_ack_handler(function (AMQPMessage $message) use ($data) {
            sublog(['生产者1', $message, $data], 'rabbitmq_debug');
        });


        //推送失败
        $channel->set_nack_handler(
            function (AMQPMessage $message) use ($data) {
                sublog(['生产者1-error', $message, $data], 'rabbitmq_debug');
            }
        );

        $channel->confirm_select();


        //初始化交换机
        $channel->exchange_declare($amqpDefail['exchange_name'], $amqpDefail['exchange_type'], false, true, false);
        sublog(['生产者2', $amqpDefail, $amqp], 'rabbitmq_debug');

        //申明队列
        $channel->queue_declare($amqpDefail['queue_name'], false, true, false, false);

        //绑定队列与交换机
        $channel->queue_bind($amqpDefail['queue_name'], $amqpDefail['exchange_name'], $key);


        //生成消息
        $msg = new AMQPMessage(json_encode($data, 256), [
            'content-type'  => 'application/json',
            'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT
        ]);

        //推送消息到某个交换机

        $channel->basic_publish($msg, $amqpDefail['exchange_name'], $key);

//        $channel->confirm_select_ok();
        $channel->wait_for_pending_acks();

        $channel->close();
        $connection->close();

        return true;
    }

    /**
     * 退出
     * @param  $channel [信道]
     * @param $connection [连接]
     */
    public function shutdown($channel, $connection)
    {
        $channel->close();
        $connection->close();
    }

}

调用范例

$res = app(services\RabbitMqService::class)->publish(['queue_id' => $queue_id], '*.risk', 'machine_risk');

其他说明:

1.需要特别注意每个exchange中的路由一定要匹配中,不然无法消费。

2.vhost参数配置相当于应用隔离,如果Mq服务需要应用到多个不同的项目中,这个参数就起码很大作用。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值