'swoole遊戲服務端開發經驗談'

"

swoole作為php的高性能第三方擴展,最近幾年異軍突起,為幾近衰落的php注入了活力。而php作為敏捷開發的利器,有大批的忠粉和黑粉,原因就是實現高效開發的同時不能達到類似node、golang、java同等的性能。而swoole的出現,以及php7尤其是7.3的版本更新大幅提升了php的性能,使php能夠運用到更多場景中。筆者作為一名手遊服務端從業者,將在本文中分享下自己在手遊開發中使用swoole的心得。才疏學淺,文中如有偏頗請及時指正,以免影響到更多小白讀者。

筆者最近一個項目是基於H5的,選擇php的原因很簡單,節約時間成本,這目前也是很多遊戲成敗的關鍵,一個小項目十幾個人開發一年就是兩三百萬!swoole在項目中的使用僅限於swooleHttp和swooleWebsocket兩種模式,因為Tcp和Udp毫無用武之地。當然,如果您想使用TCP或UDP也是可以的,就是:瀏覽器->網關(協議轉發)->swooleTCP/swooleUDP的RPC服務端,這種模式也是可以的。

swooleHttp生產環境怎麼使用呢?

1. swoole本身提供http而非https服務

swoole作者也承認swooleHttp是不完善的,並建議在外層增加nginx做反向代理,那麼https隧道加密的工作完全可以讓nginx一個人扛,然後nginx再通過http方式反向代理給swooleHttp。這樣的好處是:開發模式可以完全不使用https,方便調試、抓包,且遷到線上時不需要對配置ssl證書、url地址等配置項做任何更改。

2. 使用swoole_base模式

process模式時reactor和worker由不同進程負責,因此服務端收發數據時都需要在reactor和worker間做一次交互。而BASE模式下,worker進程直接接管客戶端連接做數據收發,即worker同時做了reactor的工作,省去一次(或者說兩次)IPC交互的消耗。作為短連接的http完全沒必要使用process模式。

3. keepalive保持連接

TCP短連接每次通信要經過三次握手四次斷開,加上每次發送、確認,回覆、確認,一共是11次數據傳輸,性能開銷可想而知。保持連接不斷開的情況下,一次跟服務器交互只需要4次通信。

nginx代理時的keepalive配置如下(手寫的,方便copy)

nginx.conf

http{

......

upstream main_server {

server 127.0.0.1:8991;

keepalive 128;

}

server{

......

# swoolehttp反向代理

location / {

proxy_http_version 1.1;

proxy_set_header Connection "";

proxy_set_header X-Real-IP $remote_addr;

proxy_pass http://main_server;

}

#swooleWebsocket反向代理

location /ws {

proxy_http_version 1.1;

proxy_set_header X-Real-IP $remote_addr;

proxy_pass http://127.0.0.1:8091;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

}

}

4.慢請求日誌

慢日誌有助於查詢性能瓶頸,如果您沒有用協程,則可以在開發環境使用xhprof調試性能,比慢日誌更行之有效。

swoole本身已經提供了慢請求日誌的功能,但是很弱,日誌內容不能自定義所以有時候並不知道是哪個接口造成的。如果您是基於swoole自建框架,建議手寫蒐集慢日誌的功能。筆者的日誌格式是這樣的,看起來一目瞭然(時間|接口|ip|耗時):

"

swoole作為php的高性能第三方擴展,最近幾年異軍突起,為幾近衰落的php注入了活力。而php作為敏捷開發的利器,有大批的忠粉和黑粉,原因就是實現高效開發的同時不能達到類似node、golang、java同等的性能。而swoole的出現,以及php7尤其是7.3的版本更新大幅提升了php的性能,使php能夠運用到更多場景中。筆者作為一名手遊服務端從業者,將在本文中分享下自己在手遊開發中使用swoole的心得。才疏學淺,文中如有偏頗請及時指正,以免影響到更多小白讀者。

筆者最近一個項目是基於H5的,選擇php的原因很簡單,節約時間成本,這目前也是很多遊戲成敗的關鍵,一個小項目十幾個人開發一年就是兩三百萬!swoole在項目中的使用僅限於swooleHttp和swooleWebsocket兩種模式,因為Tcp和Udp毫無用武之地。當然,如果您想使用TCP或UDP也是可以的,就是:瀏覽器->網關(協議轉發)->swooleTCP/swooleUDP的RPC服務端,這種模式也是可以的。

swooleHttp生產環境怎麼使用呢?

1. swoole本身提供http而非https服務

swoole作者也承認swooleHttp是不完善的,並建議在外層增加nginx做反向代理,那麼https隧道加密的工作完全可以讓nginx一個人扛,然後nginx再通過http方式反向代理給swooleHttp。這樣的好處是:開發模式可以完全不使用https,方便調試、抓包,且遷到線上時不需要對配置ssl證書、url地址等配置項做任何更改。

2. 使用swoole_base模式

process模式時reactor和worker由不同進程負責,因此服務端收發數據時都需要在reactor和worker間做一次交互。而BASE模式下,worker進程直接接管客戶端連接做數據收發,即worker同時做了reactor的工作,省去一次(或者說兩次)IPC交互的消耗。作為短連接的http完全沒必要使用process模式。

3. keepalive保持連接

TCP短連接每次通信要經過三次握手四次斷開,加上每次發送、確認,回覆、確認,一共是11次數據傳輸,性能開銷可想而知。保持連接不斷開的情況下,一次跟服務器交互只需要4次通信。

nginx代理時的keepalive配置如下(手寫的,方便copy)

nginx.conf

http{

......

upstream main_server {

server 127.0.0.1:8991;

keepalive 128;

}

server{

......

# swoolehttp反向代理

location / {

proxy_http_version 1.1;

proxy_set_header Connection "";

proxy_set_header X-Real-IP $remote_addr;

proxy_pass http://main_server;

}

#swooleWebsocket反向代理

location /ws {

proxy_http_version 1.1;

proxy_set_header X-Real-IP $remote_addr;

proxy_pass http://127.0.0.1:8091;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

}

}

4.慢請求日誌

慢日誌有助於查詢性能瓶頸,如果您沒有用協程,則可以在開發環境使用xhprof調試性能,比慢日誌更行之有效。

swoole本身已經提供了慢請求日誌的功能,但是很弱,日誌內容不能自定義所以有時候並不知道是哪個接口造成的。如果您是基於swoole自建框架,建議手寫蒐集慢日誌的功能。筆者的日誌格式是這樣的,看起來一目瞭然(時間|接口|ip|耗時):

swoole遊戲服務端開發經驗談

5.關於數據庫連接池

如使用了協程,那麼連接池是必須要建的,否則同進程內的協程都會卡在操作數據庫。如果使用的是swoole1.x,進程只能每個請求全部處理完畢才能處理下一個請求,所以只需要有一個數據庫長連接而不需要建立連接池,或者說連接池裡只有一個連接就夠了。

6.是否使用負載均衡和分佈式

如果你的服務器架構為傳統的多組服,比如1-5區在同一組服務器(game服+緩存服+數據庫+其他)上,6-10區在第二組服務器上,開第11區時發現第二組服務器還沒什麼負載,那麼11區可以繼續開在第二組服務器上。這種情況就沒必要使用分佈式,也基本用不到負載均衡,程序中可以使用文件鎖做為邏輯鎖(這比redis等緩存鎖安全但性能略低)。該模式最大的缺點是不方便和服。

如果您的服務器只有一組(和服很easy),那麼game服就需要分佈式或者負載均衡,具體看業務怎麼切割,水平切割就是負責均衡,垂直切割就是分佈式集群。另外負載均衡的流量大推薦使用服務器提供商的SLB服務(不同運營商叫法不一樣),流量小的話nginx完全可以勝任了。

同樣數據庫部分也可以讀寫分離或者主主複製或者根據業務垂直切割,這個就根據自己的情況自由定製了。

7.定時作業

遊戲一般都有定時處理作業的需求,比如定時發獎,定時分配比賽等。這樣一個定時任務處理的server是必須要有的了,最好不要混在game服中。如果可以做成linux的crontab的配置形式是最好的,用起來很舒服。但是定時作業這塊筆者還不知道怎麼使用swoole來做,目前是脫離swoole基於php-cli模式做的,不過也沒太大問題。不知道您有什麼高見?

"

相關推薦

推薦中...