2020,游戲服務器開發(fā)需要掌握哪些,你都具備了嗎
序言
一、游戲服務器開發(fā)工作介紹
有很多朋友會問我,想從其它開發(fā)領域轉到游戲服務器開發(fā)上來,需要學什么?
或許是因為游戲服務器開發(fā)工資高,或許是因為感覺做游戲服務器需要掌握的技術更高級,更具有挑戰(zhàn)性,或許覺得想換個行當試試等等。
不管出于什么原因吧,做為一名從事游戲服務器開發(fā)和教學很多年的人,我當然是持歡迎態(tài)度的,那么我就先介紹一下游戲服務器開發(fā)的工作吧,游戲服務器開發(fā)具體要做哪些工作呢?
1.團隊溝通
基本上不管做什么開發(fā),都是一個團隊來完成的,游戲也是如此,游戲團隊一般由老板、總經理、CTO(技術主管)、主策劃(領導一些人,包括數值策劃、系統(tǒng)策劃、特效策劃)、主美(領導一些人,包括原畫、UI設計、特效動作設計)、客戶端主程(領導一些人,客戶端程序員、客戶端程序員...)、服務器主程(領導一些人,包括服務器程序員),外加運維。

而游戲的大部分邏輯實現與邏輯數據驗證都會放在服務器端,所以服務端程序需要明確了解策劃的需求,要了解就需要溝通,溝通方式的正確與否,直接關系到功能的實現是否正確,由于游戲邏輯的復雜性,單純的文檔描述可能不會非常完整,不像其它行業(yè)需求文檔就幾百頁,詳細的圖文并茂,制定好之后也很少變化。所以做為一名游戲程序員,一定要有良好的溝通方式和技巧。
所以大家在與人溝通的時候應該有意培養(yǎng)自己的溝通表達能力。盡量將表達準確,高效溝通。
2.架構設計
這個架構設計就像蓋房子打基礎,基礎好,房子就穩(wěn)固,基礎不好,房子高了就容易倒。架構設計需要結合軟件工程學來搞,它需要對服務器的整個流程有足夠的了解,對需求的變化有足夠的認識。架構的設計一般有幾個特性。
首先是易用性
架構一旦完成,在開發(fā)的時候就要方便使用,比如網絡通信架構,設計好之后,其他開發(fā)者就不需要關心客戶端的數據是怎么被傳輸到服務器端的,這個時候對于服務器開發(fā)者來說,只需要實現一些簡單的接口,就可以直接對客戶端發(fā)送來的請求進行處理操作。再比如說服務器端數據的存儲與更新,開發(fā)者只需要寫少量SQL語句或基本不用寫,都由架構的底層代碼完成,開發(fā)者只需要調用封裝好的API,就可以把數據存入數據庫而不用關心數據的最終流向,只需要關心實現邏輯就可以了。
第二,可擴展性
可擴展性包括兩個方面,一是代碼的可擴展性,比如說游戲中的任務處理吧,一個游戲中任務可能有幾十種,而且還可能不定時的增加,為了判斷不同的任務類型該執(zhí)行什么操作,最簡單也是最差的寫法是if else。想象一下,一個方法里面,有幾十個if else,這簡單是bug的理想誕生地呀。
一種可行的做法是使用責任鏈模式(具體的請參考設計模式的實現),這樣每種任務都有一個單獨的類去處理它,而不會影響其它的類,符合開閉原則,相互關聯少,越少越不容易出bug。二是部署的可擴展性,比如,如果在線人數突然增加或預期可能要增加,一臺物理機器可能處理不過來這么多的請求,那怎么辦?那就需要支持在不影響其它服務器運行的情況下,可以動態(tài)的添加機器。而當壓力降低之后,又可以移除某些機器,合理利用資源。
第三,高吞吐量
這個是指能盡量最大化的利用計算機固定的資源,去處理更多的請求,更快速的響應客戶端。這就需要在服務器架構設計的時候考慮異步處理,減少IO等待時間(比如請求redis,存儲數據庫,和其它服務器通信)以及數據緩存。說到異步,一定會涉及到多線程,并發(fā)等相關的技術,所以架構設計的時候需要對這部分知識有足夠的了解。
第四
要考慮是否所有的功能模塊都放在同一個進程中。也就是需不需要分布式開發(fā),哪些功能需要單獨拿出來。對于手機游戲來說,一般要求同時在線量比較小,功能比較單一,所有功能都在一個進程中,人數大量同時在線時,可以多部署幾組進程。而對于大型網頁游戲或客戶端游戲來說,特別是有些大區(qū)或不分區(qū)的情況,單個功能訪問量大,服務器就要考慮分布式部署開發(fā)了。
架構設計一般需要有經驗的開發(fā)者(項目主程)去搭建,新手可以作為了解,在接觸到項目之后,可以按這個思路去理解項目的架構是怎么樣構成的,如果讓自己來做,能否模仿出來,有時間可以自己嘗試去獨立設計架構,鍛煉自己的能力,有一天你是會實際去做的。
3.邏輯開發(fā)
架構搭建完成之后,緊接著就是游戲服務器的邏輯開發(fā),這時才開始真正去實現游戲需要的內容,比如注冊、登陸、任務、活動、背包、組隊戰(zhàn)斗等。
由于游戲邏輯可能需要的判斷條件多,組合變化多,所以在游戲邏輯開發(fā)過程中,你會慢慢發(fā)現面向對象的重要性。邏輯開發(fā)是一個任重而道遠的過程,同一個問題,可能有很多種實現方式,不同的實現方式對效率和吞吐量有很大的影響,所以就需要對需求功能的理解要深入,不同功能之間的關聯要明確。對常用的設計模式要知道如何使用。比如像上面說的替換數量比較多的if else的方式。邏輯開發(fā)需要謹慎細心,而且一定要自己測試才可以,不然bug在不知不覺中就產生了。

4.系統(tǒng)周邊開發(fā)
一個游戲成功的運營,需要很多服務去支持它,比如SDK接入、充值接入、日志統(tǒng)計、游戲運行管理系統(tǒng)(一般叫后臺管理系統(tǒng),是內部人員為了管理游戲的而開發(fā)的系統(tǒng))。比如修改某個用戶的等級、封號等。管理系統(tǒng)一般會用web開發(fā),與游戲服務器通信。
二、游戲類型與技術選擇
游戲服務器開發(fā)使用的技術取決于游戲的類型,不同的游戲類型,需要的游戲環(huán)境不一樣,所使用的技術也不一樣。但是在本質上都是一樣的,都是面對數據,處理數據,不同的是面對的數量大小而已。
1.PC類端游
這類游戲(俗稱“端游”)在線人數龐大,游戲中要處理的數據也非常龐大。所以對服務器性能要求非常高,一般都是采用C++做為開發(fā)語言,C++可以直接操作內存數據,與操作系統(tǒng)直接交互,減少數據之間的復制,它運行效率高,處理速度快,是這類游戲開發(fā)的首選開發(fā)語言。服務器端采用分布式架構,把不同的模塊分散在多臺物理機上處理。需要學習的大致有C++編程、Linux網絡編程、TCP/IP通訊協(xié)議、多線程編程,再加數據庫。它一般開發(fā)周期比較長,一個游戲的上線基本上需要三到五年。

2.網頁游戲
這類游戲(俗稱“頁游”)相對于端游來說,開發(fā)周期短,因為是網頁游戲,游戲的界面展示依賴于網絡傳輸,所在在畫面和特效上會次于客戶端游戲很多。游戲的特點主要集中在游戲的玩法上。但是對于服務器端來說,和端游類是差不多是一樣的,有些公司之前是做端游的,他們就直接把端游的服務器架構拿來就可以使用,以完成快速開發(fā)。

3.手機游戲
手機類游戲(俗稱“手游”)目前是最火最熱門的游戲,因為他的用戶量大,用戶占有時間長。但是手機游戲大多數是一般小游戲,功能簡單,玩法單一,一般都是休閑娛樂的?,F在也有一些稍微大型的MORPG游戲。所以手機游戲開發(fā)周期更短,上線更快。

目前,游戲市場競爭激烈,當前服務器主流的開發(fā)語言是C++和Java,但是C++學習難度大,開發(fā)速度慢。為了滿足游戲服務器快速開發(fā),快速上線,所以一般來說我們都是使用Java語言來開發(fā)服務器。近年來,隨著游戲市場的發(fā)展,游戲服務器開發(fā)技術因Java而生成了一套體系??梢怨╅_發(fā)者選擇。
三、使用Java開發(fā)服務器需要學習什么
Java語言,由于學習成本低,開發(fā)速度快,穩(wěn)定性高,開源框架多,目前已成為網頁游戲和手機游戲服務器開發(fā)的主要語言。咱們從系統(tǒng)的開發(fā)流程簡單梳理一下服務器開發(fā)需要用到的技術。
1.網絡通信
這個是首要實現的,如果沒有網絡通信,就沒有服務器存在的必要了。網絡通信就需要建立網絡連接。目前網絡通信有兩種方式,一種是短連接,比如http。一種是長連接,比如socket。

當然http也是基于socket的,socket是通信的基礎。所以要對TCP/IP通信的知識有所了解,明白通信的原理。基于這兩種網絡通信,游戲服務器也分為兩種,弱聯網和強聯網。
弱聯網的游戲一般是指一些小型的游戲,比如開心消消樂、連連看,以及一些卡牌養(yǎng)成類游戲,這類游戲一般幾秒鐘或幾分鐘再會與服務器同步一次數據,一般會使用短連接。而像一些ARPG游戲、實時戰(zhàn)斗類游戲,以及帶同屏顯示玩家的游戲,這類游戲與服務器交互信息頻繁,一秒鐘可能幾十次,會采用長連接,避免每次連接重新建立消耗系統(tǒng)資源,提高通信效率。
為了網絡通信的效率,服務器要使用NIO(非阻塞網絡通信)通信。它能支持大并發(fā)連接。Java NIO是多路復用IO,在多路復用IO模型中,會有一個線程不斷去輪詢多個socket的狀態(tài),只有當socket真正有讀寫事件時,才真正調用實際的IO讀寫操作。因為在多路復用IO模型中,只需要使用一個線程就可以管理多個socket,系統(tǒng)不需要建立新的進程或者線程,也不必維護這些線程和進程,并且只有在真正有socket讀寫事件進行時,才會使用IO資源,所以它大大減少了資源占用。目前基于此技術有很多開源框架,最常用的有兩種,Netty和Mina。
所以在網絡通信這一塊,如果是弱聯網游戲,可以使用web那一套來開發(fā)游戲服務器,需要學習的技術一般有HTTP原理、JSON格式協(xié)議、Servlet、Tomcat(也可以是其它web容器)、spring等。如果是強聯網游戲,要學習的技術有Netty或Mina可以選擇一種,多線程以及線程池的應用。這是網絡通信所必須掌握的。只要能把客戶端發(fā)送的信息接收到,并解析成代碼使用的明文,就是成功了一半了,剩下的事就是把代碼封裝好,方便邏輯開發(fā)調用!
通信這塊還要考慮消息的并發(fā),長連接情況下,怎么處理斷包,粘包問題,每個用戶的消息處理的是不是有序的,如果有序會不會阻塞消息,如果無序會不會造成處理混亂,比如后到的消息先處理了,這些問題都要處理好,目前一般是保證同一個用戶的消息要有序處理!
2.數據存儲
網絡通信調試好之后,不要急著做邏輯開發(fā),還需要把數據如何存儲理清楚!因為服務器端操作的全是數據,如果處理的不好,容易出bug,丟數據,這對游戲玩家來說是致命的,不可接受的!

數據存儲要考慮,
一,數據如何存到數據庫,是同步存儲,還是異步存儲!同步存儲即將數操作完之后立刻寫入數據庫,異步操作即數據操作完之后先存儲到內存緩存,然后由另外的線程或進程再同步到數據庫!游戲中一般都是采用的異步存儲方式,因為游戲并發(fā)量大,必須低延時,快速響應客戶端!如果直接操作數據庫太慢,會造成消息阻塞!內存緩存可先擇的框架有redis,memcache,具體怎么同步到數據庫,需要自己去設計了!
二,數據接口如何設計,能不能用工作生成這些數據操作的代碼,能不能不用寫SQL語句,需是封裝在底層,或由工具生成。編程是門藝術,在這就體現出來了,當然是仁者見仁,智者見智了!
三,大并發(fā)情況下數據的一致性,像這類可能多線程操作的數據,一般是放在內存中,由鎖來控制并發(fā)!所以對鎖的使用要熟悉,不要出現死鎖,或鎖粒度過大,造成線程的長時間等待的情況!
四,當數據量太大,一個數據庫存儲不了,數據該怎么分庫分表!一種是水平劃分,一種是垂直劃分!具體的劃分方式其它資料已有詳細介紹,請自行查找閱讀!目前有一個開源的分庫框架mycat,是用JAVA寫的,大家可以研究一下!
3.邏輯開發(fā)
邏輯開發(fā)就是實現游戲策劃想象的各種游戲功能,比如:登錄、物品使用、戰(zhàn)斗結算等!邏輯開發(fā)代碼量巨大,相互之間有很緊密的耦合性,所以每個功能模塊一定要劃分好!最好是接觸下單元測試,寫之前考慮一下是否方便單元測試,這樣設計的代碼會更加清晰,每個方法責任明確,不容易出bug!正是因為邏輯代碼復雜,為了更好的管理代碼,前輩們給我們總結了一些經驗,就是著名的設計模式,所以學習一下設計模式對代碼的管理有很大的好處!
邏輯開發(fā)一般遇到的問題有:
3.1,數據同步
一說到數據同步或資源共享的時候,一般都會考慮到鎖的使用。因為一份資源同時只能被一個線程訪問才是安全的。Java的JDK中提供了一些鎖,比如:synchronized,以及java.util.concurrent.lock包中的Lock對象,
java.util.concurrent包中還提供了其它的一些原子操作的類,我們知道i++操作不是線程安全的,但是可以使用AtomicInteger中的getAndIncrement();方法代替,還有線程安全的ConcurrentHashMap,以及阻塞隊列LinkedBlockingQueue等。都是邏輯開發(fā)中常用的處理數據同步的類。
3.2,設計模式的使用
使用設計模式,可以讓代碼更加清晰,可擴展性更強,維護性更佳,比如,任務系統(tǒng),任務會有很多種類型,要獲得任務數據時,在一開始寫這個系統(tǒng)的時候,我是這樣寫的if(type == 1)做什么,else if(type == 2)做什么,else if(type == 3)......else if(type == 35) else等。如果需要添加新的類型,又要添加else,這些if else都在同一個方法中。最后都不敢動一塊,就怕出bug。其實當一個方法中出現三個以上的if else將來還可能增加時,就應當考慮設計是不是有問題了,后來改成責任鏈模式或狀態(tài)模式,就解決了這個問題。還有一個例子是,當一個值變化,要影響多個任務完成狀態(tài)時,可以使用觀察者模式或監(jiān)聽模式或訂閱模式去實現,這樣功能之間完全解耦,出問題的機率會很小很小。
3.3,數據緩存框架的API使用
目前主流使用的數據緩存框架有redis和memcache,雖然在邏輯開發(fā)前,主程會對這些進行一些封裝,但是作為使用者還是需要對這些框架的客戶端的使用要有所了解的。這些可以去閱讀相關的文檔。不是太難。

4,程序部署與運行
目前,大多數Java項目都采用maven管理 ,可以使用maven打包開發(fā)好的程序,程序一般運行在遠程服務器上,比如云服務器。一般運行Java程序的遠程服務器都是Linux系統(tǒng),需要使用Linux命令操作,或寫一些shell腳本去自動化部署管理一些程序。
5,艱苦奮斗的精神
首先,一定要讓自己對這一行有興趣,明確自己在這一行的技術選擇,人生選擇。很多人都知道,程序員加班是常有的事,堅持的住就做,堅持不了就再換一家公司做。
綜上所述,想做Java游戲服務器方面的開發(fā)要掌握的技術有以下一些:
1,網絡通信框架,Mina或Netty必須熟悉一種。而且自己必須要親自搭建過,并明白其它原理。2,通信協(xié)議制定和處理斷包粘包,這一般屬于網絡通信框架要解決的問題。3,數據緩存框架,redis或memcache選擇一個,能熟練使用其客戶端的命令。4,Java基礎,Java NIO通信原理,Java集合的使用,Java多線程開發(fā),Java鎖的使用。5,了解一些設計模式。最好能把23種設計模式都看一遍,并結合自己的開發(fā)經驗,看哪些可以用到設計模式,但也不能死套設計模式,要靈活運用。6,熟悉使用Mysql數據庫。7,了解數據庫連接池的一些框架,比如Mybatis、hibernate。8,對HTTP協(xié)議熟悉,熟悉一種web容器,比如tomcat,了解其配置。9,對常用的一些Linux命令要熟悉使用。10,熱愛學習,不斷的充實自己,上面所說的只是入門技能而已,真正做起來要復雜的多,一定要讓自己喜歡游戲這個行業(yè),這樣才能有動力做下去,做自己喜歡的工作還是比為了工作要好的!