遊戲的後台是否可以用 scala 加 node.js 來代替 C++?

最近參加了QCon技術大會,發現Facebook, Twitter和LinkedIn這樣的支持全球上億用戶的網站廣泛地使用了scala做並發處理。而node.js的運行模型能夠支持高並發請求。因此我在想,傳統的多人在線遊戲後台多用C++編寫,現在是否可以用Scala和Node.js來代替?畢竟C++太過於複雜,而且不安全(例如緩衝區溢出漏洞)


網站伺服器和遊戲伺服器有挺多區別,不能混為一談。

1. 遊戲分很多種,咱們先來看看MMORPG。

再怎麼簡單的RPG伺服器都免不了處理多人交互的情形,上百人在同一個場景裡面,每個客戶端都需要收到其他所有人的操作信息。

其次,用戶的操作是非常頻繁的,一般的伺服器傾向於持有長連接。而且這些鏈接的是頻繁交互的,沒有明顯的持久的分區策略,所以限制了伺服器的橫向擴展,同一個場景往往只能放在一個物理機上面運行。

再次,端游通常是不敢把邏輯運算放客戶端的,用戶分分鐘給你破解掉,改改金幣,刷兩件裝備再常見不過了。所以這一台地圖伺服器得驗證地圖內所有玩家的操作,並計算怪物AI、掉率等一系列業務邏輯。

我們可以看到,傳統遊戲伺服器與網頁伺服器具有明顯的區別,具有長連接、多廣播、有複雜的業務邏輯、分區策略受限等獨特的業務需求。

2. 咱們在來看看並髮帶給遊戲伺服器的好處是什麼。

並發實際上是一種程序邏輯流程,他是不需要多核物理支持的。大致意思就是讓多個獨立的邏輯流看上去像是在同時跑一樣。操作系統級別的並發就是多進程多線程模型。讓OS處理時鐘中斷,io阻塞等等問題。

對於伺服器而言,如果任務大部分的時間耗在io上,有了並發機制可以避免整個地圖服務被io訪問阻塞。一個任務阻塞的時候,把空餘計算資源分配到其他任務上去。在這種情況下,並發是有益於伺服器運行效率還有響應時間的。

對於程序員而言,獨立的邏輯流意味著可以在一個可靠、簡單、松耦合的上下文環境裡面,完成自己的任務。

因為讓OS處理程序邏輯切換得反覆陷入內核,有的人覺得這樣太慢,做了一些處於user space的線程,進程內自己控制多個邏輯流。因為語言描述能力的限制,在C/C++上面寫還有用這種東西都太麻煩。於是產生了erlang, go, lua裡面的coroutine語法糖。

node.js本質上也是自己控制多個邏輯流,但是這個邏輯流是根據io狀態還有優先順序分發的。在實際的實現中,它盡量採用非阻塞非同步io,單個任務調用io的時候,我就停掉它,等io完成的信號發上來了,我再重啟它。

  • 注意這一點,每次我會運行一個任務,直到它完成或者是發生io調用都不會主動切換至其他的程序流。那麼如果這一個任務裡面涉及過於大量的計算,那麼整個地圖進程都會被block在這裡。
  • 而正因為node.js是非同步的,所以需要不斷的寫回調監聽io完成的信號。單個任務的邏輯流會多次的被打斷。當任務變得相當複雜的時候,即有所謂的callbak hell,會帶給調試開發非常大的麻煩。

3. 因為上面的原因,所以我不建議在非原型的MMORPG伺服器開發中使用node.js。

4. 最近興起的手游伺服器倒挺適合node.js,因為手游這玩意局限於網路問題,伺服器只能做關鍵數據驗證,也沒辦法處理特別多人交互的情形。伺服器端已經簡化得跟網頁伺服器沒啥區別了,業務邏輯也簡單,處理處理數據,然後持久化就成。


網遊有很多種,說說我熟悉的MMORPG。
CPU主要瓶頸在AI里的敵我關係判斷和尋路,一個遊戲進程一般也就支持1000到4000人,主要看AI和技能複雜度,調度根本不是主要問題。
MMORPG中玩家交互非常頻繁,每個人的操作都會對其周邊的玩家產生影響,時序也不能亂。對反饋的實時性要求也很高。這些要求都不適合將處理流程分解成互不相關的小塊來調度。
從遊戲設計上來說,策劃的創意是很難預測的,你要是構建了一個非常抽象,又非常多預設條件的模型來描述這些設計,最後肯定會想刪了重寫的。


可以。


我正在寫的遊戲,後台的主要語言就是nodejs,c++和lua已經成為了nodejs的腳本了。。。


如果用了 scala,誰還會讓 node.js 搭便車啊!只用 scala 就夠了。


我不是做手游的,但是,國內最最火的手游是我的同事開發的。
答案是,當然可以,但是和別人有沒有這樣用,沒有關係,在某個情況下的最優,有很多取捨
1. 非同步
你提到scala,nodejs,它們的開發模式是非同步的。c++也可以寫成非同步的,近三年內,我寫了不下20w行,超過50個c++做的非同步伺服器,其中還包括存儲。你的取捨應該是你的團隊和項目複雜度,在使用c++之後,還能否快速迭代。如果複雜度太高,我也建議使用go語言
2. 還是非同步
nodejs是函數式的非同步,協程是同步的代碼,執行流程卻是非同步的。go和lua,erlang都是原生支持它,c++也可以,還是團隊能力和複雜度的取捨。go也是系統級的語言,能和c代碼互調,能力區間很大
3. 性能取捨
scala是跑在jvm上面的,性能你懂。nodejs是js代碼,運行之前先編譯,性能會比前者好一些,使用體驗來看,性能和c++還是有距離。一些它沒提供介面的系統能力,你就用不到了,束手束腳。c++啥都能做,就是複雜些。
就你提到的兩個c++的複雜的地方,nodejs和scala上也不見得簡單。有朋友寫了一個nodejs svr,有內存佔用的問題,相當於內存泄漏,只能定時重啟解決。對象的生命周期問題,不是高手,也搞不定
4. 還是性能取捨
c++是快。但是國內的絕大多數程序員寫的程序慢,更多的,是自己糟糕的code能力搞出來的。使用c++語言,高手換java做同樣的事情也能比它快很多。所以,核心問題還是你們開發團隊的人,他們的團隊合作以及單兵作戰的能力。論個人實力,國內的程序員,能趕上google平均水平的非常少,思考問題的方式,自然就要作調整。要更關注團隊本身在語言上的適應度,而不是只論語言本身能否做某件事情


C++ 的優勢在於:寫的好的代碼在性能和內存佔用方面都能控制得不錯。
遊戲後台與 Facebook / Twitter 和 LinkedIn 這樣的大數據企業本來就是不同的概念。實時和離線,低延遲和高帶寬,需求區別意味著對技術的要求完全不同。
用 Java 寫的遊戲後端不是沒有啊。記得 Minecraft 就是?
更多的和 Erlang 比吧,為什麼一些網頁遊戲喜歡用erlang做服務端?

另外 C++ Primer 還沒啃完趕快回去看書去,跑來這種問題給 C++ 掠陣你特么在逗我~


我有限的手游及程序員經驗告訴我:用go是最好的選擇!


scala做並發處理主要是託了當初暴雪用akka的福吧?當時actor model還少,尤其是jvm上的actor model實現還少,所以只能用akka,現在,vert.x可以了,比akka好用多了,akka太繁瑣了,而且scala的語法變態程度比c++只多不少,你想用js也是一個比較天真的想法,js的各種features,對於看的人來說極為不友好,但是你可以試試,vert.x支持js,ruby,groovy等腳本語言,你可以試試,但是個人對用js做大並發處理並不十分看好,因為腳本本身就不適合做成特別大的東西,光動態類型就是一個pain in the as*的痛點


用哪種語言應該是看哪種語言適合你的問題,比如遊戲中scala中處理並發的優勢重不重要,你舉的例子更多是側重於數據產生和處理。而很多大型遊戲中除了數據以外有很大程度是做計算的,而且這些計算是組合性的,計算也就更複雜一些。所以速度很重要,對內存的控制也很重要。

再加上很多遊戲可能需要儘可能榨取顯卡等硬體的性能,C/C++ 更經常被使用就不難理解了。


遊戲伺服器要看情況。簡單的說 強調實時性,需要伺服器主動推送(一般的polling long polling 無法滿足),有伺服器控制對象(npc) ,單位唯一性(同一時間只有一個唯一對象)的傾向於長連接。因為業內最早的伺服器都使用c++編寫(效率,牛b的代名詞,年代較早語言不象現在百家齊放,其實目前很多測試已經證明c++在某些方面不是最快的),所以導致了游伺服器就是c++,其實有很多遊戲伺服器特別是頁游都是用java編寫。遊戲伺服器用什麼語言不是關鍵,具體看遊戲類型,目前大部分手游都是短連接客戶端計算,伺服器信任客戶端只做驗證,這類遊戲伺服器java PHP c# ruby 都能作為後台語言。
語言就是工具在適合的領域用適合的語言,現在已經不是用一種語言就能將項目做到底的年代了。


我來扯點別的,c / cpp 優化起來很舒服的.
你們也不能老看寫的舒服啊.
弄那些奇怪的語言,寫著寫著,內存泄露啦,也是可以搞死人的.


》》遊戲的後台是否可以用 scala 加 node.js 來代替 C++?

這個問題我要問你,是老闆,還是員工?

如果你是老闆,要快速開發出產品,實現盈利,縮短產品開發迭代周期,運維成本,以及用戶體驗。。那麼 PHP7 是最靠普的,國內很多上市遊戲公司都是採用 PHP 開發端游後台,手游,頁游.... 成功案例比比皆是,公司市價上千萬,每年盈利按億元計算的。
1. PHP 開發速度快,產品迭代周期短
2. PHP 人力成本比其他小眾語言成本地。例如 node.js, scala
3. 成熟的案例,招聘PHP遊戲開發人才不難

如果你是員工,用什麼都我所謂
1. 學學新東西, 2.開拓新領域, 3.多踩踩坑,積累經驗

至於替代C++?
什麼語言都能替代
目前與語言都才用JIT 技術,無論是Java這種半編譯的或是PHP zend/hhvm 編譯的 或是node.js 純腳本, 最終運行都會翻譯成彙編指令,同時第一次載入都會做緩存,不會每次運行都翻譯一次。腳本的運行速度不可同日而語。以前C/C++ 快腳本幾十倍,但現很難說了。分散式與高可用的提出加上硬體成本的降低(CPU 不是問題,內存不是問題,增加硬體成本遠比人力成本低且是一次行投入)使得單機性能不那麼重要,分布試才是王道。
綜合到場景應用,腳本開發速度快,無需編譯,容易調試,尤其是升級上的優勢這是編譯語言無法比的。C++ 要做到每天兩次升級,能玩死程序猿,但產品都希望立馬看到變化,老闆希望立即投入市場。
至於性能要看開發人員的能力,而不是語言的速度,決定開發出軟體產品的速度。一個工作7/8年的C++程序猿寫不出 10000並發的C++ 程序不是什麼新鮮事,但是使用腳本語言,node.js, php7 一個工作2/3年的程序猿就可以吧活乾的很不錯。
C++生態圈還有一個問題,很多C++程序猿尤其是MS 系的,他很多處在本地應用的開發階段。對互聯網時代的東西沒有什麼概念。

目前互聯網圈心態很浮躁,大家都忙著學架構,基礎的開發都不過關,口若懸河,眼高收低,大談特談架構,動不動XXXXXX 並發,寫出的程序卻1000並發都達不到。


在現代開發網遊伺服器來說,多核和多內存是必然要考慮的,如果有C和Lua的基礎,雲風的Skynet值得推薦(據說是CPU核數的增加能夠較好的提高伺服器的性能),多內存可以考慮Redis作為內存資料庫使用,數據的落地雲風博客的博文也有分享,LevelDB或許是個不錯的選擇。當然也可以嘗試用Go來進行開發,C++的話看情況吧,還有就是Rust這個語言,可能明年春的時候會出1.0版本,這個時間目前不好確定。Rust出來之後用C++的話可能更多時候就是不太明智的了,端游的話有積累可能一下子不會過來,但是頁游和手游,特別是手游,Go和Skynet,Rust(正式版出來之後嘗試)都是不錯的選擇。說真的,用Node.js的為什麼不會考慮Go和Skynet呢?


不行的,如果你直接用nodejs或者它現有的一些框架是很難搞定的,除非你用前面有人提到的網易的那個專門為遊戲做的框架,nodejs還是有很多局限性,滿足不了大部分遊戲的複雜的需求,還是用c++ java之類的吧,發展很多年很成熟了,說實在的如果遊戲不是特別複雜還不如用python,感覺都比nodejs靠譜


手游可以嘗試,端游肯定不行。
————————————————————
我是看到騰訊程序員戰鬥力這麼強,前來佔個位。


當然可以啦,C++的優點是與硬體近,所以處理圖形時速度快很多,如果是處理業務,其實主要是看選用的演算法的時間複雜度。各語言之間的執行效率差別沒那麼大,同樣用過C++跟JAVA,相比較的話JAVA的學習曲線更低,開發效率更高,更推薦用JAVA來做伺服器。當然其它語言像GO,ERLANG,PHP做伺服器的也蠻多的。


node.js沒試過,但很多網路遊戲都使用了lua作為編寫遊戲邏輯的主力語言.


我覺得完全可以吧,畢竟node.js寫起來會簡單點兒。如果有性能問題的話直接C++重寫相關部分就行了,node.js本來就是C++實現的,而且文檔第三個小標題就是如何嵌入C++,嵌入起來很方便的,性能不用擔心。


完全可以的 而且現在nodejs 的遊戲框架也不少的


推薦閱讀:

Doom 面世 20 年來,第一人稱射擊 (FPS) 遊戲有了怎樣的發展?
最適合遊戲開發的語言是什麼?
為什麼任天堂甚至都不願意嘗試為 iOS 開發遊戲?
為什麼魔獸世界正在衰落?
大神看菜鳥玩遊戲是種什麼體驗?

TAG:遊戲 | JavaScript | 伺服器端腳本 | Node.js | 遊戲後台開發 |