學習遊戲伺服器程式設計高階篇之全球同服技術架構

2021-07-26 13:11:27 字數 3404 閱讀 4121

筆者介紹:姜雪偉,it公司技術合夥人,it高階講師,csdn社群專家,特邀編輯,暢銷書作者,國家專利發明人;已出版書籍:《手把手教你架構3d遊戲引擎》電子工業出版社和《unity3d實戰核心技術詳解》電子工業出版社等。

伺服器架構技術一直是技術熱點,比如比較流行的遊戲伺服器,各種資料平台系統等等都離不開伺服器的架構設計,伺服器架構設計的好壞直接決定了使用者對產品使用的體驗,在網際網路時代,全世界使用者或者玩家的距離已經開始變的越來越小,我們做的各種平台設計要能滿足全球使用者的使用已經成為了現實,資料的共享已經成為當前急需解決的問題。

全球同服第乙個擺在我們面前的問題是時間問題,地球上不同的國家,他們的時差是不同的,不同的時差的人要實現全球同服,需要在伺服器這塊處理好,解決方案是需要在不同的地區布置一組伺服器,這些伺服器資料最終要統一到乙個資料庫中,比如中國大陸玩家可以通過香港伺服器登陸到美國伺服器,這就要求中心伺服器的架設要在國外,所有的玩家資料都可以在美國伺服器最終實現統一。布置在世界各個地區的伺服器選擇,我們選用的開源框架haproxy框架伺服器,它的**是開源的,**:先介紹一下haproxy的功能:

haproxy通常是使用在web端的,也就是平台架構中,使用haproxy、php、redis和mysql就能支撐每週10億請求,而且擴充套件性非常好。在平台中的架構設計如下圖所示:

在上圖中,使用了symfony2,varnish,keepalived,redis。其中varnish的主要用處是varnish是一款高效能且開源的反向**伺服器和http加速器,它是一款開源的框架,網上有源**;keepalived主要功能是實現真實機器的故障隔離及負載均衡器間的失敗切換,redis主要是用於儲存的。在我們的全球同服 伺服器架構上varnish是用不到的,keepalived可以用於伺服器故障切換,如果一台伺服器發生故障了,它會快速的切換到另一台伺服器上,在這裡會用到xinetd服務的作用是檢測埠,haproxy用http協議檢測這個埠是否正常。haproxy伺服器之間的切換圖示如下:

接下來介紹資料層,

我們使用redis和mysql儲存所有的資料,mysql更多作為**快取層,而redis則是系統的主要資料儲存。選用redis的優點是:

以上講解的技術大部分都是應用在web的架構設計上,但是由於它的優點,現將haproxy主要是作為遊戲的節點伺服器使用,它的布局如下所示:

不同地區的客戶端通過這些伺服器登陸,比如中國大陸的玩家可以通過香港的haproxy伺服器登陸,最終會通過gate伺服器在美國彙總,我們的資料庫是放在美國的,我們的中心中心伺服器是在國外的,上圖中的伺服器是作為地區伺服器節點使用的。

haproxy作為乙個開源的伺服器它是使用c語言編寫的,只能在linux系統執行,感興趣的讀者可以去學習一下,接下來我們要把世界上各個地區登陸的玩家通過gate伺服器將它們聯絡起來,gate伺服器選擇的是erlang語言實現的gate伺服器,注意的是各個gate伺服器之間是相通的,只有這樣才可以滿足全世界玩家在一起。erlang伺服器用的也是比較多的,

erlang最大的優點是方便,很多基礎功能都已經整合到erlang語言中。之前用c++寫伺服器的時候,管理tcp連線很繁瑣,需要寫一大堆**來實現。底層的框架需要寫很多**實現,這樣既浪費時間,又會有很多bug。但是用erlang就方便多了,底層的一切你都不需要考慮,你只需要考慮,伺服器的架構以及業務邏輯。從此讓你徹底從底層的泥潭中解脫。可以直接使用erlang語言搭建遊戲伺服器如下所示:

我們這裡只是用它作為gate伺服器使用,使用erlang作為gate伺服器可以做到負載均衡,erlang語言非常容易上手的,這樣我們的haproxy伺服器可以直接跟erlang實現的gate伺服器直接鏈結,gate伺服器會做負載均衡處理,同時也解決了世界各個地區的接入問題。對erlang語言不了解的讀者可以查閱erlang的官方**:

10k+

客戶端接入和處理。skynet框架如下所示:

skynet的服務處理主流程比較簡單:乙個socket執行緒輪詢所有的socket,收到客戶端請求後將請求打包成乙個訊息,傳送到該socket對應的客戶特定訊息佇列中,然後將該訊息佇列掛到全域性佇列隊尾;n個工作執行緒從全域性佇列頭部獲取client特定的訊息佇列,從客戶特定訊息佇列中取出乙個訊息進行處理,處理完後將該訊息佇列重新掛到全域性佇列隊尾。

感興趣的讀者可以自行檢視skynet源**,**如下:每個客戶處理訊息時,都是按照訊息到達的順序進行處理。同一時刻,乙個客戶的訊息只會被乙個工作執行緒排程,因此客戶處理邏輯無需考慮多執行緒併發,基本不需要加鎖。這些訊息是從haproxy伺服器發出然後經過erlang gate伺服器把訊息分發給skynet處理,下面再看看skynet的併發排程任務方式:

上圖中,lua支援non-preemptive的coroutine,乙個lua虛擬機器中可以支援海量併發的協作任務,coroutine主要的問題是不支援多核,無法充分利用當前伺服器普遍提供的多核能力。所以目前有很多專案為lua新增os thread支援,比如lua lanes,luaproc等,這些專案都要解決的乙個問題就是併發任務的組成以及排程問題。併發任務可以使用coroutine表示:每個os執行緒上建立乙個lua虛擬機器(lua_state),虛擬機器上可以建立海量的coroutine。

sky net架構實現結束後開始資料儲存設計了,在這裡使用了mysql和redis儲存,它們的儲存方式在前面已經介紹過。

整個全球同服 伺服器架構的簡易設計如下圖所示:

以上實現了全球同服 伺服器技術架構,可以實現全球玩家同服,細節方面就不多說了,比如使用哪種通訊協議,開發邏輯使用lua開發等等。其實,它的主要原理還是利用了web架構的設計,要假設全球同服 伺服器,讀者主要掌握haproxy伺服器的學習,erlang語言的學習,skynet伺服器架構學習和lua指令碼的編寫,以及利用redis,mysql實現資料的儲存。在這裡也是提醒讀者市面上很多開源的東西如果利用的好也可以幫助我們實現很多事情。國外能做的事情,我們也可以做到。

學習遊戲伺服器程式設計提高篇

筆者介紹 姜雪偉,it公司技術合夥人,it高階講師,csdn 社群專家,特邀編輯,暢銷書作者,國家專利發明人 已出版書籍 手把手教你 架構 3d遊戲引擎 電子工業出版社 和 unity3d 實戰核心技術詳解 電子工業出版社等。在上篇學習遊戲伺服器基礎篇中給讀者介紹了如何學習遊戲伺服器,主要針對的是想...

遊戲伺服器程式設計

參考書籍 linux 多執行緒伺服器端程式設計 網路遊戲伺服器程式設計 unix網路程式設計 鳥哥的linux私房菜 unix環境高階程式設計 developing online games cnv1 cnv2 ice我參與專案已經用了ice,比ace corba這樣的中介軟體簡單。1 linux系...

遊戲伺服器開發 準備篇 初識遊戲伺服器開發

近期轉換了工作方向,從web開發走向了遊戲開發。此前的工作中,主要負責web分布式專案的開發,rest服務開發,幷包含一部分im系統的開發。分布式系統框架,資料庫,nosql接觸的比較多,比較雜。而新工作比較單一,主要負責遊戲伺服器的業務開發。使用的也是前輩封裝好的框架。後來發現,原來全公司都使用了...