Erlang is a general-purpose concurrent, garbage-collected programming language and runtime system.
The sequential subset of Erlang is a functional language, with strict evaluation, single assignment,
anddynamic typing. For concurrency it follows the Actor model. It was designed by Ericsson to support
distributed, fault-tolerant, soft-real-time, non-stop applications. It supports hot swapping, thus
code can be changed without stopping a system.[1]
--摘自维基百科 词条:Erlang
In computer science, the Actor model is a mathematical model of concurrent computation that treats "actors" as the universal primitives of concurrent digital computation: in response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and determine how to respond to the next message received. The Actor model originated in 1973.[1][2] It has been used both as a framework for a theoretical understanding of computation, and as the theoretical basis for several practical implementations of concurrent systems. The relationship of the model to other work is discussed in Indeterminacy in concurrent computation and Actor model and process calculi.
一款多人在线游戏,一个玩家走一步都要把消息广播给同屏的玩家,玩家聊天,战斗更涉及到大量的消息广播;如何应对?再有一个及其普通
却不太容易搞定的的需求:在线玩家列表怎么实现?是啊,你是不是在想用哪种锁合适?提到的两个场景的关键词是:高并发,大量广播;可能
你还会想到"锁".
我尝试过在.net下使用完成端口+TPL库+protocol buffer来完成上面的功能,但是并没有通过测试的检验,测试模型是聊天.在收发消息方面,
客户端和服务器一对一的收发压力不大,但是一旦开启广播,压力一下就上去了.对象的频繁创建会导致垃圾回收,而垃圾回收会导致CPU和内存都
飘忽不定,中间加入对象池会得到一定缓解,但是不能彻底解决问题,然后想到的就是人为干预垃圾回收,判断标准是什么呢?那就是用PerformanceCounter
吧,结果发现PerformanceCounter一次调用分配的内存相当大!最后一版的结果是:聊天室模型,一人说话广播给所有人,300人在线能够稳定,人数一多
就开始不淡定了.这些都是经过量化分析得出的结果,使用的工具是Visual Studio2010中的Performace Profile工具.
需要解决的第二个问题就是并发加锁,最简单的测试模型就是在线玩家列表.这个问题同样困扰了我很久,尝试各种锁,还是在抛异常,要么就是
性能的下降,问题此起彼伏.
后续还要解决TCP通信的数据格式,以及粘包等问题......
项目时间紧张,存在的风险很多,要尽快把技术方案确定下来然后去推进别的事情;但是可供选择的方案有C++和Erlang.坦白讲我和团队的基础
如果使用C++方案,一定能搞出来,但是排错和性能优化将是一个巨大的挑战.那么Erlang呢?从开篇引用的那段文字看,好像这就是我需要的,简单了解了
一下语法,还是很惊喜,由于之前对F#有过接触,一下感觉很亲切.而且我特别关注到:
-
面向并发,有成熟而且久经考验的框架可供使用,网络部分已经经过了良好封装
-
内存缓存解决方案ETS,检索时间为常量而且为常量值
-
对二进制数据解析的语法是直观,简单,强大
-
没有共享内存! 没有锁!(我们在代码中没有显示使用锁)
从一种语言过渡到另一种语言,会有各种不爽:
-
控制逻辑简单只有if 和 case ,而且有if没有else,没有continue break goto
-
没有for循环
-
包括kernel库和standlib库在内,很多函数和变量的命名简直太糟糕了
但是,这些都是可以接受的!一门语言在很多地方备受诟病,但是依然站在在不同时期的舞台上,无论是主角还是配角,它都没有被彻底否定掉,那么它必定
存在着不可替代的优势,而且随着它成为主角那一天,很多周边的支持会到位,那时再看就是另外一番景象了.就像javascript,早期调试js只有alter输出,大家
一遍埋怨,一遍用,浏览器兼容问题,跨域问题,被反反复复解决,而随着ajax的热潮,js一下成为宠儿.现在你可以在firefox里面进行单步调试了,jquery,prototype
等优秀的开发框架也为常见问题提供了完整的解决方案.
同样,看Erlang现在的局面,使用者较为小众,周边工具,框架较少,语法有种种的怪异之处,但它就是在处理并发上有着得天独厚的优势,无可取代;这和javascript
何其相似!如果说ajax是javascript的春天,那么Erlang的春天什么时候到来呢?马上!在单核处理能力达到一个极限的时候,虽然硬件工程师们说还有提升空间,而实际
上他们把处理能力的提升放在了多核上!我们当然希望在语言的基础框架层面就可以把并行计算的问题给隐藏掉,比如微软的TPL (Task Parallel Library),比如Erlang
后面,我会有专门的文章来比较这两者的使用的解决方案.在这里可以预言一下,并行计算一定会把Erlang变成主流!
这里有两篇很棒的文章:多核编程的难题(一) http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/
多核编程的难题(二) http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/
P.S: 现在C#在我们团队中主要作用是快速产出各种工具,作为一个.net开发者,心中还是有极大的不甘,基于.net是否有一个优雅的方案可以解决上述问题?
有兴趣的可以用聊天室模型来检验自己的方案是否有效,期待大家的结果