溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

PHP中實現(xiàn)消息隊列的要素有哪些

發(fā)布時間:2021-06-22 16:29:05 來源:億速云 閱讀:142 作者:Leah 欄目:編程語言

PHP中實現(xiàn)消息隊列的要素有哪些,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

1、為什么使用消息隊列

消息隊列技術(shù)是分布式應(yīng)用間交換信息的一種技術(shù)。消息隊列可駐留在內(nèi)存或磁盤上,隊列存儲消息直到它們被應(yīng)用程序讀出。通過消息隊列,應(yīng)用程序可獨立地執(zhí)行,它們不需要知道彼此的位置、或在繼續(xù)執(zhí)行前不需要等待接收程序接收此消息。

2. 什么場合使用消息隊列

你首先需要弄清楚,消息隊列與遠程過程調(diào)用的區(qū)別,在很多讀者咨詢我的時候,我發(fā)現(xiàn)他們需要的是RPC(遠程過程調(diào)用),而不是消息隊列。

消息隊列有同步或異步實現(xiàn)方式,通常我們采用異步方式使用消息隊列,遠程過程調(diào)用多采用同步方式。

MQ與RPC有什么不同? MQ通常傳遞無規(guī)則協(xié)議,這個協(xié)議由用戶定義并且實現(xiàn)存儲轉(zhuǎn)發(fā);而RPC通常是專用協(xié)議,調(diào)用過程返回結(jié)果。

3. 什么時候使用消息隊列

同步需求,遠程過程調(diào)用(PRC)更適合你。

異步需求,消息隊列更適合你。

目前很多消息隊列軟件同時支持RPC功能,很多RPC系統(tǒng)也能異步調(diào)用。

消息隊列用來實現(xiàn)下列需求

  1. 存儲轉(zhuǎn)發(fā)

  2. 分布式事務(wù)

  3. 發(fā)布訂閱

  4. 基于內(nèi)容的路由

  5. 點對點連接

以下是一個消息隊列的運用實例

<?php

/**
 * Created by PhpStorm.
 * User: lin
 * Date: 2017/6/9
 * Time: 11:19
 * 實現(xiàn)php共享內(nèi)存消息隊列
 */
class ShmQueue
{
    private $maxQSize = 0;//隊列最大長度
    private $front = 0;//隊頭指針
    private $rear = 0; //隊尾指針
    private $blockSize = 256;  // 塊的大小(byte)
    private $memSize = 1280;  // 最大共享內(nèi)存(byte)
    private $shmId = 0;//根據(jù)這個id可以操作該共享內(nèi)存片段
    private $filePtr = APP_PATH.'public/shmq.ptr';
    private $semId = 0;
    public function __construct()
    {
        $shmkey = ftok(__FILE__, 't');//產(chǎn)生系統(tǒng)id
        $this->shmId = shmop_open($shmkey, "c", 0644, $this->memSize );//創(chuàng)建一個內(nèi)存段
        $this->maxQSize = $this->memSize / $this->blockSize;
        // 申請一個信號量
        $this->semId = sem_get($shmkey, 1);
        sem_acquire($this->semId); // 申請進入臨界
        $this->init();
    }
    private function init()
    {
        if ( file_exists($this->filePtr) ){
            $contents = file_get_contents($this->filePtr);
            $data = explode( '|', $contents );
            if ( isset($data[0]) && isset($data[1])){
                $this->front = (int)$data[0];
                $this->rear  = (int)$data[1];
            }
        }
    }
    public function getLength()
    {
        return (($this->rear - $this->front + $this->memSize) % ($this->memSize) )/$this->blockSize;
    }
    public function enQueue( $value )
    {
        if ( $this->ptrInc($this->rear) == $this->front ){ // 隊滿
            return false;
        }
        //echo $this->front;
        $data = $this->encode($value);
        shmop_write($this->shmId, $data, $this->rear );
        $this->rear = $this->ptrInc($this->rear);
        return  $this->decode($data);
    }
    public function deQueue()
    {
        if ( $this->front == $this->rear ){ // 隊空
            throw new Exception(" block size is null!");
        }
        $value = shmop_read($this->shmId, $this->front, $this->blockSize-1);
        $this->front = $this->ptrInc($this->front);
        return $this->decode($value);
    }
    private function ptrInc( $ptr )
    {
        return ($ptr + $this->blockSize) % ($this->memSize);
    }
    private function encode( $value )
    {
        $data = serialize($value) . "__eof";
        //echo '';
        //echo strlen($data);
        //echo '';
       // echo $this->blockSize -1;
       // echo '';

        if ( strlen($data) > $this->blockSize -1 ){
            throw new Exception(strlen($data)." is overload block size!");
        }
        return $data;
    }
    public function exist($value){//判斷隊頭的數(shù)據(jù)

        $data = shmop_read($this->shmId, $this->front, $this->blockSize-1);
        if($value == $this->decode($data)){
            return 1;
        }
        return 0;
    }
    private function decode( $value )
    {
        //return $value;
        $data = explode("__eof", $value);
        return unserialize($data[0]);
    }
    public function __destruct()
    {
        //保存隊頭和隊尾指針
        $data = $this->front . '|' . $this->rear;
        file_put_contents($this->filePtr, $data);
        sem_release($this->semId); // 出臨界區(qū), 釋放信號量
    }

}

如何調(diào)用

$shmq = new ShmQueue();
入隊:
$data = 125;
$shmq->enQueue($data);

出隊:
$shmq->deQueue();

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI