王盛林
(上海竹靈網(wǎng)絡科技有限公司 上海200120)
基于PHP的socket游戲服務器設計與實現(xiàn)
王盛林
(上海竹靈網(wǎng)絡科技有限公司 上海200120)
近年來網(wǎng)頁游戲、手機游戲快速發(fā)展,對游戲服務端提出新的要求:架構(gòu)簡單、配置靈活,同時可支持快速開發(fā)。文中提出一種架構(gòu):服務器底層通訊基于高性能的socket庫開發(fā),而游戲邏輯采用成熟的PHP框架開發(fā),游戲邏輯不關(guān)心底層細節(jié)達到快速高效的目的。文中主要分三層介紹:基礎層主要采用libevent和ZeroMQ的API;核心服務層提供網(wǎng)絡通訊和數(shù)據(jù)存儲服務;應用層處理游戲內(nèi)的邏輯。此外,以該架構(gòu)的游戲服務器已在兩款網(wǎng)頁游戲開服上百組,性能測試穩(wěn)定。
游戲服務器;套接字;libevent;ZeroMQ;PHP
在游戲產(chǎn)業(yè)快速發(fā)展的今天,越來越多的公司因為一款游戲就從互聯(lián)網(wǎng)公司當中脫穎而出,相比于傳統(tǒng)的MMORPG客戶端游戲,網(wǎng)頁游戲與手機游戲由于其便捷性更容易實際盈利目標。因單服規(guī)模相對較小,游戲服務端無須復雜的服務器架構(gòu),需要能快速開服,如何能保持在多人同時游戲時的流暢性以及系統(tǒng)的穩(wěn)定性是對游戲開發(fā)人員的一大考驗。由于這類游戲要求開發(fā)周期短、開服速度快,因此需要綜合考慮成本與機動性,同時又要求保證性能。文中就當前比較熱門的網(wǎng)頁游戲和手機游戲,提出了一款基于PHP的Socket的游戲服務器,在底層引進 libevent庫提高負載能力和ZeroMQ庫來進行服務器的通訊,游戲邏輯層采用PHP開發(fā),最終達到快速與高效的目的。
1.1 基礎層分析
游戲服務器采用PHP作為腳本開發(fā)語言,因其跨平臺、易布署、維護方便等特性,得到廣泛應用。通過Socket網(wǎng)絡編程中成熟的技術(shù)方案來處理游戲中高連接數(shù)、高吞吐量的事件[1]。同時PHP支持C編寫擴展,可以做到與游戲服務器數(shù)據(jù)通訊一致。在底層采用類庫有:
1)Libevent庫,使用事件驅(qū)動方式極大的降低資源占用,增大服務接待能力,并提高網(wǎng)絡傳輸效率。
2)ZeroMQ號稱“史上最快的消息隊列”,他提供的API讓復雜的消息處理更加簡潔同時性能更高。
1.2 底層庫libevent
libevent是一個開源的事件觸發(fā)的網(wǎng)絡庫,適用于windows、linux、bsd等多種平臺,按不同平臺采用select、epoll、kqueue等系統(tǒng)調(diào)用管理事件機制。對于每個網(wǎng)絡請求,libevent相當于在各個平臺的網(wǎng)絡后端增加一個包裝器,讓事件管理在得以最高效最高性能,同時事件系統(tǒng)優(yōu)化讓處理函數(shù)非常方便,有效降低底層I/O復雜性。其主要功能有:
1)采用事件驅(qū)動機制,異步調(diào)用性能高。
2)專注于網(wǎng)絡處理,方便編寫。
3)跨平臺支持,嘗試使用每個平臺上最高速的非阻塞IO實現(xiàn),并且不引入太多的額外開銷。
4)支持I/O(socket)、定時器和信號事件。
5)支持多種I/O多路復用技術(shù),有效提高網(wǎng)絡傳輸效率。
6)其他組件提供緩沖的事件系統(tǒng),以及HTTP、DNS和RPC系統(tǒng)核心實現(xiàn)。
libevent在網(wǎng)絡編程得到充分驗證,采用基于libevent為底層的成熟服務器端:Memcache(分布式緩存)[2],PLB(負載均衡器),而對PHP支持很好的有Swoole[3]、ReactPHP[4]等。
1.3 底層庫ZeroMQ
ZeroMQ[5]是消息隊列管理庫,其提供底層的網(wǎng)絡通訊庫,對Socket API做了一層封裝,將網(wǎng)絡通訊、進程通訊和線程通訊作為統(tǒng)一的API接口,其主要優(yōu)點有:
1)支持高并發(fā)、異步調(diào)用,速度快。
2)支持多個消息傳送模式:如P2P、訂閱發(fā)布模式、以及請求響應模式。
3)支持多個平臺:如Linux/Windows/OSX等。
4)協(xié)議比 TCP更快、適用于大型集群和分布式計算
5)開源社區(qū)支持,支持多種開發(fā)語言。
圖1 游戲服務器端結(jié)構(gòu)示意圖
傳統(tǒng)客戶端服務器在線人數(shù)多,游戲邏輯復雜,所以已發(fā)展出成熟的解決方案:如魔獸世界(WOW)采用的BigWorld[6]方案,功能強大,動態(tài)負載均衡和容錯性做了很多工作,但同時硬件要求比較高,價格昂貴。它的服務器端架構(gòu)分為Gate(網(wǎng)關(guān)服務器,負責客戶端連接及消息轉(zhuǎn)發(fā))、GameServer(提供游戲邏輯功能的服務器程序)、DBManager(負責將游戲數(shù)據(jù)寫入到數(shù)據(jù)庫)、GameManager(處理所有GameServer中消息處理)。
文中主要借鑒這種架構(gòu)思路:按數(shù)據(jù)通訊服務、數(shù)據(jù)存儲服務、定時器服務、消息服務劃分,可實現(xiàn)一臺獨立物理服務器提供所有核心服務,或者一個服務提供給多臺服務器,同時還支持分布式服務,按照實際開服情況靈活處理,實現(xiàn)快速機動、節(jié)約成本。
2.1 數(shù)據(jù)通訊服務
2.1.1 功能說明
數(shù)據(jù)通訊服務類似Gateway網(wǎng)關(guān)服務器,負責網(wǎng)絡數(shù)據(jù)的接收與發(fā)送,將客戶端發(fā)送的數(shù)據(jù)解碼后發(fā)送游戲邏輯層處理,對游戲邏輯發(fā)過來的數(shù)據(jù)編碼后發(fā)送給客戶端。由于在線玩家通過TCP直接連到服務器,所以承載很大的壓力,數(shù)據(jù)通訊服務具有如下特點:
1)響應時間及時:與游戲客戶端一樣,響應越快游戲越流暢,延時過長會大大降低游戲體檢。
2)服務可擴展:根據(jù)游戲人數(shù)確定增加負載能力,如增加Worker進程,多開通訊進程等。
3)服務穩(wěn)定性:游戲是7*24不間斷服務,所以需要提供由于在線人數(shù)多或者少各種情況下的應用平穩(wěn)以及各種異常的修復及處理功能。
2.1.2 方案說明
游戲服務是網(wǎng)絡IO密集型服務,采用方案是:
1)采用libevent庫作為網(wǎng)絡通訊接口:由于libevent采用事件驅(qū)動模式,非阻塞網(wǎng)絡IO,采用EPOLL事件輪循機制,盡管采用多進程,但由于游戲邏輯執(zhí)行優(yōu)化后,并行處理數(shù)據(jù)輸入輸出還是很高效的。通訊服務以常駐進程方式啟動,worker進程收到客戶端發(fā)來的請求,以C加載CLI的方式執(zhí)行PHP業(yè)務邏輯,處理結(jié)果PHP通知給worker,中間用C編寫的PHP擴展保持數(shù)據(jù)結(jié)構(gòu)一致。
2)服務端采用Master-Workers結(jié)構(gòu) (管理者-工作者):這種結(jié)構(gòu)能夠動態(tài)管理游戲服務進程,從而提高處理效率。如:Nginx[6]、PHP-FPM[7]都采用這種方式。主要特點有:
①多進程由操作系統(tǒng)來調(diào)度,管理方便,運行起來比較強壯穩(wěn)定。
②隔離性好,可由Master來管理worker進程,實現(xiàn)平滑的加載游戲配置以達熱更新。
③充分利用多核cpu來進行并行運算,利用率高。具體工作示意圖如圖2。
圖2 通訊服務結(jié)構(gòu)示意圖
2.2 定時器服務
定時器服務是以加載配置的方式,執(zhí)行應用層的業(yè)務邏輯??芍苯邮褂闷鋪韯?chuàng)建定時啟動、關(guān)閉應用。設定時間到來時,會自動執(zhí)行配置中指定應用層游戲邏輯。一般用在游戲活動開啟、關(guān)閉,定時恢復游戲?qū)傩缘取?/p>
其中游戲中一些需要異步去處理的應用,以常駐進程方式加載,也用定時器來實現(xiàn)。如一些比較占用網(wǎng)絡IO資源、業(yè)務邏輯復雜的服務:合作商之間的充值驗證服務、游戲戰(zhàn)斗結(jié)算服務等,以隊列形式處理請求,有效平衡服務器負載。
2.3 數(shù)據(jù)存儲服務
游戲中玩家數(shù)據(jù)分成兩種方式存儲:一種存儲在物理介質(zhì)上的DataBase(如一般的關(guān)系型數(shù)據(jù)庫,MySQL/SQLServer等)中,另一種存儲在內(nèi)存為介質(zhì)的NoSQL中 (如Redis、Mongo等)。考慮到游戲的高性能需要,對于實時操作的數(shù)據(jù)放在以內(nèi)存為介質(zhì)的NoSQL中,而那些需要提供給數(shù)據(jù)分析的數(shù)據(jù)會寫入數(shù)據(jù)庫中。
2.3.1 關(guān)系型數(shù)據(jù)庫DataBase
關(guān)系型數(shù)據(jù)庫是創(chuàng)建在關(guān)系模型(relational database)基礎上的數(shù)據(jù)庫,借助于集合代數(shù)等概念和方法來處理數(shù)據(jù)庫中的數(shù)據(jù)。由于游戲中操作頻繁,磁盤IO成了性能瓶頸,主要用于玩家游戲數(shù)據(jù)的持久化:如保留一些用戶信息以及游戲日志。
2.3.2 內(nèi)存型數(shù)據(jù)庫NoSQL
NoSQL不同于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,已經(jīng)不使用SQL作為查詢語言。NoSQL數(shù)據(jù)庫有幾大好處:大數(shù)據(jù)量,高性能,支持集群,易部署。本例采用的Redis[8]是一種key-value對應結(jié)構(gòu)的內(nèi)存數(shù)據(jù)庫,存儲效率高。同時支持定時器、自動排序結(jié)構(gòu)(stored set)、邏輯事務等結(jié)構(gòu),適合游戲內(nèi)的邏輯。還利用其提供的持久化用作游戲數(shù)據(jù)的備份。
2.4 消息通知服務
游戲邏輯需要在服務之間以及服務器組之間傳遞消息。文中采用的是ZeroMQ,其除了簡潔快速外,對其中組件的啟動順序沒有要求,適合游戲服務器動態(tài)擴展。文中使用ZeroMQ主要用到他的通訊模式只有兩類。
1)請求回應模型(Request-Reply)。
該模型為請求端(REQ)發(fā)起請求,等待回應端(REP)回應。因REQ端均只能在單線程中運行,因此必須要recv與send配對使用,但利用支持的路由功能(Router),加大了REQ端的擴展性,如下圖3,在游戲服務器常見情景如:客戶端發(fā)起戰(zhàn)斗請求,服務端將復雜的運算結(jié)果返回給客戶端。
圖3 ZeroMQ的請求回應模型
2)發(fā)布訂閱模型(Publish-Subscribe)。
訂閱端一旦連接上發(fā)布端就能收到發(fā)布端發(fā)送的消息,而沒連接上不影響發(fā)布端發(fā)布給其他訂閱端。同時如果發(fā)布端丟失,所有訂閱端都會等待發(fā)布端連接上直至發(fā)布新的消息,如下圖4所示。而對于訂閱端斷線重連消息丟失以及訂閱端后連接上而丟失消息均可有相應解決方案。在游戲中實際常用在跨區(qū)玩法:不同游戲區(qū)組成一個跨區(qū)讓玩家玩一個模塊,跨區(qū)服相當于發(fā)布端,其他游戲大區(qū)相當于訂閱者,從而實現(xiàn)跨區(qū)消息傳送目的。
圖4 ZeroMQ的發(fā)布訂閱模型
應用層采用PHP開發(fā),開發(fā)效率高,適合于頁游、手游這類快速開服平臺。采用高性能框架,采用內(nèi)存化數(shù)據(jù)緩存,能保證游戲邏輯快速響應。
3.1 開發(fā)框架
采用Yaf(Yet Another Framework)是由PHP核心開發(fā)組成員惠新宸開發(fā)一款用C語言擴展開源框,與其他框架CI、Zend Framework,Yii相比效率更高,無需編譯,在PHP啟動時加載,并常駐內(nèi)存。優(yōu)化如圖5。
圖5 優(yōu)化框架圖
同時支持MVC(Model-View-Controller,應用邏輯和表現(xiàn)邏輯分開)。游戲處理請求與發(fā)送請求代碼如下例:
3.2 加密與安全
由于PHP是一種腳本型語言,以明文方式保存在服務器,所以并不安全??梢圆捎肸end Guard Loader、ioncube等商業(yè)軟件來加密源代碼。
3.3 優(yōu)化與加速
由于PHP預編譯時會把源碼編成opcode緩存來達到加速目的,這里開啟PHP5.5以后自帶OPCache[11],相對比eacce lerator、xcache、apc等緩存工具更穩(wěn)定。
對于游戲邏輯中用到的大量配置文件,采用緩存到redis方法達到加速目的。
3.4 模塊說明
3.4.1 游戲邏輯模塊
采用MVC開發(fā)模式,Models模型文件提供接口給Controller來處理游戲邏輯。
3.4.2 登陸模塊
由于目前手機游戲和網(wǎng)頁游戲大多聯(lián)合運營,登陸、充值模塊都是以接口的方式與運營平臺通訊,所以這里采用WEB方式與平臺對接,與平臺驗證成功便可進入游戲邏輯。采用訪問白名單方式來保證通訊安全,同時寫入登陸日志以備查詢。
3.4.3 充值模塊
游戲開發(fā)商提供充值接口與運營平臺充值平臺對接,來完成游戲內(nèi)充值。在游戲內(nèi)需要一個常駐進程來處理來自運營平臺的充值邏輯。同樣這個接口需要設置白名單來保證安全性。由于充值會涉及很多游戲邏輯,所以這里將以隊列形式(如:Redis的List數(shù)據(jù)類型)來處理。
3.4.4 日志模塊
1)一般游戲日志:如用戶消費日志,使用日志一般均是在游戲邏輯中以數(shù)據(jù)庫形式保存,方便查詢和制作數(shù)據(jù)報表
2)游戲運行日志:包括游戲邏輯異常、worker進程異常日志,一般以文本形式保存,方便改進。
在游戲行業(yè)快速發(fā)展的今天,技術(shù)變化日新月異,不斷有更優(yōu)化、更適合的方案出現(xiàn)?;赑HP的socket游戲服務器方案優(yōu)點明顯,但也有一些缺點。若是計算密集型應用,就無法體現(xiàn)出libevent提供的異步非阻塞IO的優(yōu)點。本文從基礎層、核心層以及應用層三部分進行系統(tǒng)的介紹,實現(xiàn)一種快速高效的解決方案。通過對實際游戲運行測試,結(jié)果表明該服務器可實現(xiàn)較高的穩(wěn)定性和運行速度,達到所需目的。
[1](美)Pieter Hintjens.ZeroMQ:云時代極速消息通信庫[M].盧濤,李穎譯.北京:電子工業(yè)出版社,2015.
[2]李子婷.基于分布式中間件的多人在線網(wǎng)絡游戲的構(gòu)建[D].上海:復旦大學,2010.
[3]陳俊,黃維平.分布式Memcached在社交游戲中的應用研究[J].電腦知識與技術(shù),2011,7(10):2301-2305.
[4]Kjetil Raaen,Hard Espeland&HonKvale Stensland.ADemonstration Of aLoekless,Relaxed Atomicity State Parallel Game Server[D].NorwaySimulaResearchLaboratory,2010.
[5](美)Pieter Hintjens.ZeroMQ:云時代極速消息通信庫[M].盧濤,李穎譯.北京:電子工業(yè)出版社,2015.
[6]深入理解Nginx[M].陶輝.北京:機械工業(yè)出版社,2013.
[7](美)W.Richard Stevens,(美)BillFenner,(美)Andrew M.Rudoff.Tudoff.UNIX網(wǎng)絡編程卷1:套接字聯(lián)網(wǎng)API[M].3版.北京:人民郵電出版社,2010.
[8]Redis設計與實現(xiàn)[M].黃健宏.北京:機械工業(yè)出版社,2014.
The architectures of socket game server based on PHP
WANG Sheng-lin
(Shanghai Zhulin Network Inc.PostCode,Shanghai200120,China)
Web games,mobile games fast development today,the game server need simplearchitectures,flexible configuationandsupport high-efficiencydevelopment.This paper presents the design of Socket server-based game,usehighefficiency PHP framework to develop the game logic,and game logicdon't need to care about the server communication details.This papermainly describes the system in three parts from the base layer and core layer and application layer.Among them,the base layer ismainly done to pave the way for the subsequent development of pre-module,which consists of data,protocolmodules;the core layer provide data communication and data storage;application layer is the base layer on the base,by calling each module server package and handling agreements.In order to improve server performance and speed,at the application layer adds libevent and ZeroMQ two open source model.In this paper,the proposed technology for the server based on the developmentofa good stability and speed.
gameserver;Socket;libevent;ZeroMQ
TM933.4
A
1674-6236(2016)20-0125-04
2015-10-28 稿件編號:201510208
王盛林(1977—),男,湖北蘄春人,工程師。研究方向:網(wǎng)頁游戲移動游戲系統(tǒng)架構(gòu)與開發(fā)。