一、游戲服務(wù)器、普通APP和web服務(wù)器
如果是同等用戶規(guī)模,相對來說,游戲服務(wù)器的復雜程度要大于普通app和web服務(wù)器。當然涉及到特殊算法的服務(wù)器另說,比如搜索引擎、頭條人工智能推薦這些除外,在這里只說普通的。

二、游戲服務(wù)器類型
游戲服務(wù)器根據(jù)不同的游戲類型有很大的區(qū)別,如王者榮耀之類的MOBA手游,服務(wù)器主要由2部分構(gòu)成,局內(nèi)戰(zhàn)斗服務(wù)器和局外系統(tǒng)服務(wù)器。
局內(nèi)戰(zhàn)斗服務(wù)器程序是游戲?qū)S玫模谄渌?/span>app服務(wù)器上幾乎沒有使用場景,在技術(shù)方面是有鴻溝的,也就是說你在開發(fā)app服務(wù)器上使用的技術(shù)以及設(shè)計思路,是無法轉(zhuǎn)換為局內(nèi)戰(zhàn)斗服務(wù)器設(shè)計思路的,兩者之間存沒有相同點。
二、幀同步和狀態(tài)同步

戰(zhàn)斗服務(wù)器需要做到給各個玩家數(shù)據(jù)同步,也就是說,在一局游戲內(nèi),所有玩家的實時狀態(tài)都要相互可見。這其中又設(shè)計到2種技術(shù),幀同步和狀態(tài)同步。
幀同步服務(wù)器不包含游戲邏輯,就是簡單將客戶端發(fā)送過來的命令轉(zhuǎn)發(fā)給其他客戶端,比如玩家A執(zhí)行一個攻擊操作,那么玩家A客戶端會給服務(wù)器發(fā)送一個攻擊命令,服務(wù)器將這個命令同步給局內(nèi)的其他玩家,至于攻擊一下少多少點血,會不會把人打死,服務(wù)器不管,全部由客戶端完成計算判斷,客戶端計算完畢后將結(jié)果發(fā)送給服務(wù)器,服務(wù)器再將結(jié)果同步給其他玩家,然后客戶端播放表現(xiàn)效果。簡單的說幀同步服務(wù)器就是給各個游戲客戶端同步數(shù)據(jù),它會不間斷的發(fā),即使局內(nèi)的玩家什么都不干,傻傻的站在那里,服務(wù)器也會發(fā),他的作用就是同步玩家們的狀態(tài),所以說幀同步服務(wù)器費流量。
狀態(tài)同步服務(wù)器和幀同步服務(wù)器的區(qū)別在于,除了同步玩家狀態(tài)的機制相同外,狀態(tài)同步服務(wù)器包含游戲的運行邏輯,比如玩家之間互相攻擊、技能傷害大小計算,都在服務(wù)器上執(zhí)行,然后再將執(zhí)行結(jié)果同步給客戶端,客戶端只要根據(jù)結(jié)果播放對應(yīng)的動畫就可以了。
簡而言之,幀同步服務(wù)器和狀態(tài)同步服務(wù)器的區(qū)別就是游戲局內(nèi)游戲邏輯放在哪兒運行的問題。因為要運行游戲邏輯,狀態(tài)同步非常消耗服務(wù)器資源,如果代碼寫的爛一點,一臺4核8G的機器上只能跑10局游戲100個玩家,那么要是同時有10萬玩家在局內(nèi),就需要1000臺服務(wù)器,這么多服務(wù)器,運維管理壓力非常大。因此使用幀同步服務(wù)器能有效的減少服務(wù)器消耗資源,減少服務(wù)器數(shù)量。然而有缺點就有優(yōu)點,因為業(yè)務(wù)邏輯在客戶端,幀同步服務(wù)器很難有效的杜絕外掛問題,斷線重連也相對費勁,用戶體驗差。而狀態(tài)同步則不存在這種問題,能有效的杜絕外掛,也能很容易的支持重連進入游戲。所以這兩種技術(shù)各有優(yōu)缺點,選擇哪一種,需要根據(jù)實際情況權(quán)衡。
四、TCP與UDP協(xié)議
普通的web服務(wù)器或者app服務(wù)器十有八九使用基于tcp的http協(xié)議,而局內(nèi)戰(zhàn)斗服務(wù)器,普遍使用UDP。TCP是可靠傳輸協(xié)議,用起來省事,確認機制、丟包重傳、滑動窗口之類機制開銷也大,在極端性能敏感的場景下,裸奔的UDP更加合適,通過UDP實現(xiàn)一個lite版的TCP,是游戲戰(zhàn)斗服務(wù)器常規(guī)的優(yōu)化手段。
不過話說回來,看起來局內(nèi)戰(zhàn)斗服務(wù)器實現(xiàn)有很多門道,但是工作量其實非常少,屬于做好一次到處通用, 即使狀態(tài)同步,雖然業(yè)務(wù)邏輯跑在服務(wù)器上,但實際功能開發(fā)還是客戶端程序員實現(xiàn),服務(wù)器只是提供了一個運行程序的容器,戰(zhàn)斗邏輯的實現(xiàn)不歸服務(wù)器管。
再說說局外服務(wù)器,這部分和普通的web服務(wù)器和app服務(wù)器就比較像了,MySql、Redis、protobuf、消息隊列、分布式框架等等互聯(lián)網(wǎng)應(yīng)用的基礎(chǔ)架構(gòu)在游戲服務(wù)器上也是常規(guī)配置,不過有一點明顯的區(qū)別是,游戲服務(wù)器的數(shù)據(jù)存儲都是以玩家為單位的,當玩家登錄的時候,程序會將所有玩家的數(shù)據(jù),如道具、裝備、任務(wù)等所有相關(guān)數(shù)據(jù)從MySql等數(shù)據(jù)庫中加載到程序內(nèi)存,之后所有的操作都在內(nèi)存中進行,之后等到某個適當?shù)臅r機才會將內(nèi)存中的數(shù)據(jù)同步到MySql中。當然,為了保證即使程序掛掉,數(shù)據(jù)也不丟失,還需要設(shè)計許多復雜的機制,這里就不展開了。
而web服務(wù)器和app服務(wù)器則不是這么設(shè)計的,因為游戲如果不登錄是不可以玩的,因此我們可以把數(shù)據(jù)結(jié)構(gòu)設(shè)計成以用戶分組的。而web和app即使用戶不登錄,功能依然需要可以使用,功能和用戶不綁定,所以設(shè)計的時候也不會把數(shù)據(jù)以用戶為單位進行組織。不過除了數(shù)據(jù)組織方式不同外, 其他地方大致都相同,原本是做游戲服務(wù)器的,稍微熟悉下就可以去做web或者app服務(wù)器,反過來也一樣,互相之間沒有門檻。
不過從技術(shù)的角度出發(fā),局外游戲服務(wù)器的技術(shù)相對與其他互聯(lián)網(wǎng)行業(yè)是比較落后的,如果你原本是在傳統(tǒng)互聯(lián)網(wǎng)行業(yè),轉(zhuǎn)去做游戲服務(wù)器,可能會被雷到,因為他們用的框架一點也不”現(xiàn)代化“,也許框架的性能還不錯, 但是開發(fā)效率極低。這一點和游戲客戶端不一樣,游戲客戶端是脫離傳統(tǒng)互聯(lián)網(wǎng)技術(shù)的,他們有自己的技術(shù)棧,而且實時更新。比如unity、unreal引擎出新版本了,他們都會討論的熱火朝天,然后嘗試升級使用,這和互聯(lián)網(wǎng)行業(yè)的vue、react、spring更新一樣,相關(guān)程序員都會熱衷與研究。
但是服務(wù)器卻沒有這樣的熱點可以追,我在一家公司,這家公司雖然已經(jīng)生產(chǎn)了幾十個游戲,客戶端引擎也不知道換了多少套,但是服務(wù)器程序卻一點沒變,仍舊使用祖宗流傳下來的那套c++框架,里面什么都是手動實現(xiàn)的
比如數(shù)據(jù)傳輸協(xié)議,是自己組裝字節(jié)流,發(fā)送給另一端,另一端根據(jù)事先定義好的規(guī)則,一個int,一個bool,一個float的讀取。這對于理解網(wǎng)絡(luò)的本質(zhì)非常有好處,但是顯然在實際應(yīng)用中,使用protobuf會更好。
當然我也碰到過協(xié)議不自己實現(xiàn)而是使用protobuf的,而且使用的是java開發(fā)局外服務(wù)器,而網(wǎng)絡(luò)底層仍舊使用java自帶的NIO,而不是更好的netty。
總而言之,傳統(tǒng)的游戲服務(wù)器程序不是太喜歡用框架,而是偏向于自己造輪子。這可能跟這個行業(yè)大量使用c++有關(guān)系,即使有一部分游戲使用java服務(wù)器 ,但是開發(fā)人員大多也是c++轉(zhuǎn)過來的,還是以c++一切靠自己的思路在開發(fā),所以很難見到流行的互聯(lián)網(wǎng)框架在游戲服務(wù)器上使用。
游戲服務(wù)器不會只用一種語言開發(fā),也可能是兩種。如果是一種,那大概率是c++。如果是兩種,那大概率是c++加另一種語言。
用c++的原因很多,如果要找一種語言,兼顧性能、開發(fā)效率、流行度,那肯定是c++。戰(zhàn)斗服務(wù)器通常用c++開發(fā),一來是速度夠快;二來戰(zhàn)斗程序通常需要同時在客戶端和服務(wù)器上運行,要找一種跨平臺的,還是要c++,比如unity種就可以通過c#調(diào)用c++。
局外服務(wù)器可以不用c++做,用java、go甚至php都可以,不過近年來用go好像越來越多了。
最后還有一個人員方面的區(qū)別,一個傳統(tǒng)互聯(lián)網(wǎng)項目,后端開發(fā)人員會多于前端開發(fā)人員。而一個游戲項目,客戶端開發(fā)人員要比服務(wù)器開發(fā)人員多,可能一個項目服務(wù)器程序員只有3個,而客戶端程序員有10多個。而且客戶端程序員都很忙,而服務(wù)器程序員,在開發(fā)階段,相對很閑,游戲上線后, 會忙一些。