美文网首页
Erlang游戏服务器精进之路

Erlang游戏服务器精进之路

作者: 陶马文 | 来源:发表于2017-07-12 12:07 被阅读772次

    % 希望未来可以不断增补

    对于大部分自称为Erlang程序员来说,Erlang更像是一个兴趣。我们熟悉Erlang的各种优点,譬如函数式编程,譬如极小的进程生灭代价,以及高度的并发性。我目前是一个游戏创业公司的主程,赌上了不小的代价决定用Erlang作为我们的服务器框架。在实际推进的时候也遇到了很多以前作为兴趣钻研时没有遇到的问题。

    Erlang仍然是我心目中一个非常适合开发大型系统的语言,但是最后你是否能用它开发出一个稳健的大型系统,取决于你是否有大型系统的思维。我必须承认我现在也在摸索之中,也就是说我目前也不具备开发稳健的大型系统的能力。游戏后台本身是一个很复杂的系统,从构建逻辑到performance tuning都有天然的复杂性。有了这个经验,未来去转移到其它系统的逻辑,譬如电商,社交系统等也都不会有太大压力。

    接下来的内容,假定你已经对Erlang语言本身,以及它所鼓励你的开发方式比较熟悉,你常常关注Erlang的发展,了解它的新动态。

    1. 不要过早优化
      当我在完成项目的时候对这个说法有了新的体会。过早优化是一个熟悉语言特性,却又缺乏项目经验的程序员常有的倾向。比如我们都知道Erlang虚拟机会对尾递归进行优化,也知道Erlang鼓励在函数定义中进行pattern matching而非函数内部。但是你在项目过程中首先要做的,是把所有的注意力先放在逻辑和需求上,关注数据结构,关注进程间的通信的是否明确。和你的客户端同事一起敲定前后端通信的格式和协议,完成所有的功能。这会帮助你节约大量的时间,先保证正确再追求性能。

    2. 不要尝试反模式的事
      本质上也落入不要过早优化的范畴。比如有人告诉你Erlang变量不变是件麻烦的事,你又不能把那些关键的函数都写成进程来修改内部状态,因为进程间通信的开销也很大。所以使用进程字典,或者使用ETS来存储那些需要常常改变的状态量。这样做其实违背了Erlang设计的初衷。因为函数式编程的语境下,使用可变状态的代价就是很大的。同时考虑到不要过早优化,你首先做的应当是估计函数从输入到输出的流程,并决定绑定哪些变量来描述中间结果,而不是首先想到要需要频繁改变的状态。脏操作总是应该在最后一步再考虑。

    3. 善用你的资源
      Erlang的社群不大,久经考验的Erlang项目,以及Erlang开发者也不是太多。如果你是初学者,你需要读一读 Learn you Some Erlang,这是一个非常全面的教程,比起文档向前推进了很多。进阶的开发者,同一位作者所写的 Erlang in Anger 值得你一读,这本书里面包含了各种在Erlang实际项目中的坑——但是仅限于几个方面。与此同时,淘宝褚霸(余锋)的博客也可以作为参考。

    4. 决定用Erlang还是Elixir?
      有一种流行的说法是说Erlang的语法太奇怪,限制了它的流行。于是2006年出现了基于Erlang虚拟机的Elixir,在语法上接近Ruby。如果你现在准备开始一个新的Erlang项目,并且听说过Elixir,你可能会考虑花点时间学一下Elixir。然而我个人在尝试之后,并不建议切换到Elixir,原因有如下几点:

    • 语义不明确
      之前通过首字母大小写区分的变量与atom变为a小写符号加冒号,map的#用作注释而%用作map的符号,本质上是提供了一系列的语法糖。如果你之前并没有接触过Erlang,准备去学一门这样的语言,那么恐怕Elixir是比Erlang更好的选择(尽管我也不是很确定),但是如果你已经对Erlang非常熟悉,那么这笔在时间上的投资并不划算。
    • 编译/包管理/单元测试/社区
      Elixir提供了mix作为一整套的编译/发布/测试工具,也确实非常好用。相比之下专注于Erlang编译/发布/测试的rebar3(下文会更详细说明)看起来有点土。Elixir的设计者对于编译过程有独到的见解,他说,表意不明的编译器信息应当看作bug提交上来,因此Elixir会向程序员提供非常友好的信息。然而Erlang的哲学是,你应当通过Erlang看起来刻板的语法,在写代码的时候来约束自己的行为,而不是在写代码的时候非常灵活,然后让编译器承担起告诉你哪里出错的思路。当然Elixir为习惯不同的人提供了一个新的选择,但是我的建议就是,不要轻易改弦易辙。
    1. 弱类型的麻烦
      Erlang不仅是一个动态类型的语言,而且更重要的是,它没有静态类型!这类的语言有一个特点,就是写起来很爽,读起来很痛苦,甚至会无谓地浪费时间。想要避免这些代价,大概有如下几种方法:
    • 作为状态/中间结果的数据结构只在模块内使用
    • 用tag进行pattern matching
    • 用dialyzer进行静态分析,它是比编译器更强大的检查器,可以发现在代码中调用不一致的地方

    % TBC

    相关文章

      网友评论

          本文标题:Erlang游戏服务器精进之路

          本文链接:https://www.haomeiwen.com/subject/ndzvhxtx.html