swoole 異步隊列簡明教程

安裝步驟以下(推薦把安裝文件下載到 /usr/local/src 目錄下):
step 1: wget --no-check-certificate https://github.com/swoole/swoole-src/archive/v1.9.13.tar.gz
step 2: tar zxf v1.9.13.tar.gz
step 3: cd swoole-src-1.9.13
step 4: phpize 
step 5: ./configure --with-php-config=/usr/local/php/bin/php-config
step 6: make && make install
step 7: 修改 php.ini ,加入 extension=swoole.so ,而後重啓 php-fpm
step 8: 執行 php --info | grep swoole 查看設置是否生效

############################  消費者,文件名《server.php》  ############################
<?php
class Server {
    private $serv;
    private $logFile;
    
    public function __construct() {
        $this->serv = new swoole_server('0.0.0.0', 9501);   // 容許全部IP訪問
        $this->serv->set([
            'worker_num' => 4,   // 通常設置爲服務器CPU數的1-4倍
            'task_worker_num' => 1,  // task進程的數量(通常任務都是同步阻塞的,能夠設置爲單進程單線程)
            'daemonize' => true,  // 以守護進程執行
            'package_eof' => PHP_EOL,  // 設置EOF
            'open_eof_split' => true,  // 按照EOF進行分包,防止TCP粘包
        //  'task_ipc_mode' => 1,  // 使用unix socket通訊,默認模式
        //  'log_file' => '/data/log/queue.log' ,    // swoole日誌
        
        // 數據包分發策略(dispatch_mode=1/3時,底層會屏蔽onConnect/onClose事件,
        // 緣由是這2種模式下沒法保證onConnect/onClose/onReceive的順序,非請求響應式的服務器程序,請不要使用模式1或3)
        //  'dispatch_mode' => 2,        // 固定模式,根據鏈接的文件描述符分配worker。這樣能夠保證同一個鏈接發來的數據只會被同一個worker處理
        ]);

        $this->logFile = dirname(__FILE__).'/log.txt';        // 以守護進程執行的時候,要絕對路徑
        $this->serv->on('Receive', [$this, 'onReceive']);
        $this->serv->on('Task', [$this, 'onTask']);
        $this->serv->on('Finish', [$this, 'onFinish']);
        $this->serv->start();
    }
    
    /**
    * 接收到數據時回調此函數,發生在worker進程中
    * $server,swoole_server對象
    * $fd,TCP客戶端鏈接的文件描述符
    * $from_id,TCP鏈接所在的Reactor線程ID
    * $data,收到的數據內容,多是文本或者二進制內容
    */
    public function onReceive($serv, $fd, $from_id, $data ) {
        $str  = "=========== onReceive ============ \n";
        $str .= "Get Message From Client $fd:$data \n";
        error_log($str, 3, $this->logFile);
        $serv->task( $data );
    }
    
    /**
    * 在task_worker進程內被調用。worker進程可使用swoole_server_task函數向task_worker進程投遞新的任務。當前的Task進程在調用onTask回調函數時會將進程狀態切換爲忙碌,
    * 這時將再也不接收新的Task,當onTask函數返回時會將進程狀態切換爲空閒而後繼續接收新的Task。
    * $task_id是任務ID,由swoole擴展內自動生成,用於區分不一樣的任務。$task_id和$src_worker_id組合起來纔是全局惟一的,不一樣的worker進程投遞的任務ID可能會有相同
    * $src_worker_id來自於哪一個worker進程
    * $data 是任務的內容
    */
    public function onTask($serv, $task_id, $src_worker_id, $data) {
        $data   = trim($data);  // 刪除EOF
        $array  = json_decode( $data , true );
        $str    = "=========== onTask ============ \n";
        $str   .= var_export($array, 1);
        error_log($str, 3 , $this->logFile);
        return $array;
    }
    
    /**
    * 當worker進程投遞的任務在task_worker中完成時,task進程會經過swoole_server->finish()方法將任務處理的結果發送給worker進程
    * $task_id是任務的ID
    * $data是任務處理的結果內容(也就是onTask()函數,中return的值)
    */
    public function onFinish($serv, $task_id, $data) {
        $str  = "=========== onFinish ============ \n";
        $str .= "Task $task_id finish ! \n";
        $str .= var_export($data, 1);
        error_log($str, 3, $this->logFile);
    }

}
$server = new Server();


############################  生產者,文件名《client.php》  ############################
<?php
class Client {
    
    private function _sendData($data) {
        $client = new \swoole_client(SWOOLE_SOCK_TCP);
        $client->connect('127.0.0.1', 9501, 1);
        $client->send($data.PHP_EOL);    // 加入PHP_EOL做爲結束分隔符(EOF)
    }
    
    
    public function run() {
        for($i=0; $i<10; $i++) {
            $data = [  'time'   => rand(1000, 9999),
                      'id'     => $i ];
            $jsonData = json_encode($data);
            // 每次循環都要開啓新的鏈接,不然隊列會出問題
            $this->_sendData($jsonData);
        }
    }
    
}


############################  華麗的分割線  ############################

先執行 php server.php (執行一次,會以守護進程運行)
而後再執行 php client.php

# 內核參數調整(關鍵步驟)
http://wiki.swoole.com/wiki/page/p-server/sysctl.html

# swoole 離線手冊,裏面有更多的示例
https://github.com/smalleyes/swoole-chm
相關文章
相關標籤/搜索