隨着移動終端硬件配置的飛速提高,手遊行業開始從爆發期進入相對穩定的發展期。殘酷市場競爭環境下,遊戲公司紛紛尋求業務創新,手遊重度化、VR/AR遊戲、經典IP迴歸以外,遊戲出海和全球服也成爲新亮點。這也意味着雲服務須要承載愈來愈多後端服務器的支撐工做,合理的平臺架構將成爲系統穩定運行的基礎保障。數據庫
迄今爲止,UCloud平臺支持的遊戲已經超過了1000餘款,其中手遊佔據了70%以上。在這過程當中咱們也陪用戶踩過了不少「坑」,本文將結合以往的一些經驗和成功案例,爲你們闡釋遊戲架構設計上,可能會遇到的一些問題和解決方案。後端
場景A:All In One的MudOS架構緩存
MudOS是第一代遊戲架構,目前應該是無人使用的歷史里程碑了,之因此會在這裏提到,是由於在雲平臺,仍然有很多用戶使用數據、計算、日誌所有集中於同一臺服務器的All In One集中式部署架構。服務器
以當前的技術來講,公有云還沒能徹底避免宕機對業務形成的影響,而宕機必然要致使業務一段時間內的不可用。一旦出現雲主機內部系統崩潰,對於這種架構的服務器更是災難性的。由於時間和數據都很難保證,最終可能必須經過備份文件才能進行回檔。網絡
此外,集中式部署架構對於雲主機的性能要求很是高,隨着業務的增加,開發者常常要從新調整配置,甚至最後直接購買物理雲主機。同時,爲了達到太高的性能要求,須要對雲產品的硬件靈活性和彈性伸縮能力進行取捨,即便在購買了物理雲主機的狀況下,雲平臺的成本優化效果也沒法達到最大化。所以,但願你們在遊戲設計中規避掉這種集中式部署架構,儘可能使用邏輯服或者微服務的模式。架構
場景B:瘋狂掉線框架
掉線對全部遊戲玩家來講都是很是痛苦的事情,咱們曾經手過一個瘋狂掉線的案例,這個案例的獨特之處在於玩家在遊戲過程當中不多發生卡頓和瞬移問題,可是會常常出現掉線現象,並且仍是不按期的玩家集中掉線。掉線的時間點也很是巧合,基本上是在機房監控到DDoS、或者地方級以上骨幹容災切換閃斷的時候。運維
咱們初步分析多是業務和網絡的特殊狀況觸發的,在和用戶交流業務邏輯以後,瞭解到用戶的遊戲設計採用的是TCP邏輯:業務1分鐘發出1個心跳包,若是30秒未收到ACK測試則認爲客戶端掉線須要重連。很明顯,這種設計並無考慮到丟包或錯包等問題。微服務
由於實際狀況下,全球運營商的網絡設備都有必定的錯包率或丟包率,1分鐘1個心跳包模式下,一旦發生丟包,玩家在1分30秒內沒法收到測試信息,必然會被系統剔除,致使掉線。而在容災切換或者DDoS狀況下,丟包或者錯包的問題會更加嚴重,玩家會集中掉線也就能夠解釋了。性能
定位問題後,咱們幫助用戶對以上邏輯進行了修改,將玩家的掉線時間從1分30秒收斂成30秒,設置業務每10秒3個心跳包,超過3個週期未收到則視爲掉線。 每10秒3個心跳包的狀況下,超過30秒就有9個心跳包,只有當這9個心跳包所有丟失,系統纔會認爲玩家離線。邏輯修改後會形式一個緩衝區,避免錯包或丟包狀況下形成的系統判斷失誤。
場景C:單點DB的危機
下圖的業務架構設計得已經相對完整,整個系統採用的是DB的主從架構,可能宕機形成的風險都已經規避,惟一的疏漏在於用戶將Cache和業務綁定,一旦業務重啓,整個Cache就會被清空,同時若是Cache達到上限也形成業務異常。
有一次用戶的DB磁盤異常須要較長時間恢復,雪上加霜的是Cache即將寫滿,由於更改數據庫指向必須重啓業務,爲了保證遊戲的正常運行,又不能把業務切到從庫。最後只好聯合當時的DBA、內核以及系統專家,耗費大量時間來恢復主庫。
爲了不這種狀況再次發生,後續用戶直接將Cache層拆分出來放到咱們的高可用Redis上來保證系統的穩定。
場景D:Redis崩潰
相信作遊戲開發的人或多或少都經歷過Redis崩潰問題。本案例中,用戶採用了比較前沿的框架,它拋棄了傳統數據庫,直接使用內存存儲做爲數據的惟一存儲器。全球服上使用的是微服務框架,不存在單點風險,業務能力很是強。但由於在研發過程當中第一次使用集羣化,因此也踩過一些坑。
問題一:Redis AOF形成短暫查詢堆積。 解決方案是進行分片操做,保證AOF時間不同,將總體業務查詢危機縮減下來。此外,針對遊戲框架申請DPA,儘可能減小刷數據的可能性。 問題二:QPS極限僅能達到數千,甚至出現了不按期慢查詢卡死的狀況。 查看代碼和數據時發現,用戶的業務語句中大量使用了KEYS命令且無任何限制,這就相似於在巨大的MySQL集羣裏select *, 解決方式是直接將全部KEYS風險語句進行調整和範圍限制,保證業務的正常運做。 另外,集羣Redis是基於proxy和Redis分片實現的,而非集羣的原生Redis對短鏈接的處理性能極差,而且因爲單線程的特性,很是容易由於短鏈接將CPU打滿。對於Redis來講,即便提供最強的44核CPU,最後程序運行的結果也是1核跑滿,其它43個核圍觀。
所以,在設計遊戲的時候,使用Redis要特別注意兩點:一、集羣Redis儘可能少用Keys命令;二、主備Redis儘可能不要使用短鏈接,由於短鏈接過多會形成總體業務性降低,尤爲在Redis特別集中的環境下,影響會很是嚴重。
場景E:Register Server 單點
下圖爲一個實時對戰場景的全球服架構,架構採用了自動註冊機制,註冊服務器相似路由表功能,會保存全部微服務集羣的節點IP信息以供業務節點須要時查詢調用。架構左側上層爲高可用數據庫、高可用內存存儲,下方是對戰服務器和平臺入口,右側爲工會聊天室,框架裏面接入了四個對戰服。這個框架的穩定性和擴展性都很是強,主機狀態對總體業務的影響極小。
整個框架美中不足的是,最核心的註冊服務器採用的是單點,且該服務器串行在整個業務的邏輯中,一旦服務器異常,一樣會形成總體業務不可用。若是不作任何修改,在後續上線運維的過程當中,不管是由於壓力、系統仍是其它緣由,Register服務器都將會是一個巨大的技術風險。
針對上述問題,咱們根據不一樣的場景推薦了兩種不一樣的解決方案:
管控分離, 經過中心推送+本地緩存機制旁路Register。這種方案適用於調用邏輯較爲簡單的狀況; 影子備份, 配置備用Register Server同步數據並切換。這種方案適用於註冊邏輯較爲複雜的狀況。
總結
本文主要簡單介紹了不一樣場景、不一樣遊戲案例當中遇到的一些框架設計問題和解決方案。下篇文章,將會以對戰類全球服遊戲爲例,重點講講遊戲架構的設計思路與技術實現。
做者介紹
沈皓:UCloud PathX產品早期方案設計者之一,深耕全球服遊戲領域,曾全面負責多個知名遊戲的全球/跨國業務對接、部署及落地。對於MOBA、RTS、FPS等各種遊戲的出海全球化的需求、難點、架構實現等有獨到看法。