這篇文章主要介紹游戲服務(wù)器開(kāi)發(fā)基本體系與服務(wù)器端開(kāi)發(fā)技巧的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
為黃石港等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及黃石港網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、黃石港網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!首先,要明確一點(diǎn),做游戲服務(wù)器開(kāi)發(fā)和做傳統(tǒng)的web開(kāi)發(fā)有著本質(zhì)的區(qū)別。游戲服務(wù)器開(kāi)發(fā),如果沒(méi)有經(jīng)驗(yàn),一開(kāi)始根本沒(méi)有一個(gè)明確清析的目標(biāo),不像web那樣,有些明確的MVC架構(gòu),往往就是為了盡快滿足策劃的需求,盡快的實(shí)現(xiàn)功能,盡快能讓游戲跑起來(lái)。但是隨著功能越來(lái)越多,在老代碼上面修改的越來(lái)越頻繁,游戲測(cè)試時(shí)暴露出來(lái)的一堆bug,更讓人覺(jué)得束手無(wú)策,這個(gè)時(shí)候我們想到了重構(gòu),想到了架構(gòu)的設(shè)計(jì)。
游戲的構(gòu)架設(shè)計(jì)非常重要,好的構(gòu)架代碼清析,責(zé)任明確,擴(kuò)展性強(qiáng),易調(diào)試。這些會(huì)為我們的開(kāi)發(fā)省去不少時(shí)間。那要怎么樣設(shè)計(jì)游戲的構(gòu)架呢?可能每個(gè)游戲都不一樣,但是本質(zhì)上還是差不多的。
對(duì)于游戲服務(wù)器的構(gòu)架設(shè)計(jì),我們首先要了解游戲的服務(wù)器構(gòu)架都有什么組成的?一款游戲到上線,需要具備哪些功能?有些人可能會(huì)說(shuō),只要讓游戲跑起來(lái),訪問(wèn)服務(wù)器不出問(wèn)題不就行了嗎?答案是不行的,游戲構(gòu)架本身代表的是一個(gè)體系,它包括:
1,系統(tǒng)初始化
2,游戲邏輯
3,數(shù)據(jù)庫(kù)系統(tǒng)
4,緩存系統(tǒng)。
5,游戲日志
6,游戲管理工具
7,公共服務(wù)組件
這一系統(tǒng)的東西都是不可少的,它們共同服務(wù)于游戲的整個(gè)運(yùn)營(yíng)過(guò)程。我們一點(diǎn)點(diǎn)來(lái)介紹各個(gè)系統(tǒng)的功能。
一,系統(tǒng)初始化
系統(tǒng)初始化是在沒(méi)有客戶端連接的時(shí)候,服務(wù)器啟動(dòng)時(shí)所需要做的工作?;旧暇褪桥渲梦募淖x取,初始化系統(tǒng)參數(shù)。但是我們必須要考慮的是,系統(tǒng)初始化需要的參數(shù)配置在哪兒,是配置在本地服務(wù)器,還是配置在數(shù)據(jù)庫(kù),服務(wù)器啟的時(shí)候去數(shù)據(jù)庫(kù)取。配置的修改需不需要重啟服務(wù)器等。
二,游戲邏輯
游戲邏輯是游戲的核心功能實(shí)現(xiàn),也是整個(gè)游戲的服務(wù)中心,它被開(kāi)發(fā)的好壞,直接決定了游戲服務(wù)器在運(yùn)行中的性能。那在游戲邏輯的開(kāi)發(fā)中我們要注意些什么呢?
(1)網(wǎng)絡(luò)通信
游戲是一種網(wǎng)絡(luò)交互比較強(qiáng)的業(yè)務(wù),好的底層通信,可以大化游戲的性能,增加單臺(tái)服務(wù)器處理的同時(shí)在線人數(shù),給游戲帶來(lái)更好的體驗(yàn),至少不容易出現(xiàn)因?yàn)榫W(wǎng)絡(luò)層導(dǎo)致的數(shù)據(jù)交互卡頓的現(xiàn)象。在這里我推薦使用Netty,它是目前最流行的NIO框架,它的用法可以在我之前的文章中查看,這里不再多說(shuō)了。
有人疑問(wèn),代碼也需要分層次?這個(gè)是當(dāng)然了,不同的代碼,代表了不同的功能實(shí)現(xiàn)。現(xiàn)在的開(kāi)發(fā)語(yǔ)言都是面向?qū)ο蟮?,如果我們不加思考,不加整理的把功能代碼亂堆一起,起始看起來(lái)是快速實(shí)現(xiàn)了功能,但是到后期,如果要修改需求,或在原來(lái)的代碼上增加新的需求,那真是被自己打敗了。所以代碼一定要分層,主要有以下幾層:
a,協(xié)議層,也叫前后臺(tái)交互層,它主要負(fù)責(zé)與前臺(tái)交互協(xié)議的解析和返回?cái)?shù)據(jù)。在這一層基本上沒(méi)有什么業(yè)務(wù)邏輯實(shí)現(xiàn)。與前臺(tái)交互的數(shù)據(jù)都在這一層開(kāi)始,也在這一層終止。比如你使用了Netty框架,那么Netty的ChannelHandlerContext即Ctx只能出現(xiàn)在這一層,他不能出現(xiàn)到游戲業(yè)務(wù)邏輯代碼的實(shí)現(xiàn)中,接收到客戶端的請(qǐng)求,在這一層把需要的參數(shù)解析出來(lái),再把參數(shù)傳到業(yè)務(wù)邏輯方法中,業(yè)務(wù)邏輯方法處理完后,把要返回給客戶端的數(shù)據(jù)再返回到這一層,在這一層組織數(shù)據(jù),返回給客戶端,這樣就可以把業(yè)務(wù)邏輯和網(wǎng)絡(luò)層分離,業(yè)務(wù)邏輯只關(guān)心業(yè)務(wù)實(shí)現(xiàn),而且也方便對(duì)業(yè)務(wù)邏輯進(jìn)行單元測(cè)試。
b,業(yè)務(wù)邏輯層,這里處理真正的游戲邏輯,該計(jì)算價(jià)格計(jì)算價(jià)格,該通關(guān)的通關(guān),該計(jì)時(shí)的計(jì)時(shí)。該保存數(shù)據(jù)的保存數(shù)據(jù)。但是這一層不直接操作緩存或數(shù)據(jù)庫(kù),只是處理游戲邏輯計(jì)算。因?yàn)闃I(yè)務(wù)邏輯層是整個(gè)游戲事件的處理核心,所以他的處理是否正確直接決定游戲的正確性。所以這一層的代碼要盡量使用面向?qū)堑姆椒ㄈ?shí)現(xiàn)。不要出現(xiàn)重復(fù)代碼或相似的功能進(jìn)行復(fù)制粘貼,這樣修改起來(lái)非常不方便,可能是修改了某一處,而忘記了修改另外同樣的代碼。還要考慮每個(gè)方法都是可測(cè)試的,一個(gè)方法的行數(shù)最好不要超過(guò)一百行。另外,可以多看看設(shè)計(jì)模式的書(shū),它可以幫助我們?cè)O(shè)計(jì)出靈活,整潔的代碼。
三,數(shù)據(jù)庫(kù)系統(tǒng)
數(shù)據(jù)庫(kù)是存儲(chǔ)數(shù)據(jù)庫(kù)的核心,但是游戲數(shù)據(jù)在存儲(chǔ)到數(shù)據(jù)庫(kù)的時(shí)候會(huì)經(jīng)過(guò)網(wǎng)絡(luò)和磁盤(pán)的IO,它的訪問(wèn)速度相對(duì)于內(nèi)存來(lái)說(shuō)是很慢的。一般來(lái)說(shuō),每次訪問(wèn)數(shù)據(jù)庫(kù)都要和數(shù)據(jù)庫(kù)建立連接,訪問(wèn)完成之后,為了節(jié)省數(shù)據(jù)庫(kù)的連接資源,要再把連接斷開(kāi)。這樣無(wú)形中又為服務(wù)器增加了開(kāi)銷(xiāo),在大量的數(shù)據(jù)訪問(wèn)時(shí),可能會(huì)更慢,而游戲又是要求低延時(shí)的,這時(shí)該怎么辦呢?我們想到了數(shù)據(jù)庫(kù)連接池,即把訪問(wèn)數(shù)據(jù)庫(kù)的連接放到一個(gè)地方管理,用完我不斷開(kāi),用的時(shí)候去那拿,用完再放回去。這樣不用每次都建立新的連接了。但是如果要我們自己去實(shí)現(xiàn)一套連接池管理組件的話,需要時(shí)間不說(shuō),對(duì)技術(shù)的把控也是一個(gè)考驗(yàn),還要再經(jīng)過(guò)測(cè)試等等,幸好互聯(lián)網(wǎng)開(kāi)源的今天,有一些現(xiàn)成的可以使用,這里推薦Mybatis,即實(shí)現(xiàn)了代碼與SQL的分離,又有足夠的SQL編寫(xiě)的靈活性,是一個(gè)不錯(cuò)的選擇。
四,緩存系統(tǒng)
游戲中,客戶端與服務(wù)器的交互是要求低延遲的,延遲越低,用戶體驗(yàn)越好。像之前說(shuō)過(guò)的一樣,低延遲就是要求服務(wù)器處理業(yè)務(wù)盡量的快,客戶端一個(gè)請(qǐng)求過(guò)來(lái),要在最短的時(shí)間內(nèi)響應(yīng)結(jié)果,最低不得超過(guò)500ms,因?yàn)榧由蟻?lái)回的網(wǎng)絡(luò)傳輸耗時(shí),基本上就是600ms-到700ms了,再長(zhǎng)玩家就會(huì)覺(jué)得游戲卡了。如果直接從數(shù)據(jù)庫(kù)中取數(shù)據(jù),處理完之后再存回?cái)?shù)據(jù)庫(kù)的話,這個(gè)性能是跟不上的。在服務(wù)器,數(shù)據(jù)在內(nèi)存中處理是最快的,所以我們要把一部分常用的數(shù)據(jù)提前加載到內(nèi)存中,比如說(shuō)游戲數(shù)據(jù)配置表,經(jīng)常登陸的玩家數(shù)據(jù)等。這樣在處理業(yè)務(wù)時(shí),就不用走數(shù)據(jù)庫(kù)了,直接從內(nèi)存中取就可以了,速度更快。游戲中常見(jiàn)的緩存有兩種,1,直接把數(shù)據(jù)存儲(chǔ)在jvm或服務(wù)器內(nèi)存中,2,使用第三方的緩存工具,這里推薦Redis,詳細(xì)的用法可以自己去查詢。
五,游戲日志
日志是個(gè)好東西呀,一個(gè)游戲中更不能少了日志,而且日志一定要記錄的詳細(xì)。它是玩家在整個(gè)游戲中的行為記錄,有了這個(gè)記錄,我們就可以分析玩家的行為,查找游戲的不足,在處理玩家在游戲中的問(wèn)題時(shí),日志也是一個(gè)良好的憑證和快速處理方式。
在游戲中,日志分為:1,系統(tǒng)日志,主要記錄游戲服務(wù)器的系統(tǒng)情況。比如:數(shù)據(jù)庫(kù)能否正常連接,服務(wù)器是否正常啟動(dòng),數(shù)據(jù)是否正常加載;2,玩家行為日志,比如玩家發(fā)送了什么請(qǐng)求,得到了什么物品,消費(fèi)了多少貨幣等等;3,統(tǒng)計(jì)日志,這種日志是對(duì)游戲中所有玩家某種行為的一種統(tǒng)計(jì),根據(jù)這個(gè)統(tǒng)計(jì)來(lái)分析大部分玩家的行為,得出一些共性或不同之處,以方法運(yùn)營(yíng)做不同的活動(dòng)吸引用戶消費(fèi)。
在構(gòu)架設(shè)計(jì)中,日志記錄一定要做為一種強(qiáng)制行為,因?yàn)椴粡?qiáng)制的話,可能由于某種原因某個(gè)功能忘記加日志了,那么當(dāng)這個(gè)功能出問(wèn)題了,或者運(yùn)營(yíng)跟我們要這個(gè)功能的一些數(shù)據(jù)庫(kù),就傻眼了。又得加需求,改代碼了。日志一定要設(shè)計(jì)一種良好的格式,日志記錄的數(shù)據(jù)要容易讀取,分解。日志行為可以用枚舉描述,在功能最后的處理方法里面加上這個(gè)枚舉做為參數(shù),這樣不管誰(shuí)在調(diào)用這個(gè)方法時(shí),都要去加參數(shù)描述。
俗話說(shuō),工欲善其事,必先利其器。游戲管理工具是對(duì)游戲運(yùn)行中的一系列問(wèn)題處理的一種工具。它不僅是給開(kāi)發(fā)人員用,大多數(shù)是給運(yùn)營(yíng)使用。游戲上線后,我們需要針對(duì)線上的問(wèn)題進(jìn)行不同的處理。不可能把所有問(wèn)題都讓程序員去處理吧,于是程序員們想到了一個(gè)辦法,給你們做一個(gè)工具,你們愛(ài)誰(shuí)處理誰(shuí)處理去吧。
六, 游戲管理工具
游戲管理工具是一個(gè)不斷增漲的系統(tǒng),因?yàn)樗芏鄷r(shí)候是伴隨著游戲中遇到的問(wèn)題而實(shí)現(xiàn)的。但是根據(jù)經(jīng)驗(yàn),有一些功能是必須有的,比如:服務(wù)器管理,主要負(fù)責(zé)服務(wù)器的開(kāi)啟,關(guān)閉,服務(wù)器配置信息,玩家信息查詢,玩家管理,比如踢人,封號(hào);統(tǒng)計(jì)查詢,玩家行為日志查詢,統(tǒng)計(jì)查詢,次留率查詢,郵件服務(wù),修改玩家數(shù)據(jù)等,根據(jù)游戲的不同要求,凡是可以能過(guò)工具實(shí)現(xiàn)的,都做到游戲管理工具里面。它是針對(duì)所有服務(wù)器的管理。一個(gè)好的,全的游戲管理工具,可以提高游戲運(yùn)營(yíng)中遇到問(wèn)題處理的效率,為玩家提供更好的服務(wù)。
七,公共組件
公共組件是為游戲運(yùn)行中提供公共的服務(wù),比如,充值服務(wù)器,我們沒(méi)必須一個(gè)服用一個(gè)充值,而且你也不能對(duì)外提供多個(gè)充值服務(wù)器地址,和第三方公司對(duì)接,他們絕對(duì)不干,這是要瘋呀;還有運(yùn)營(yíng)搞活動(dòng)時(shí)的禮包碼,還有注冊(cè)用戶的管理,玩家一個(gè)注冊(cè)賬號(hào)可以進(jìn)不同的區(qū)等。這些都是針對(duì)所有區(qū)服提供的服務(wù),所以要單獨(dú)做,與游戲邏輯分開(kāi),這樣方便管理,部署和負(fù)載均衡。還有SDK的登陸驗(yàn)證,現(xiàn)在手游比較多,與渠道對(duì)接里要進(jìn)行驗(yàn)證,這往往是很多http請(qǐng)求,速度慢,所以這個(gè)也要拿出來(lái)單獨(dú)做,不要在游戲邏輯中去驗(yàn)證,因?yàn)榫W(wǎng)絡(luò)IO的訪問(wèn)時(shí)間是不可控制的,http是阻塞的請(qǐng)求。
所以,綜上來(lái)看,一個(gè)游戲服務(wù)器起碼有幾個(gè)大的功能模塊組成:a,游戲邏輯工程;b,日志處理工程;c,充值工程;d,游戲管理工具工程;e,用戶登陸工程;f,公共活動(dòng)工程等,根據(jù)游戲的不同需要,可能還有其它的。所在在構(gòu)架的設(shè)計(jì)中,一定要考慮到系統(tǒng)的分布式部署,盡量把公共的功能拆出來(lái)做,這樣可以增強(qiáng)系統(tǒng)的可擴(kuò)展性。
服務(wù)器端開(kāi)發(fā)的一些建議
本文作為游戲服務(wù)器端開(kāi)發(fā)的基本大綱,是游戲?qū)嵺`開(kāi)發(fā)中的總結(jié)。第一部分專(zhuān)業(yè)基礎(chǔ),用于指導(dǎo)招聘和實(shí)習(xí)考核, 第二部分游戲入門(mén),講述游戲服務(wù)器端開(kāi)發(fā)的基本要點(diǎn),第三部分服務(wù)端架構(gòu),介紹架構(gòu)設(shè)計(jì)中的一些基本原則。希望能幫到大家
一 專(zhuān)業(yè)基礎(chǔ)
1.1 網(wǎng)絡(luò)
1.1.1 理解TCP/IP協(xié)議
網(wǎng)絡(luò)傳輸模型
滑動(dòng)窗口技術(shù)
建立連接的三次握手與斷開(kāi)連接的四次握手
連接建立與斷開(kāi)過(guò)程中的各種狀態(tài)
TCP/IP協(xié)議的傳輸效率
思考
1)請(qǐng)解釋DOS攻擊與DRDOS攻擊的基本原理
2)一個(gè)100Byte數(shù)據(jù)包,精簡(jiǎn)到50Byte, 其傳輸效率提高了50%
3)TIMEWAIT狀態(tài)怎么解釋?zhuān)?br/>1.1.2 掌握常用的網(wǎng)絡(luò)通信模型
Select
Epoll,邊緣觸發(fā)與平臺(tái)出發(fā)點(diǎn)區(qū)別與應(yīng)用
Select與Epoll的區(qū)別及應(yīng)用
1.2 存儲(chǔ)
計(jì)算機(jī)系統(tǒng)存儲(chǔ)體系
程序運(yùn)行時(shí)的內(nèi)存結(jié)構(gòu)
計(jì)算機(jī)文件系統(tǒng),頁(yè)表結(jié)構(gòu)
內(nèi)存池與對(duì)象池的實(shí)現(xiàn)原理,應(yīng)用場(chǎng)景與區(qū)別
關(guān)系數(shù)據(jù)庫(kù)MySQL的使用
共享內(nèi)存
1.3 程序
對(duì)C/C++語(yǔ)言有較深的理解
深刻理解接口,封裝與多態(tài),并且有實(shí)踐經(jīng)驗(yàn)
深刻理解常用的數(shù)據(jù)結(jié)構(gòu):數(shù)組,鏈表,二叉樹(shù),哈希表
熟悉常用的算法及相關(guān)復(fù)雜度:冒泡排序,快速排序
二 游戲開(kāi)發(fā)入門(mén)
2.1防御式編程
不要相信客戶端數(shù)據(jù),一定要檢驗(yàn)。作為服務(wù)器端你無(wú)法確定你的客戶端是誰(shuí),你也不能假定它是善意的,請(qǐng)做好自我保護(hù)。(這是判斷一個(gè)服務(wù)器端程序員是否入門(mén)的基本標(biāo)準(zhǔn))
務(wù)必對(duì)于函數(shù)的傳人參數(shù)和返回值進(jìn)行合法性判斷,內(nèi)部子系統(tǒng),功能模塊之間不要太過(guò)信任,要求低耦合,高內(nèi)聚
插件式的模塊設(shè)計(jì),模塊功能的健壯性應(yīng)該是內(nèi)建的,盡量減少模塊間耦合
2.2 設(shè)計(jì)模式
道法自然。不要迷信,迷戀設(shè)計(jì)模式,更不要生搬硬套
簡(jiǎn)化,簡(jiǎn)化,再簡(jiǎn)化,用最簡(jiǎn)單的辦法解決問(wèn)題
借大寶一句話:設(shè)計(jì)本天成,妙手偶得之
2.3 網(wǎng)絡(luò)模型
自造輪子: Select, Epoll, Epoll一定比Select高效嗎?
開(kāi)源框架: Libevent, libev, ACE
2.4 數(shù)據(jù)持久化
自定義文件存儲(chǔ),如《夢(mèng)幻西游》
關(guān)系數(shù)據(jù)庫(kù): MySQL
NO-SQL數(shù)據(jù)庫(kù): MongoDB
選擇存儲(chǔ)系統(tǒng)要考慮到因素:穩(wěn)定性,性能,可擴(kuò)展性
2.5 內(nèi)存管理
使用內(nèi)存池和對(duì)象池,禁止運(yùn)行期間動(dòng)態(tài)分配內(nèi)存
對(duì)于輸入輸出的指針參數(shù),嚴(yán)格檢查,寧濫勿缺
寫(xiě)內(nèi)存保護(hù)。使用帶內(nèi)存保護(hù)的函數(shù)(strncpy, memcpy, snprintf, vsnprintf等),嚴(yán)防數(shù)組下標(biāo)越界
防止讀內(nèi)存溢出,確保字符串以'\0'結(jié)束
2.6 日志系統(tǒng)
簡(jiǎn)單高效,大量日志操作不應(yīng)該影響程序性能
穩(wěn)定,做到服務(wù)器崩潰是日志不丟失
完備,玩家關(guān)鍵操作一定要記日志,理想的情況是通過(guò)日志能重建任何時(shí)刻的玩家數(shù)據(jù)
開(kāi)關(guān),開(kāi)發(fā)日志的要加級(jí)別開(kāi)關(guān)控制
2.7 通信協(xié)議
采用PDL(Protocol Design Language), 如Protobuf,可以同時(shí)生成前后端代碼,減少前后端協(xié)議聯(lián)調(diào)成本, 擴(kuò)展性好
JSON,文本協(xié)議,簡(jiǎn)單,自解釋?zhuān)瑹o(wú)聯(lián)調(diào)成本,擴(kuò)展性好,也很方便進(jìn)行包過(guò)濾以及寫(xiě)日志
自定義二進(jìn)制協(xié)議,精簡(jiǎn),有高效的傳輸性能,完全可控,幾乎無(wú)擴(kuò)展性
2.8 全局唯一Key(GUID)
為合服做準(zhǔn)備
方便追蹤道具,裝備流向
每個(gè)角色,裝備,道具都應(yīng)對(duì)應(yīng)有全局唯一Key
2.9 多線程與同步
消息隊(duì)列進(jìn)行同步化處理
2.10 狀態(tài)機(jī)
強(qiáng)化角色的狀態(tài)
前置狀態(tài)的檢查校驗(yàn)
2.11 數(shù)據(jù)包操作
合并, 同一幀內(nèi)的數(shù)據(jù)包進(jìn)行合并,減少I(mǎi)O操作次數(shù)
單副本, 用一個(gè)包盡量只保存一份,減少內(nèi)存復(fù)制次數(shù)
AOI同步中減少中間過(guò)程無(wú)用數(shù)據(jù)包
2.12 狀態(tài)監(jiān)控
隨時(shí)監(jiān)控服務(wù)器內(nèi)部狀態(tài)
內(nèi)存池,對(duì)象池使用情況
幀處理時(shí)間
網(wǎng)絡(luò)IO
包處理性能
各種業(yè)務(wù)邏輯的處理次數(shù)
2.13 包頻率控制
基于每個(gè)玩家每條協(xié)議的包頻率控制,癱瘓變速齒輪
2.14 開(kāi)關(guān)控制
每個(gè)模塊都有開(kāi)關(guān),可以緊急關(guān)閉任何出問(wèn)題的功能模塊
2.15 反外掛反作弊
包頻率控制可以消滅變速齒輪
包id自增校驗(yàn),可以消滅WPE
包校驗(yàn)碼可以消滅包攔截篡改
圖形識(shí)別嗎,可以踢掉99%非人的操作
魔高一尺,道高一丈
2.16 熱更新
核心配置邏輯的熱更新,如防沉迷系統(tǒng),包頻率控制,開(kāi)關(guān)控制等
代碼基本熱更新,如Erlang,Lua等
2.17 防刷
關(guān)鍵系統(tǒng)資源(如元寶,精力值,道具,裝備等)的產(chǎn)出記日志
資源的產(chǎn)出和消耗盡量依賴(lài)兩個(gè)或以上的獨(dú)立條件的檢測(cè)
嚴(yán)格檢查各項(xiàng)操作的前置條件
校驗(yàn)參數(shù)合法性
2.18 防崩潰
系統(tǒng)底層與具體業(yè)務(wù)邏輯無(wú)關(guān),可以用大量的機(jī)器人壓力測(cè)試暴露各種bug,確保穩(wěn)定
業(yè)務(wù)邏輯建議使用腳本
系統(tǒng)性的保證游戲不會(huì)崩潰
2.19 性能優(yōu)化
IO操作異步化
IO操作合并緩寫(xiě) (事務(wù)性的提交db操作,包合并,文件日志緩寫(xiě))
Cache機(jī)制
減少競(jìng)態(tài)條件 (避免頻繁進(jìn)出切換,盡量減少鎖定使用,多線程不一定由于單線程) 多線程不一定比單線程快
減少內(nèi)存復(fù)制
自己測(cè)試,用數(shù)據(jù)說(shuō)話,別猜
2.20 運(yùn)營(yíng)支持
接口支持:實(shí)時(shí)查詢,控制指令,數(shù)據(jù)監(jiān)控,客服處理等
實(shí)現(xiàn)考慮提供Http接口
2.21 容災(zāi)與故障預(yù)案
略
三 服務(wù)器端架構(gòu)
3.1 什么是好的架構(gòu)?
滿足業(yè)務(wù)要求
能迅速的實(shí)現(xiàn)策劃需求,響應(yīng)需求變更
系統(tǒng)級(jí)的穩(wěn)定性保障
簡(jiǎn)化開(kāi)發(fā)。將復(fù)雜性控制在架構(gòu)底層,降低對(duì)開(kāi)發(fā)人員的技術(shù)要求,邏輯開(kāi)發(fā)不依賴(lài)于開(kāi)發(fā)人員本身強(qiáng)大的技術(shù)實(shí)力,提高開(kāi)發(fā)效率
完善的運(yùn)營(yíng)支撐體系
3.2 架構(gòu)實(shí)踐的思考
簡(jiǎn)單,滿足需求的架構(gòu)就是好架構(gòu)
設(shè)計(jì)性能,抓住重要的20%, 沒(méi)必要從程序代碼里面去摳性能
熱更新是必須的
人難免會(huì)犯錯(cuò),盡可能的用一套機(jī)制去保障邏輯的健壯性
游戲服務(wù)器的設(shè)計(jì)是一項(xiàng)頗有挑戰(zhàn)性的工作,游戲服務(wù)器的發(fā)展也由以前的單服結(jié)構(gòu)轉(zhuǎn)變?yōu)槎喾C(jī)構(gòu),甚至出現(xiàn)了bigworld引擎的分布式解決方案,最近了解到Unreal的服務(wù)器解決方案atlas也是基于集群的方式。
負(fù)載均衡是一個(gè)很復(fù)雜的課題,這里暫不談bigworld和atlas的這類(lèi)服務(wù)器的設(shè)計(jì),更多的是基于功能和場(chǎng)景劃分服務(wù)器結(jié)構(gòu)。
首先說(shuō)一下思路,服務(wù)器劃分基于以下原則:
分離游戲中占用系統(tǒng)資源(cpu,內(nèi)存,IO等)較多的功能,獨(dú)立成服務(wù)器。
在同一服務(wù)器架構(gòu)下的不同游戲,應(yīng)盡可能的復(fù)用某些服務(wù)器(進(jìn)程級(jí)別的復(fù)用)。
以多線程并發(fā)的編程方式適應(yīng)多核處理器。
寧可在服務(wù)器之間多復(fù)制數(shù)據(jù),也要保持清晰的數(shù)據(jù)流向。
主要按照?qǐng)鼍皠澐诌M(jìn)程,若需按功能劃分,必須保持整個(gè)邏輯足夠的簡(jiǎn)單,并滿足以上1,2點(diǎn)。
服務(wù)器結(jié)構(gòu)圖:
各個(gè)服務(wù)器的簡(jiǎn)要說(shuō)明:
Gateway 是應(yīng)用網(wǎng)關(guān),主要用于保持和client的連接,該服務(wù)器需要2種IO,對(duì)client采用高并發(fā)連接,低吞吐量的網(wǎng)絡(luò)模型,如IOCP等,對(duì)服務(wù)器采用高吞吐量連接,如阻塞或異步IO。
網(wǎng)關(guān)主要有以下用途:
分擔(dān)了網(wǎng)絡(luò)IO資源
同時(shí),也分擔(dān)了網(wǎng)絡(luò)消息包的加解密,壓縮解壓等cpu密集的操作。
隔離了client和內(nèi)部服務(wù)器組,對(duì)client來(lái)說(shuō),它只需要知道網(wǎng)關(guān)的相關(guān)信息即可(ip和port)。
client由于一直和網(wǎng)關(guān)保持常連接,所以切換場(chǎng)景服務(wù)器等操作對(duì)client來(lái)說(shuō)是透明的。
維護(hù)玩家登錄狀態(tài)。
World Server 是一個(gè)控制中心,它負(fù)責(zé)把各種計(jì)算資源分布到各個(gè)服務(wù)器,它具有以下職責(zé):
管理和維護(hù)多個(gè)Scene Server。
管理和維護(hù)多個(gè)功能服務(wù)器,主要是同步數(shù)據(jù)到功能服務(wù)器。
復(fù)雜轉(zhuǎn)發(fā)其他服務(wù)器和Gateway之間的數(shù)據(jù)。
實(shí)現(xiàn)其他需要跨場(chǎng)景的功能,如組隊(duì),聊天,幫派等。
Phys Server 主要用于玩家移動(dòng),碰撞等檢測(cè)。
所有玩家的移動(dòng)類(lèi)操作都在該服務(wù)器上做檢查,所以該服務(wù)器本身具備所有地圖的地形等相關(guān)信息。具體檢查過(guò)程是這樣的:首先,Worldserver收到一個(gè)移動(dòng)信息,WorldServer收到后向Phys Server請(qǐng)求檢查,Phys Server檢查成功后再返回給world Server,然后world server傳遞給相應(yīng)的Scene Server。
Scene Server 場(chǎng)景服務(wù)器,按場(chǎng)景劃分,每個(gè)服務(wù)器負(fù)責(zé)的場(chǎng)景應(yīng)該是可以配置的。理想情況下是可以動(dòng)態(tài)調(diào)節(jié)的。
ItemMgr Server 物品管理服務(wù)器,負(fù)責(zé)所有物品的生產(chǎn)過(guò)程。在該服務(wù)器上存儲(chǔ)一個(gè)物品掉落數(shù)據(jù)庫(kù),服務(wù)器初始化的時(shí)候載入到內(nèi)存。任何需要產(chǎn)生物品的服務(wù)器均與該服務(wù)器直接通信。
AIServer 又一個(gè)功能服務(wù)器,負(fù)責(zé)管理所有NPC的AI。AI服務(wù)器通常有2個(gè)輸入,一個(gè)是Scene Server發(fā)送過(guò)來(lái)的玩家相關(guān)操作信息,另一個(gè)時(shí)鐘Timer驅(qū)動(dòng),在這個(gè)設(shè)計(jì)中,對(duì)其他服務(wù)器來(lái)說(shuō),AIServer就是一個(gè)擁有很多個(gè)NPC的客戶端。AIserver需要同步所有與AI相關(guān)的數(shù)據(jù),包括很多玩家數(shù)據(jù)。由于AIServer的Timer驅(qū)動(dòng)特性,可在很大程度上使用TBB程序庫(kù)來(lái)發(fā)揮多核的性能。
把網(wǎng)絡(luò)游戲服務(wù)器分拆成多個(gè)進(jìn)程,分開(kāi)部署。這種設(shè)計(jì)的好處是模塊自然分離,可以單獨(dú)設(shè)計(jì)。分擔(dān)負(fù)荷,可以提高整個(gè)系統(tǒng)的承載能力。
缺點(diǎn)在于,網(wǎng)絡(luò)環(huán)境并不那么可靠。跨進(jìn)程通訊有一定的不可預(yù)知性。服務(wù)器間通訊往往難以架設(shè)調(diào)試環(huán)境,并很容易把事情攪成一團(tuán)糨糊。而且正確高效的管理多連接,對(duì)程序員來(lái)說(shuō)也是一項(xiàng)挑戰(zhàn)。
前些年,我也曾寫(xiě)過(guò)好幾篇與之相關(guān)的設(shè)計(jì)。這幾天在思考一個(gè)問(wèn)題:如果我們要做一個(gè)底層通用模塊,讓后續(xù)開(kāi)發(fā)更為方便。到底要解決怎樣的需求。這個(gè)需求應(yīng)該是單一且基礎(chǔ)的,每個(gè)應(yīng)用都需要的。
正如 TCP 協(xié)議解決了互聯(lián)網(wǎng)上穩(wěn)定可靠的點(diǎn)對(duì)點(diǎn)數(shù)據(jù)流通訊一樣。游戲世界實(shí)際需要的是一個(gè)穩(wěn)定可靠的在游戲系統(tǒng)內(nèi)的點(diǎn)對(duì)點(diǎn)通訊需要。
我們可以在一條 TCP 連接之上做到這一點(diǎn)。一旦實(shí)現(xiàn),可以給游戲服務(wù)的開(kāi)發(fā)帶來(lái)極大的方便。
可以把游戲系統(tǒng)內(nèi)的各項(xiàng)服務(wù),包括并不限于登陸,拍賣(mài),戰(zhàn)斗場(chǎng)景,數(shù)據(jù)服務(wù),等等獨(dú)立服務(wù)看成網(wǎng)絡(luò)上的若干終端。每個(gè)玩家也可以是一個(gè)獨(dú)立終端。它們一起構(gòu)成一個(gè)網(wǎng)絡(luò)。在這個(gè)網(wǎng)絡(luò)之上,終端之間可以進(jìn)行可靠的連接和通訊。
實(shí)現(xiàn)可以是這樣的:每個(gè)虛擬終端都在游戲虛擬網(wǎng)絡(luò)(Game Network)上有一個(gè)唯一地址 (Game Network Address , GNA) 。這個(gè)地址可以預(yù)先設(shè)定,也可以動(dòng)態(tài)分配。每個(gè)終端都可以通過(guò)游戲網(wǎng)絡(luò)的若干接入點(diǎn) ( GNAP ) 通過(guò)唯一一條 TCP 連接接入網(wǎng)絡(luò)。接入過(guò)程需要通過(guò)鑒權(quán)。
鑒權(quán)過(guò)程依賴(lài)內(nèi)部的安全機(jī)制,可以包括密碼證書(shū),或是特別的接入點(diǎn)區(qū)分。(例如,玩家接入網(wǎng)絡(luò)就需要特定的接入點(diǎn),這個(gè)接入點(diǎn)接入的終端都一定是玩家)
鑒權(quán)通過(guò)后,網(wǎng)絡(luò)為終端分配一個(gè)固定的游戲域名。例如,玩家進(jìn)入會(huì)分配到 player.12345 這樣的域名,數(shù)據(jù)庫(kù)接入可能分配到 database 。
游戲網(wǎng)絡(luò)默認(rèn)提供一個(gè)域名查詢服務(wù)(這個(gè)服務(wù)可以通過(guò)鑒權(quán)的過(guò)程注冊(cè)到網(wǎng)絡(luò)中),讓每個(gè)終端都能通過(guò)域名查詢到對(duì)應(yīng)的地址。
然后,游戲網(wǎng)絡(luò)里所有合法接入的終端都可以通過(guò)其地址相互發(fā)起連接并通訊了。整個(gè)協(xié)議建立在 TCP 協(xié)議之上,工作于唯一的這個(gè) TCP 連接上。和直接使用 TCP 連接不同。游戲網(wǎng)絡(luò)中每個(gè)終端之間相互發(fā)起連接都是可靠的。不僅玩家可以向某個(gè)服務(wù)發(fā)起連接,反過(guò)來(lái)也是可以的。玩家之間的直接連接也是可行的(是否允許這樣,取決于具體設(shè)計(jì))。
由于每個(gè)虛擬連接都是建立在單一的 TCP 連接之上。所以減少了互連網(wǎng)上發(fā)起 TCP 連接的各種不可靠性。鑒權(quán)過(guò)程也是一次性唯一的。并且我們提供域名反查服務(wù),我們的游戲服務(wù)可以清楚且安全的知道連接過(guò)來(lái)的是誰(shuí)。
系統(tǒng)可以設(shè)計(jì)為,游戲網(wǎng)絡(luò)上每個(gè)終端離網(wǎng),域名服務(wù)將廣播這條消息,通知所有人。這種廣播服務(wù)在互聯(lián)網(wǎng)上難以做到,但無(wú)論是廣播還是組播,在這個(gè)虛擬游戲網(wǎng)絡(luò)中都是可行的。
在這種設(shè)計(jì)上。在邏輯層面,我們可以讓玩家直接把聊天信息從玩家客互端發(fā)送到聊天服務(wù)器,而不需要建立多余的 TCP 連接,也不需要對(duì)轉(zhuǎn)發(fā)處理聊天消息做多余的處理。聊天服務(wù)器可以獨(dú)立的存在于游戲網(wǎng)絡(luò)。也可以讓廣播服務(wù)主動(dòng)向玩家推送消息,由服務(wù)器向玩家發(fā)起連接,而不是所有連接請(qǐng)求都是由玩家客互端發(fā)起。
虛擬游戲網(wǎng)絡(luò)的構(gòu)成是一個(gè)獨(dú)立的層次,完全可以撇開(kāi)具體游戲邏輯來(lái)實(shí)現(xiàn),并能夠單獨(dú)去按承載量考慮具體設(shè)計(jì)方案。非常利于剝離出具體游戲項(xiàng)目來(lái)開(kāi)發(fā)并優(yōu)化。
最終,我們或許需要的一套 C 庫(kù),用于游戲網(wǎng)絡(luò)內(nèi)的通訊。api 可以和 socket api 類(lèi)似。額外多兩條接入與離開(kāi)游戲網(wǎng)絡(luò)即可。
以上是“游戲服務(wù)器開(kāi)發(fā)基本體系與服務(wù)器端開(kāi)發(fā)技巧的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
本文名稱(chēng):游戲服務(wù)器開(kāi)發(fā)基本體系與服務(wù)器端開(kāi)發(fā)技巧的示例分析-創(chuàng)新互聯(lián)
網(wǎng)站路徑:http://aaarwkj.com/article4/coggoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、做網(wǎng)站、小程序開(kāi)發(fā)、網(wǎng)站策劃、面包屑導(dǎo)航、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
移動(dòng)網(wǎng)站建設(shè)知識(shí)