为什么我要选择erlang+go进行server架构(2)
原創文章,轉載請注明出處:server非業余研究http://blog.csdn.net/erlib 作者Sunface
為什么我要選擇Erlang呢?
? ? ? 一、erlang特別適合中小團隊創業:
? ? ? ?erlang有異常成熟、經過電信級別大規模驗證的OTP應用庫,僅僅須要非常easy的代碼就能建立起異常穩定、容錯性強、擴展性強、高并發的server框架,這也是erlang最寶貴的核心價值所在。
? ? ? 二、erlang是天生的并發語言:
? ? ? ? ? ?erlang的并發特性是語言級別的,從開發伊始就採用了CSP并發模式, 以進程為單位,進程間沒有共享內存,變量不可變的實現方式保證了無鎖的并發模型,因此也是異常高效的,換句話說:你僅僅要像尋常一樣寫代碼就能并發,全然不用擔心不論什么底層實現,你的代碼能完美的并行執行在多核server上,假設你能寫出美麗的并發級別的算法和代碼(盡量少的順序代碼),那在32核機器上就能跑出32倍性能!!!! Go 語言的并發模型也是取經于Erlang,可是我覺得Erlang的并發模型更優秀,由于進程間全然沒有共享內存,全然無鎖。
? ? ? 三、再介紹下我當初的業務需求:
? ? ? ? ?一款多人在線游戲,一個玩家走一步都要把消息廣播給同屏的玩家,玩家聊天,戰斗更涉及到大量的消息廣播;怎樣應對?再有一個及其普通卻不太easy搞定的的需求:在線玩家列表怎么實現?是啊,你是不是在想用哪種鎖合適?提到的兩個場景的關鍵詞是:高并發,大量廣播;可能你還會想到"鎖".
? ? ? ? 我嘗試過在.net下使用完畢port+TPL庫+protocol buffer來完畢上面的功能,可是并沒有通過測試的檢驗,測試模型是聊天.在收發消息方面,client和server一對一的收發壓力不大,可是一旦開啟廣播,壓力一下就上去了.對象的頻繁創建會導致垃圾回收,而垃圾回收會導致CPU和內存都飄忽不定,中間增加對象池會得到一定緩解,可是不能徹底解決這個問題,然后想到的就是人為干預垃圾回收,推斷標準是什么呢?那就是用PerformanceCounter吧,結果發現PerformanceCounter一次調用分配的內存相當大!最后一版的結果是:聊天室模型,一人說話廣播給全部人,300人在線可以穩定,人數一多就開始不淡定了.這些都是經過量化分析得出的結果,使用的工具是Visual Studio2010中的Performace Profile工具.
? ? ? ?須要解決的第二個問題就是并發加鎖,最簡單的測試模型就是在線玩家列表.這個問題相同困擾了我非常久,嘗試各種鎖,還是在拋異常,要么就是性能的下降,問題此起彼伏.興許還要解決TCP通信的數據格式,以及粘包等問題......
? ? ? ?項目時間緊張,存在的風險非常多,要盡快把技術方案確定下來然后去推進別的事情;可是可供選擇的方案有C++和Erlang.坦白講我和團隊的基礎假設使用C++方案,一定能搞出來,可是排錯和性能優化將是一個巨大的挑戰.那么Erlang呢?從開篇引用的那段文字看,好像這就是我須要的,簡單了解了一下語法,還是非常驚喜,因為之前對F#有過接觸,一下感覺非常親切.并且我特別關注到:
? ? ?長處:
? ? ? 1.面向并發,有成熟并且久經考驗的框架可供使用,網絡部分已經經過了良好封裝
? ? ? 2.內存緩存解決方式進程字典,前者的讀寫速度是50NS-100Ns級別的
? ? ? 3.對二進制數據解析的語法是直觀,簡單,強大(游戲中有大量的二進制數據要處理
? ? ? 4.沒有共享內存! 沒有鎖!(我們在代碼中沒有過顯示使用鎖)
? ? ?缺點
? ? ? ?1.從一種語言過渡到還有一種語言,會有各種不爽:
? ? ? ?2.控制邏輯簡單僅僅有if 和 case ,并且有if沒有else,沒有continue break goto
? ? ? ?3.包含kernel庫和standlib庫在內,非常多函數和變量的命名和傳統語言不一樣
? ? ? ?因此我們就決定了採用erlang來又一次寫一套全新的架構,事實證明當初的決定是無比正確的,一個極少須要重新啟動、能熱更、穩定的游戲server實在是太重要了,并且開發過程和維護是如此的高速和輕松,我們的團隊一致覺得:從來沒有想過開發會是這么一件愉快的事情!
既然Erlang已經被我“吹”的快飛起來了,為什么還要使用Go?
? ?鑒于Go語言已經婦孺皆知了,我也就不介紹了,大概說說我自己的情況,我這人沒啥其它興趣愛好,業余時間絕大部分都花費在所謂的“程序猿要不停的學習才不會落伍”上,因此在11年的時候,知道了go,斷斷續續學習了一年后,Go1.1版本號出來后,發現改進非常大,就開始認真研究并常年混跡在google-group及國外大牛的博客世界中,自我感覺還能夠。當然我絕對不是Go的“朝圣者”,也發現Go確實不是非常完美,詳細能夠參見“為什么我要放棄Go“,此文作者的觀點我盡管不敢全然茍同,可是有些觀點還是贊同的,比方說非常多Go愛好者是非常護短的,假設你敢說什么“壞話”,就等著被查水表吧 ;)。
??
| 體系成熟 | 4 | 3 | 5 | 5 | 3 |
| 開發效率 | 5 | 5 | 3 | 4 | 5 |
| 性能 | 3 | 3 | 5 | 5 | 4 |
| 加密公布 | 3 | 0 | 4 | 3 | 5 |
| 邏輯簡單 | 5 | 5 | 3 | 4 | 5 |
| 易學易用 | 5 | 5 | 2 | 5 | 4 |
| 跨平臺 | 5 | 5 | 5 | 5 | 5 |
? ?因為Erlang和Go都是非常棒的語言,這里就出現一個問題:二選其一還是物盡其用?經過深思熟慮后,我和團隊選擇了后者。首先,erlang的OTP寫server并發框架非常之簡單、穩定且高性能,erlang的Mnesia數據庫也是非常輕量:速度非???#xff0c;分布式簡單,使用起來也非常原生態(是Erlang標準庫支持的),全部的這些都能把程序猿從繁瑣的工作中解放出來,可是,erlang也有個挺重要的問題(在不同業務場景中此問題或許非常突出,也可能全然無關緊要,至少85%的情況下不算一個問題):它是虛擬機語言,對于順序代碼的運行速度僅僅有C的七分之中的一個,盡管能夠利用多核的優勢,可是在大型mmorpg中,消息密集時,CPU的瓶頸還是挺明顯的,會影響玩家順暢的體驗感覺(ARPG)。
? ? 因此我就想假設邏輯這部分用Go來寫,是不是能夠非常好的利用這兩個語言的長處進行互補?心動不如行動,由于我們的erlang游戲架構的藕合度還是挺低的,因此分離出來地圖server,用Go又一次實現了下,通過socket跟erlang架構部分進行通信,發現效果異常之好,Go的性能、并發的原生支持再配合上erlang寫游戲框架,在性能上已經絕不亞于C++框架,可是后者大家都懂,中關村程序猿據說平均壽命50多歲,非常大的一部分原因是由于這個。
以后的路怎么走?
?? ?混合型編程會是以后的主流,由于沒有哪個語言是完美的,包含被眾多“朝圣者”所推崇的Go,假設我們能依據自己的業務場景,選對合適的語言,那不敢說事半功10倍,至少事半功倍應該是有的,所以不要被主流語言(Java,C++)禁錮了我們的世界,局限了我們的創新,假設能做到輕松愉快的開發,那這個世界該多美好!!
總結
以上是生活随笔為你收集整理的为什么我要选择erlang+go进行server架构(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转]“Ceph浅析”系列之(—)—Ce
- 下一篇: 机房收费重构之总结篇