最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PHP實(shí)現(xiàn)RabbitMQ消息列隊(duì)的示例代碼

 更新時(shí)間:2022年05月10日 16:53:03   作者:PHP開源社區(qū)  
眾所周知,php本身的運(yùn)行效率存在一定的缺陷,所以如果有一個(gè)很復(fù)雜很耗時(shí)的業(yè)務(wù)時(shí),必須開發(fā)一個(gè)常駐內(nèi)存的程序。本文將利用PHP實(shí)現(xiàn)RabbitMQ消息列隊(duì),感興趣的可以了解一下

業(yè)務(wù)場(chǎng)景

項(xiàng)目公司是主php做開發(fā)的,框架為thinkphp。眾所周知,php本身的運(yùn)行效率存在一定的缺陷,所以如果有一個(gè)很復(fù)雜很耗時(shí)的業(yè)務(wù)時(shí),必須開發(fā)一個(gè)常駐內(nèi)存的程序。首先我想到了php的workerman與swoole,但是這里應(yīng)上面的標(biāo)題哈,想將耗時(shí)任務(wù)交給另一個(gè)服務(wù)器,同時(shí)列隊(duì)處理。所以這里我想獨(dú)立部署一個(gè)rabbitMQ服務(wù)器用于處理列隊(duì)任務(wù)。

當(dāng)rabbitMQ服務(wù)器我們準(zhǔn)備好了,建立了一個(gè)持久化命名為ceshi的列隊(duì),如下:

項(xiàng)目上生產(chǎn)者和消費(fèi)者的開發(fā)我這里全部采用tinkphp6+workerman,為便于管理。這里這么做也是因?yàn)榘l(fā)現(xiàn)workerman中對(duì)rabbitMQ的文檔解釋太少了!

所以開始踩坑!

1、首先部署好thinkphp6框架

過程去看thinkphp6手冊(cè)

2、安裝workerman擴(kuò)展

過程去看thinkphp6手冊(cè)

3、生產(chǎn)者

配置一個(gè)workerman類

創(chuàng)建的Send類代碼如下:

<?php

namespace app\workerman;
use Bunny\Channel;
use Workerman\RabbitMQ\Client;
use think\worker\Server;
class Send extends Server
{
    //websocket地址,一會(huì)用于測(cè)試。
    protected $socket = 'websocket://127.0.0.1:2345';

    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
{
        //websocket發(fā)送過來的消息
        $connection->send('我收到你的信息了:'.$data);
        //rabbitMQ配置
        $options = [
            'host'=>'127.0.0.1',//rabbitMQ IP
            'port'=>5672,//rabbitMQ 通訊端口
            'user'=>'admin',//rabbitMQ 賬號(hào)
            'password'=>'123456'//rabbitMQ 密碼
        ];
        (new Client($options))->connect()->then(function (Client $client) {
            return $client->channel();
        })->then(function (Channel $channel) {
            /**
             * 創(chuàng)建隊(duì)列(Queue)
             * name: ceshi         // 隊(duì)列名稱
             * passive: false      // 如果設(shè)置true存在則返回OK,否則就報(bào)錯(cuò)。設(shè)置false存在返回OK,不存在則自動(dòng)創(chuàng)建
             * durable: true       // 是否持久化,設(shè)置false是存放到內(nèi)存中RabbitMQ重啟后會(huì)丟失,
             *                        設(shè)置true則代表是一個(gè)持久的隊(duì)列,服務(wù)重啟之后也會(huì)存在,因?yàn)榉?wù)會(huì)把持久化的Queue存放在硬盤上,當(dāng)服務(wù)重啟的時(shí)候,會(huì)重新加載之前被持久化的Queue
             * exclusive: false    // 是否排他,指定該選項(xiàng)為true則隊(duì)列只對(duì)當(dāng)前連接有效,連接斷開后自動(dòng)刪除
             *  auto_delete: false // 是否自動(dòng)刪除,當(dāng)最后一個(gè)消費(fèi)者斷開連接之后隊(duì)列是否自動(dòng)被刪除
             */
            return $channel->queueDeclare('ceshi', false, true, false, false)->then(function () use ($channel) {
                return $channel;
            });
        })->then(function (Channel $channel) use($data){
            echo "發(fā)送消息內(nèi)容:".$data."\n";

            /**
             * 發(fā)送消息
             * body 發(fā)送的數(shù)據(jù)
             * headers 數(shù)據(jù)頭,建議 ['content_type' => 'text/plain'],這樣消費(fèi)端是springboot注解接收直接是字符串類型
             * exchange 交換器名稱
             * routingKey 路由key
             * mandatory
             * immediate
             * @return bool|PromiseInterface|int
             */

            return $channel->publish($data, ['content_type' => 'text/plain'], '', 'ceshi')->then(function () use ($channel) {
                return $channel;
            });
        })->then(function (Channel $channel) {
            //echo " [x] Sent 'Hello World!'\n";
            $client = $channel->getClient();
            return $channel->close()->then(function () use ($client) {
                return $client;
            });
        })->then(function (Client $client) {
            $client->disconnect();
        });
    }

    /**
     * 當(dāng)連接建立時(shí)觸發(fā)的回調(diào)函數(shù)
     * @param $connection
     */
    public function onConnect($connection)
{

    }

    /**
     * 當(dāng)連接斷開時(shí)觸發(fā)的回調(diào)函數(shù)
     * @param $connection
     */
    public function onClose($connection)
{

    }
    /**
     * 當(dāng)客戶端的連接上發(fā)生錯(cuò)誤時(shí)觸發(fā)
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
{
        echo "error $code $msg\n";
    }

    /**
     * 每個(gè)進(jìn)程啟動(dòng)
     * @param $worker
     */
    public function onWorkerStart($worker)
{


    }
}

上述都OK以后咱們可以項(xiàng)目路徑下通過命令啟動(dòng)這個(gè)生產(chǎn)者:

php think worker:server

測(cè)試發(fā)送數(shù)據(jù):

通過這個(gè)網(wǎng)站

連接【ws://127.0.0.1:2345】后發(fā)送數(shù)據(jù)!

前往rabbitMQ控制臺(tái)

列隊(duì)中有一條消息產(chǎn)生并且等待了!

這個(gè)時(shí)候你可能問,如果我發(fā)送數(shù)據(jù)不想通過ws發(fā)送而是接口發(fā)送怎么辦?

笨思路唄:接口給內(nèi)置服務(wù)器發(fā)消息->內(nèi)置服務(wù)去發(fā)消息給rabbitMQ

將協(xié)議改為tcp

然后重新啟動(dòng)服務(wù)

然后去tp6創(chuàng)建一個(gè)路由接口

接口代碼

<?php
namespace app\controller;

use app\BaseController;

class Index extends BaseController
{
    public function index(string $msg)
{
        //連接本地tcp服務(wù)
        $client = stream_socket_client('tcp://127.0.0.1:2345', $errno, $errmsg, 1);
        //發(fā)送字符串
        fwrite($client, $msg."\n");
        //斷開服務(wù)
        fclose($client);
        return 'OK';
    }

}

執(zhí)行結(jié)果:

說明接口成功的將數(shù)據(jù)發(fā)送給了本地內(nèi)置的tcp服務(wù)。

同時(shí),內(nèi)置服務(wù)將收到的數(shù)據(jù)給了rabbitMQ服務(wù)列隊(duì)中。

生產(chǎn)者完成。

4、消費(fèi)者

同生產(chǎn)者一樣新創(chuàng)建一個(gè)thinkphp6及安裝workerman擴(kuò)展,注意端口別和生產(chǎn)者沖突!這里我設(shè)置的是2346端口

創(chuàng)建的Receive類代碼如下:

<?php

namespace app\workerman;
use Bunny\Channel;
use Bunny\Message;
use Workerman\RabbitMQ\Client;
use think\worker\Server;
class Receive extends Server
{
    protected $socket = 'tcp://127.0.0.1:2346';

    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
{

    }

    /**
     * 當(dāng)連接建立時(shí)觸發(fā)的回調(diào)函數(shù)
     * @param $connection
     */
    public function onConnect($connection)
{

    }

    /**
     * 當(dāng)連接斷開時(shí)觸發(fā)的回調(diào)函數(shù)
     * @param $connection
     */
    public function onClose($connection)
{

    }
    /**
     * 當(dāng)客戶端的連接上發(fā)生錯(cuò)誤時(shí)觸發(fā)
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
{
        echo "error $code $msg\n";
    }

    /**
     * 每個(gè)進(jìn)程啟動(dòng)
     * @param $worker
     */
    public function onWorkerStart($worker)
{
        //rabbitMQ配置
        $options = [
            'host'=>'127.0.0.1',//rabbitMQ IP
            'port'=>5672,//rabbitMQ 通訊端口
            'user'=>'admin',//rabbitMQ 賬號(hào)
            'password'=>'123456'//rabbitMQ 密碼
        ];
        (new Client($options))->connect()->then(function (Client $client) {
            return $client->channel();
        })->then(function (Channel $channel) {
            /**
             * 創(chuàng)建隊(duì)列(Queue)
             * name: ceshi         // 隊(duì)列名稱
             * passive: false      // 如果設(shè)置true存在則返回OK,否則就報(bào)錯(cuò)。設(shè)置false存在返回OK,不存在則自動(dòng)創(chuàng)建
             * durable: true       // 是否持久化,設(shè)置false是存放到內(nèi)存中RabbitMQ重啟后會(huì)丟失,
             *                        設(shè)置true則代表是一個(gè)持久的隊(duì)列,服務(wù)重啟之后也會(huì)存在,因?yàn)榉?wù)會(huì)把持久化的Queue存放在硬盤上,當(dāng)服務(wù)重啟的時(shí)候,會(huì)重新加載之前被持久化的Queue
             * exclusive: false    // 是否排他,指定該選項(xiàng)為true則隊(duì)列只對(duì)當(dāng)前連接有效,連接斷開后自動(dòng)刪除
             *  auto_delete: false // 是否自動(dòng)刪除,當(dāng)最后一個(gè)消費(fèi)者斷開連接之后隊(duì)列是否自動(dòng)被刪除
             */
            return $channel->queueDeclare('ceshi', false, true, false, false)->then(function () use ($channel) {
                return $channel;
            });
        })->then(function (Channel $channel) {
            echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";
            $channel->consume(
                function (Message $message, Channel $channel, Client $client) {
                    echo "接收消息內(nèi)容:", $message->content, "\n";
                },
                'ceshi',
                '',
                false,
                true
            );
        });

    }
}

都OK以后咱們可以項(xiàng)目路徑下通過命令啟動(dòng)這個(gè)消費(fèi)者:

php think worker:server

此時(shí)應(yīng)該會(huì)自動(dòng)消費(fèi)掉rabbitMQ中等待的消息!

到這里消費(fèi)者也就結(jié)束啦!

5、整體測(cè)試

接下來我用cmd來啟動(dòng)兩個(gè)服務(wù),然后用接口發(fā)送消息和消費(fèi)測(cè)試!

至于具體怎么靈活應(yīng)用自行開拓大腦哦~

比如php項(xiàng)目有些業(yè)務(wù)吃力,可以去做個(gè)java的消費(fèi)端,讓java來完成任務(wù)~

以上就是PHP實(shí)現(xiàn)RabbitMQ消息列隊(duì)的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于PHP RabbitMQ消息列隊(duì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何修改和添加Apache的默認(rèn)站點(diǎn)目錄

    如何修改和添加Apache的默認(rèn)站點(diǎn)目錄

    本篇文章是對(duì)修改和添加Apache的默認(rèn)站點(diǎn)目錄方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • PHP封裝的字符串加密解密函數(shù)

    PHP封裝的字符串加密解密函數(shù)

    這篇文章主要給大家匯總介紹了PHP封裝的字符串加密解密函數(shù)以及使用方法,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下
    2015-12-12
  • 9段PHP實(shí)用功能的代碼推薦

    9段PHP實(shí)用功能的代碼推薦

    本文是記錄一下小編常用的幾段實(shí)用的代碼,做項(xiàng)目的時(shí)候經(jīng)常會(huì)用到,這里推薦給大家,大家可以隨意擴(kuò)展
    2014-10-10
  • php+redis在實(shí)際項(xiàng)目中HTTP 500: Internal Server Error故障排除

    php+redis在實(shí)際項(xiàng)目中HTTP 500: Internal Server Error故障排除

    用戶量快速增長(zhǎng),訪問量在短時(shí)間內(nèi)翻倍,由于前期容量規(guī)劃做得比較好,硬件資源可以支撐,可是軟件系統(tǒng)方面出現(xiàn)了大問題:40% 的請(qǐng)求都會(huì)返回 HTTP 500: Internal Server Error
    2017-02-02
  • PHP云打印類完整示例

    PHP云打印類完整示例

    這篇文章主要介紹了PHP云打印類,結(jié)合完整實(shí)例形式分析了php實(shí)現(xiàn)網(wǎng)絡(luò)打印數(shù)據(jù)的搜集與隊(duì)列排序整理及數(shù)據(jù)打印等功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2016-10-10
  • PHP中垃圾回收相關(guān)函數(shù)的使用

    PHP中垃圾回收相關(guān)函數(shù)的使用

    這篇文章主要介紹了PHP中垃圾回收相關(guān)函數(shù)的使用,幫助大家更好的理解和學(xué)習(xí)使用PHP,感興趣的朋友可以了解下
    2021-05-05
  • PHP CURLFile函數(shù)模擬實(shí)現(xiàn)文件上傳示例詳解

    PHP CURLFile函數(shù)模擬實(shí)現(xiàn)文件上傳示例詳解

    這篇文章主要介紹了PHP使用CURLFile函數(shù)模擬實(shí)現(xiàn)文件上傳,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • php簡(jiǎn)單實(shí)現(xiàn)多維數(shù)組排序的方法

    php簡(jiǎn)單實(shí)現(xiàn)多維數(shù)組排序的方法

    這篇文章主要介紹了php簡(jiǎn)單實(shí)現(xiàn)多維數(shù)組排序的方法,涉及php數(shù)組的遍歷及array_multisort函數(shù)的相關(guān)使用技巧,需要的朋友可以參考下
    2016-09-09
  • windows下配置apache+php+mysql時(shí)出現(xiàn)問題的處理方法

    windows下配置apache+php+mysql時(shí)出現(xiàn)問題的處理方法

    windows下配置apache+php+mysql應(yīng)該是每個(gè)phper必須掌握的基礎(chǔ)技能了,這也是熟悉php的一個(gè)過程,小編當(dāng)年自己配環(huán)境的時(shí)候也遇到過這樣那樣的問題,現(xiàn)在把當(dāng)時(shí)記錄的幾個(gè)問題的處理方法分享給大家
    2014-06-06
  • PHP判斷遠(yuǎn)程圖片是否存在的幾種方法

    PHP判斷遠(yuǎn)程圖片是否存在的幾種方法

    這篇文章主要介紹了PHP判斷遠(yuǎn)程圖片是否存在的幾種方法,需要的朋友可以參考下
    2014-05-05

最新評(píng)論

阳东县| 崇州市| 黎川县| 南投市| 新龙县| 民权县| 呼伦贝尔市| 瑞丽市| 宽甸| 西宁市| 哈巴河县| 海盐县| 淄博市| 射阳县| 景洪市| 阳春市| 清涧县| 寻乌县| 偏关县| 华坪县| 高安市| 噶尔县| 遂平县| 陵川县| 波密县| 顺昌县| 社旗县| 汉源县| 施甸县| 灵台县| 上虞市| 东乌珠穆沁旗| 同江市| 平江县| 阿荣旗| 凤城市| 瑞安市| 商河县| 通辽市| 瓮安县| 嘉荫县|