swoole支持下的長鏈接和異步任務(wù)實(shí)現(xiàn)

2018-11-21 21:31 更新

遵守規(guī)則可以讓你遠(yuǎn)離選擇煩惱,無論是在坐車還是參加雞尾酒會的時候。 --《選擇的悖論》

寫在前面的話

此PhalApi擴(kuò)展類庫只是初步開發(fā)完成,建議有swoole擴(kuò)展經(jīng)驗(yàn)或非保守派的同學(xué)使用,也歡迎你來豐富完善此擴(kuò)展類庫。

3.9.1 擴(kuò)展類庫:swoole支持下的長鏈接和異步任務(wù)實(shí)現(xiàn)

swoole官網(wǎng)請見: Swoole: PHP的異步、并行、分布式擴(kuò)展

在這里,首先需要非常感謝swoole。

因?yàn)镾woole給我們提供了很多解決以往因PHP本身限制而產(chǎn)生的難題的靈感,但與此同時,也給我們帶來了從沒遇到過的挑戰(zhàn),特別是并發(fā)和長時間運(yùn)行。

這需要我們更為小心地進(jìn)行編碼,因?yàn)橐酝梢院雎缘男栴},在新的解決方案背景下都可能成為一個大問題。此擴(kuò)展類庫更多是作為一種嘗試,并且可以作為擴(kuò)展類庫重要的一個轉(zhuǎn)換點(diǎn)。因?yàn)樵诮窈蟮娜兆永铮?span> PhalApi將會爭取與其他開源項目一起,提供企業(yè)級的解決方案 。

目前,此擴(kuò)展類庫提供了:

  • 長鏈接的接口調(diào)用
  • 異步計劃任務(wù)的調(diào)用

3.9.2 安裝

(1)安裝swoole擴(kuò)展類庫 安裝過程可以參考swoole官網(wǎng),這里稍以linux系統(tǒng)簡單說明一下編譯安裝。

unzip ./swoole-src-swoole-1.7.16-beta.zip
cd swoole-src-swoole-1.7.16-beta
phpize
./configure
make && make install

安裝好后,添加swoole擴(kuò)展:

extension=swoole.so

重啟PHP后,如果看到有swoole擴(kuò)展,則說明安裝成功:

#php -m | grep swoole
swoole

(2)擴(kuò)展包下載

從 PhalApi-Library 擴(kuò)展庫中下載獲取 Swoole 包,如使用:

git clone https://git.oschina.net/dogstar/PhalApi-Library.git

然后把 Swoole 目錄復(fù)制到 ./PhalApi/Library/ 下,即:

cp ./PhalApi-Library/Swoole/ ./PhalApi/Library/ -R

到此安裝完畢!

溫馨提示:
此擴(kuò)展類庫需要PhaApi 1.1.4及以上版本。

(3)配置

將以下配置追加到./Config/app.php:

    /**
     * Swoole擴(kuò)展類庫
     */
    'Swoole' => array(
        //服務(wù)
        'server' => array(
            'ip' => '127.0.0.1',
            'port' => 9501,
            'worker_num' => 1,
        ),
        //計劃任務(wù)
        'task' => array(
            'ip' => '127.0.0.1',
            'port' => 9502,
            'worker_num' => 1,
        ),
    ),

3.9.3 入門使用

(1)長鏈接入口

在使用長鏈接入口對外提供接口服務(wù)后,由于不再是HTTP協(xié)議,所以入口建議放置在新的目錄./Server,而不再是./Public。
入口文件的編寫,如同我們以往一樣,很簡單:

//$ vim ./Server/run_server.php
<?php

require_once dirname(__FILE__) . '/../Public/init.php';

DI()->loader->addDirs(array('Library', 'Demo'));

$swooleLite = new Swoole_Lite();
$swooleLite->runServer();

啟動、重啟和關(guān)閉服務(wù)

啟動可以用:

php ./Server/run_server.php

關(guān)閉可以用:

ps -ef | grep run_server | grep -v grep | awk '{print $2}'|xargs kill -9

(2)異步計劃任務(wù)

異步計劃任務(wù)是新型的做法,即:也通過接口服務(wù)調(diào)用的方式來完成計劃任務(wù)的調(diào)度,其啟動文件如同長鏈接入口一樣簡單:

//$ vim ./Server/run_task.php
<?php

require_once dirname(__FILE__) . '/../Public/init.php';

DI()->loader->addDirs(array('Library', 'Demo'));

$swooleLite = new Swoole_Lite();
$swooleLite->runTask();

啟動、重啟和關(guān)閉服務(wù)

啟動可以用:

nohup php ./Server/run_task.php > ./Server/run_task.log 2>&1 &

(3)客戶端調(diào)用

在擴(kuò)展類庫里有一個測試的腳本,可以用來進(jìn)行PHP客戶端的請求。

(1)默認(rèn)接口調(diào)用

$ php ./check.php 127.0.0.1 9501 Default.Index username=swoole
Send: {"service":"Default.Index","username":"swoole"}
Received: {"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430620911},"msg":""}
Connection close

(2)帶數(shù)據(jù)庫的調(diào)用

$ php ./check.php 127.0.0.1 9501 User.getBaseInfo userId=1
Send: {"service":"User.getBaseInfo","userId":"1"}
Received: {"ret":200,"data":{"code":0,"msg":"","info":{"id":"1","username":"aevit","nickname":"test","password":"DE4CA99150F44B26F0D320DCA6E4B7629C43B6","salt":"wefewfew","reg_time":"0","avatar":"http:\/\/image.famillelab.com\/no_avatar.png","UUID":""}},"msg":""}
Connection close

(3)異步計劃任務(wù)的調(diào)度

$ php ./check.php 127.0.0.1 9502 Default.Index username=swoole
Send: {"service":"Default.Index","username":"swoole"}
Connection close

假設(shè)Default.Index為一個計劃任務(wù)的接口,但目前發(fā)現(xiàn)一個問題是,首次請求異步計劃任務(wù)不會主動結(jié)束,而需要工作強(qiáng)制ctrl + c結(jié)束,再請求,則正常。

對應(yīng)的log,可以看到:

2015-05-03 12:24:57|DEBUG|asynctask(0) dispath in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(0) start in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(0) finish in swoole|{"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430627097},"msg":""}
2015-05-03 12:24:57|DEBUG|asynctask(1) dispath in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(1) start in swoole|{"service":"Default.Index","username":"swoole"}
2015-05-03 12:24:57|DEBUG|asynctask(1) finish in swoole|{"ret":200,"data":{"title":"Hello World!","content":"Hi swoole, welcome to use PhalApi!","version":"1.1.3","time":1430627097},"msg":""}
...

3.9.4 對客戶端調(diào)整

(1)調(diào)用方式的改變

改用長鏈接。

(2)POST參數(shù)傳遞方式的改變

統(tǒng)一使用json發(fā)送數(shù)據(jù)包。

3.9.5 對服務(wù)端的影響

(1)DI資源服務(wù)的調(diào)整

變量名稱是否全局通用是否每次請求新建可否使用備注
loader可使用
config可使用
logger可使用
notorm可使用每次響應(yīng)后,關(guān)閉此次全部數(shù)據(jù)庫鏈接
cache可使用需要查看使用的鏈接是否支持長鏈接
filter可使用
crypt可使用
curl可使用
request可使用
response可使用
cookie------不可使用長鏈接下不應(yīng)進(jìn)行COOKIE的操作

(2)關(guān)于swoole擴(kuò)展類庫的自問自答

  • 1、數(shù)據(jù)庫使用長鏈接嗎? -- 不使用,每次響應(yīng)后手動關(guān)閉數(shù)據(jù)鏈接
  • 2、內(nèi)存問題?-- 通過類成員方法的作用域控制內(nèi)存
  • 3、并發(fā)的問題?-- TODO
  • 4、代碼更新后如何同步?需要重啟服務(wù)器嗎? -- 需要重啟
  • 5、PhalApi_Response::formatResult()的訪問權(quán)限,是框架的調(diào)整,還是個別自我提高? -- 擴(kuò)展自我提高
  • 6、注冊錯誤回調(diào)函數(shù)? -- 來自swoole的建議,已注冊
  • 7、啟動和關(guān)閉、重啟腳本文件? -- 提供參考命令
  • 8、一直運(yùn)行? -- TODO

    (3)特別注意!

    由于服務(wù)在啟動后,已經(jīng)完成了大部分的類加載、配置讀取以及PHP文件的解析,所以在對項目代碼(包括配置)修改后,需要重啟服務(wù),方能生效。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號