Mangos源碼分析(5):服務器結構探討之最終的結構

如果我們就此打住,可能馬上就會有人要嗤之以鼻了,就這點古董級的技術也敢出來現。好吧,我們還是把之前留下的問題拿出來解決掉吧。

   一般來說,當某一部分能力達不到我們的要求時,最簡單的解決方法就是在此多投入一點資源。既然想要更多的連接數,那就再加一臺網關服務器吧。新增加了網 關服後需要在大區服上做相應的支持,或者再簡單點,有一臺主要的網關服,當其負載較高時,主動將新到達的連接重定向到其他網關服上。

   而對於遊戲服來說,有一臺還是多臺網關服是沒有什麼區別的。每個代表客戶端玩家的對象內部都保留一個代表其連接的對象,消息廣播時要求每個玩家對象使用自 己的連接對象發送數據即可,至於連接是在什麼地方,那是完全透明的。當然,這只是一種簡單的實現,也是普通使用的一種方案,如果後期想對消息廣播做一些優 化的話,那可能才需要多考慮一下。

  既然說到了優化,我們也稍稍考慮一下現在結構下可能採用的優化方案。

  首先是當前的Zone Server要做的事情太多了,以至於他都處理不了多少連接。這其中最消耗系統資源的當屬生物的AI處理了,尤其是那些複雜的尋路算法,所以我們可以考慮把這部分AI邏輯獨立出來,由一臺單獨的AI服務器來承擔。

  然後,我們可以試着把一些與地圖數據無關的公共邏輯放到Master Server上去實現,這樣Zone Server上只保留了與地圖數據緊密相關的邏輯,如生物管理,玩家移動和狀態更新等。

  還有聊天處理邏輯,這部分與遊戲邏輯沒有任何關聯,我們也完全可以將其獨立出來,放到一臺單獨的聊天服務器上去實現。

  最後是數據庫了,爲了減輕數據庫的壓力,提高數據請求的響應速度,我們可以在數據庫之前建立一個數據庫緩存服務器,將一些常用數據緩存在此,服務器與數據庫的通信都要通過這臺服務器進行代理。緩存的數據會定時的寫入到後臺數據庫中。

  好了,做完這些優化我們的服務器結構大體也就定的差不多了,暫且也不再繼續深入,更細化的內容等到各個部分實現的時候再探討。

  好比我們去看一場晚會,舞臺上演員們按着預定的節目單有序地上演着,但這就是整場晚會的全部嗎?顯然不止,在幕後還有太多太多的人在忙碌着,甚至在晚會前和晚會後都有。我們的遊戲服務器也如此。

  在之前描述的部分就如同舞臺上的演員,是我們能直接看到的,幕後的工作人員我們也來認識一下。

  現實中有警察來維護秩序,遊戲中也如此,這就是我們常說的GM。GM可以採用跟普通玩家一樣的拉入方式來進入遊戲,當然權限會比普通玩家高一些,也可以提供一臺GM服務器專門用來處理GM命令,這樣可以有更高的安全性,GM服一般接在中心服務器上。

  在以時間收費的遊戲中,我們還需要一臺計費的服務器,這臺服務器一般接在網關服務器上,註冊玩家登錄和退出事件以記錄玩家的遊戲時間。

  任何爲用戶提供服務的地方都會有日誌記錄,遊戲服務器當然也不例外。從記錄玩家登錄的時間,地址,機器信息到遊戲過程中的每一項操作都可以作爲日誌記錄下來,以備查錯及數據挖掘用。至於蒐集玩家機器資料所涉及到的法律問題不是我們該考慮的。

  差不多就這麼多了吧,接下來我們會按照這個大致的結構來詳細討論各部分的實現。

  再強調一下,服務器結構本無所謂好壞,只有是否適合自己。我們在前面探討了一些在現在的遊戲中見到過的結構,並盡我所知地分析了各自存在的一些問題和可以做的一些改進,希望其中沒有謬誤,如果能給大家也帶來些啓發那自然更好。



  突然發現自己一旦羅嗦起來還真是沒完沒了。接下來先說說我在開發中遇到過的一些困惑和一基礎問題探討吧,這些問題可能有人與我一樣,也曾遇到過,或者正在被困擾中,而所要探討的這些基礎問題向來也是爭論比較多的,我們也不評價其中的好與壞,只做簡單的描述。

  首先是服務器操作系統,linux與windows之爭隨處可見,其實在大多數情況下這不是我們所能決定的,似乎各大公司也基本都有了自己的傳統,如網易的freebsd,騰訊的linux等。如果真有權利去選擇的話,選自己最熟悉的吧。

  決定了OS也就基本上確定了網絡IO模型,windows上的IOCP和linux下的epool,或者直接使用現有的網絡框架,如ACE和asio等,其他還有些商業的網絡庫在國內的使用好像沒有見到,不符合中國國情嘛。:)

   然後是網絡協議的選擇,以前的選擇大多傾向於UDP,爲了可靠傳輸一般自己都會在上面實現一層封裝,而現在更普通的是直接採用本身就很可靠的TCP,或 者TCP與UDP的混用。早期選擇UDP的主要原因還是帶寬限制,現在寬帶普通的情況下TCP比UDP多出來的一點點開銷與開發的便利性相比已經不算什麼 了。當然,如果已有了成熟的可靠UDP庫,那也可以繼續使用着。

  還有消息包格式的定義,這個曾在雲風的blog上展開過激烈的爭論。消息包格式定義包括三段,包長、消息碼和包體,爭論的焦點在於應該是消息碼在前還是包長在前,我們也把這個當作是信仰問題吧,有興趣的去雲風的blog上看看,論論。

   另外早期有些遊戲的包格式定義是以特殊字符作分隔的,這樣一個好處是其中某個包出現錯誤後我們的遊戲還能繼續。但實際上,我覺得這是完全沒有必要的,真 要出現這樣的錯誤,直接斷開這個客戶端的連接可能更安全。而且,以特殊字符做分隔的消息包定義還加大了一點點網絡數據量。

  最後是一個 純技術問題,有關socket連接數的最大限制。開始學習網絡編程的時候我犯過這樣的錯誤,以爲port的定義爲unsigned short,所以想當然的認爲服務器的最大連接數爲65535,這會是一個硬性的限制。而實際上,一個socket描述符在windows上的定義是 unsigned int,因此要有限制那也是四十多億,放心好了。

  在服務器上port是監聽用的,想象這樣一種情況,web server在80端口上監聽,當一個連接到來時,系統會爲這個連接分配一個socket句柄,同時與其在80端口上進行通訊;當另一個連接到來時,服務 器仍然在80端口與之通信,只是分配的socket句柄不一樣。這個socket句柄纔是描述每個連接的唯一標識。按windows網絡編程第二版上的說 法,這個上限值配置影響。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章