標籤:

國外很多遊戲服務端遊戲邏輯部分用c++開發,上線後沒辦法熱更,他們是怎麼考慮的?

最近接觸韓國和美國的遊戲開發團隊,他們都用c++做服務端遊戲邏輯開發,導致國內代理上線後沒辦法熱更維護,他們是怎麼考慮的?為什麼不使用腳本做遊戲邏輯?遊戲菜鳥有疑問?


UE4都能用C++做腳本了,你告訴我不能熱更?架構沒設計好賴語言都行?


現在連C++寫的顯卡驅動都能熱更,你告訴我伺服器不能熱更?這顯然是招錯人了。


我們就能熱更,C++,噢耶~


關注了問題好幾天了才有時間來回答。

先來回答題主, 不用腳本有幾個原因:

  • 1 參見ue4的列表(主要還是維護問題)(我翻譯爛)

The scripting approach is very welcoming to new programmers, but eventually it breaks down and becomes an obstacle to innovation and shipping. We experienced this over time as the Unreal Engine grew until finally, in 2011, we moved to a pure C++ architecture. The causative factors were both pervasive and general:

腳本對新人友好,但是有時影響真實平台發布。

- As an engine and its community grows, there is increasing pressure to expose more of the its native C++ features to the scripting environment. What starts out as a sandbox full of toys eventually grows into a desert of complexity and duplication.

項目變大了不斷的導出各種c++介面,腳本從天使變成魔鬼。

- As the script interface expands, there is a seemingly exponential increase in the cost and complexity of its interoperability or "interop" layer where C++ and script code communicate through a multi-language interface for calling functions and marshaling data. Interop becomes very tricky for advanced data types such as containers where standard scripting-language idioms differ greatly in representation and semantics from their templated C++ counterparts.

膨脹的腳本綁定層簡直爽到爆。

- Developers seeking to take advantage of the engine"s native C++ features end up dividing their code unnaturally between the script world and the C++ world, with significant development time lost in this Interop Hell.

強行隔離引擎和腳本花了不少時間。

- Developers need to look at program behavior holistically, but quickly find that script debugging tools and C++ debugging tools are separate and incompatible. Seeing where script code had gone wrong is of little value if you can"t trace the C++ that code led to it, and vice-versa.

調試惱火,腳本錯了都不曉得是底層c++錯了還是哪裡錯了。

  • 2 團隊人員只有c++經驗而且很熟。這個就沒法了,現實是這種例子還真多。這樣的團隊在產品環境穩定可靠性的要求下,只能用最熟悉的技術。腳本帶來很多不確定性。再者c++用熟了以後開發也沒傳的那麼惱火。

  • 3 潛在的性能問題。腳本除了開發方便,會引入很多潛在的性能問題,沒有好用的工具最後修復這些問題花的時間不比直接c++來的少。當你的腳本到了那種對象也不敢亂創建,用完了要記著釋放的時候,你會發現其實有時候也沒有比c++方便多少。

  • 4 還是腳本的維護問題。腳本量大了以後,沒有可靠的測試支撐的話,大規模的改動成本是很高的,而且很多時候腳本都是寫的比較不規範,重用起來也不方便。而且腳本的工具鏈寫參差不齊,比如說調試腳本就是比較痛苦的事情。很多公司都還在用log調試,但是想想如果用腳本造一個輪子沒有debugger會是如何的痛苦。IDE也頂多只能單詞完成,代碼多了根本記不住而且腳本的動態性導致運行才報錯,這種情況下,開發效率也不高。

  • 5 所以有些團隊開發中用腳本提高開發效率,後期穩定後轉換成c++。慢慢的,就乾脆直接c++了,免得還要翻譯一次。

我這裡不是說腳本不好,只是羅列了一些腳本比較麻煩的問題,腳本是不是你的團隊還是要具體分析才行。

///////////////////\////////\/\//\/風騷的分割線//////////////\/\//////////

怎麼熱更新c++服務端, 本質就2點,A重啟進程和B動態庫。這裡主要說B:

  • 像UE4一樣,腳本統一繼承自一個介面類並且能序列化自己。當代碼修改以後對應的子類能編譯成動態庫然後替換掉遊戲里對應的對象並把老對象數據通過序列化轉移到新對象上。因為外部操作都是通過純虛函數所以實現變了也不受影響。

  • 比較傳統的方式,只替換函數不交換數據。這種方式比較簡單但是要求提前分層設計,保證數據和行為是分離的。reload就直接換函數地址就OK了。當然也可以把函數都丟到介面裡面一次性全部reload。

大概就這樣,都會要求一定的前期設計,尤其是第一種。

其實熱更新還是比較危險的,想像一下汽車一邊跑一邊在被維修的情景。

還有客戶端的動態更新有些人也叫熱更新,但是其實只是把代碼和數據從伺服器上取下來再啟動遊戲,一般在運行中是沒有更新的也沒必要。這部分需求又不一樣,比如IOS動態庫更新限制大(不是不能)沒有腳本更新方便所以大部分人還是都用腳本,但是也避免不了改動native代碼(C#、C++)而更新大版本。


能不能熱更是架構設計的問題,不在於使用什麼語言,現在很多人一談伺服器熱更就說Lua, Erlang,我認為是掩蓋了伺服器設計理念上的缺陷。
如果你的伺服器集群像Google那樣設計為任何一個進程都可以隨時重啟,那用什麼語言已經不重要了,而且C++還天然自帶性能加成。

比如,我胡謅一個簡單的理想方案:

在遊戲伺服器(game)和客戶端(client)之間掛上網關伺服器(gate),gate只用來承載TCP連接,它一旦穩定幾乎是不需要重啟的,要更新遊戲內容的時候直接重啟game進程,client掛在gate上所以用戶不會感覺到掉線。

要更新的時候,正常的重啟game(暫不考慮到一些比如玩家正在戰鬥之類的狀態),gate把game進程重啟事件廣播給所有client,client重走一遍登陸流程,或者通過保留一些token來簡化這個登陸流程。

整套步驟下來,game的遊戲內容更新了,玩家也沒有重啟遊戲,這不就是熱更新想要的效果么?

還有一個方案就是拆分服務:

像郵件、聊天、排行榜這類需求比較固定的功能,做成請求/相應模型的單獨服務,這樣當這個模塊出現bug或者需要增加功能的時候,直接重啟對應的服務就可以了。


因為他們沒有藏好自己,做好清理。


要就可以了


回答大部分都是裝逼犯寫的!不是能不能做的問題,是方不方便,值不值得的問題。如果lua解決了問題,用cpp做熱更新麻煩,為什麼不用lua呢?什麼ue4,那你去做一個啊,花五年開發啊,真是服了。按照這種邏輯,那為什麼要操作系統,你自己直接控制硬體啊!為什麼做不到,是你太弱了啊!做遊戲的時間緊張,工作繁重,很多大牛根本體會不到,他們不是真做遊戲的。腳踏實地的太少,裝逼忽悠的太多。多時學習,多嘗試,不要輕信所謂大牛的論調,也許進步更快些。當然,準備好了,什麼時候也可以嘗試著cpp熱更,沒有人攔著你。


服務端遊戲邏輯部分用c++開發為動態庫,如果是按文件名載入,應該就方便切換了

更具體的說,就是2個dll,通過狀態變數決定該載入哪一個dll,只是需要注意。。。

不用腳本,是因為編譯的代碼比腳本的運行效率高很多


為什麼一定要熱更新,另外c++寫也可以熱更新,看你怎麼設計了


大家都看到了吧。

這就是一條清晰的鄙視鏈。


全你媽在這扯淡,說能的沒一個說出可行方案的,沒方案就老實等別人的!

對於這個問題,我也沒成熟的方案,但我可以幫你分析一下這個需求的必要性:

用c++的基本都是長鏈接遊戲,要想程序不重啟像erlang一樣運行中載入新代碼,應該做不到,就算用so動態載入,這個實操起來也很麻煩,這要代碼非常獨立才行,而像遊戲這樣邏輯,業務關聯性非常強的的服務,實現起來得不償失,我覺得能配置熱更新做好抽象的好就可以了,而且c++天生就約束你程序要非常健壯,遊戲又有每周定期維護,做代碼熱更意義真不大,我做的遊戲上線(包括公司內測試都)很少有bug,當然我不是說不考慮bug。。。

越簡單,越好控,越不容易出問題!

貼一個我最後做的一個遊戲代碼,最簡單的結構,穩定的要死,後端組閑的蛋疼

https://github.com/shaovie/gserver


誰倒是說說怎麼cocos2d-x怎麼熱更啊(無腳本)。

把so下載下來,整個換掉?那遊戲正在跑呢。更啥更。不得把遊戲先停了啊,那還叫啥熱更。

不拿具體例子做分析,我也知道c++能熱更(沒有做不到的事情)

我也知道設計不好。

那誰倒是說說這種情況要怎麼設計啊(引擎該怎麼改?。

知乎成為這些人秀優越的地方了。。。(跑


C++業務邏輯部分寫成SO,上線時install覆蓋SO,給框架發信號重新載入即可。

更新:

熱更新問題關鍵是服務重新部署時,已經收進來的請求不能丟。意味著服務端框架的請求接收模塊和業務處理模塊在部署時需要是分離的,而請求接收模塊一般實現的是通用邏輯一般不需要更新(通常還維護了消息隊列確保一段時間內請求不丟失),通過更新業務處理模塊就實現了業務服務的熱更新。業務處理模塊一般實現為SO(通過dlopen載入),或者腳本語言編寫的模塊(通過載入器載入,方法跟具體語言有關)。


誰說C++不能熱更。

分散式的架構,負載均衡設計的好,每個節點都妥妥的熱更啊,需求上線和更新一點都不影響對外服務,用戶零感知。

管你用什麼語言


其實熱更新主要還是看業務邏輯。我以前的一個業務也是遊戲,在國外版本就是熱更新,而國內就是宕機更新,為啥在國內宕機呢?因為運營模式里允許每周有個凌晨維護窗口。


利用.so更新。業務邏輯和框架分離。


能不能熱更關c++什麼事?甩鍋也要參照基本法啊


第一 任何語言都能熱跟

第二 能熱更的肯定很費勁了


我教你怎麼用c++熱更

先用c++實現一個腳步語言,再用這個腳步語言寫邏輯,妥妥的


推薦閱讀:

本人有一定的C++基礎,想哪一些項目練手熟練C++,怎麼開始呢?有什麼建議?
有沒有C++的web伺服器?
會C語言,如何學好C++?
C++ 編譯時會把標準庫里所有的函數都編譯嗎?還是其他的實現方式?如果全部編譯不是太費時間了?
如何從只會 C++ 語法的水平到達完成項目編寫軟體的水平?

TAG:遊戲 | C | 服務端 |