rpc服務在游戲中的簡單運用


我們最開始做的游戲框架,多數都是client—>server—>db的模式,但是隨着玩家數量的增加,一個server進程就會扛不住,需要多個進程服務於多個玩家。但是給定了不同進程的玩家,有可能需要交互,這就導致了client與server端的連接,有可能是o(1),但也可能是o(n)連接,o(n)的擴展性非常差,不容易維護,因此可以剔除了。但是如果只保持o(1),那必然要引入新的抽象服務,網關也就登場了。下圖是一個簡單的網關部署架構:

 

網關的引入,有哪些改變呢?
  • 內外網解耦,在保持客外網客戶端不變的情況下,可以通過這個中間層調整內網服務的實現
  • 規范化,由於請求是網關統一接受和分發的,會直接促使客戶端在發送和接受請求時規范化
  • 安全,由於網關具有收口作用,所有的安全問題都可以在這里解決,保護內網,比如反爬,認證等功能
  • 限流熔斷,在網關上實現限流,避免內網被突發流量壓垮
  • 統一的監控告警平台

 

有了網關后,開始在下游增加業務邏輯,可能我們會把所有的業務都耦合成一個service,比如聊天掛了,派系掛了,場景掛了,都可能會對有戲本身產生影響;基於此,不得不考慮拆分進程,之前的游戲service服務,可能會被拆分為多個服務,但是對於大多數的游戲開發人員來說,基於服務的開發,比基於進程的開發,也難的多,如果不是領導推進,也不會有人願意把聊天做成一個單獨的服務。
對於游戲來說,服務拆分最最極端的情況,就是一個消息cmd對應了一個service,但是這種情況會導致service越來越多,無法維護的程度,實際上游戲拆分也確實沒有必要。不過服務service越來越多,某個service甚至處於內存,cpu瓶頸的狀態,應該如何解決呢?這時候rpc的服務治理派上了用場。我們對上面的圖示做下改動:

 

 

game-rpc的引入,解決了哪些問題呢?
  • 開發人員不再需要關注內部通信機制,減少項目開發時間,降低成本
  • 強大的集群容錯,負載均衡能力等,保證每次調用都能路由到合適的節點

 

service與service做成了集群,每個service啟動后,往zk或nacos注冊中心注冊自己的url。gateway在啟動后,訂閱zk注冊中心的service列表,依托於rpc本身強大的集群,負載等功能,可以自動實現service的切換。
在針對rpg等長連接游戲類型時,玩家在場景中的移動都需要同步,廣播給周圍的玩家,但是rpc是單通道的,不能回傳,這應該如何處理呢?
有借於此,game-rpc增加了全雙工的概念,不僅僅是client對service的請求,同時service也可以根據uniqueId,進行主動推送。於是上面的流程圖變成了下面這樣:
 
 
一切看上去都很完美,似乎沒有問題了,然而新的問題隨之出現。
我們知道,優秀的架構體系中,單點問題是不能容忍的,很不幸,我們的gateway,就出現了單點。隨着玩家數量的增加,整個服務都會處於不可用的狀態。於是網關需要拆成集群的模式,新的架構圖顯示如下:
 
 
網關拆分后,gate1和gate2的玩家是兩個tcp長連狀態的服務,無法交互,這應該怎么辦?
我們參照了現行市面上比較常用的tcp網關做法,消息下行通知的解決方案,目前框架支持了兩種方式:
  • MQ廣播機制,當某台網關服務器收到廣播消息后,MQ通知給集群內的所有gate server,每個gate在收到消息后,判斷要推送端的消息是否是當前gate所持有的會話,如果在當前服務,則進行推送,否則拋棄
 
 
  • redis session共享,針對MQ的廣播機制,如果以后游戲火爆,同時有百萬玩家在線,那么gate集群里的機器,可能會達到上百台不等,如果每個消息都需要MQ廣播,有可能會導致信號風暴,於是我們調整了最后一種解決方案。玩家在登錄網關,認證成功后,把玩家id作為key,當前連接的網關uniqueId作為value,存儲到redis集群中。網關隨后把消息路由到具體某個service,service從redis集群里獲取到需要廣播的玩家對應的gate服務,service通過rpc消息下行,直接推送到具體的gate,再由gate轉發到client
 
 
說明:這種架構,更適用於全區全服類型的游戲。目前我們已經有多款線上游戲使用。
更多交流,也歡迎您關注我的微信公眾號:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM