Go vs Erlang(Yunba.IO)

Posted CSDN大数据

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go vs Erlang(Yunba.IO)相关的知识,希望对你有一定的参考价值。

因为云巴系统对高并发、低延迟的需求,我们对各个语言、平台做了很多的调研比较工作。这自然就包括致力于开发高并发应用的Go和Erlang。


并发



Erlang的高并发通过轻量级进程(process)实现,每一个进程都有独立的状态记录。


另外,使用goroutine要注意,goroutine运行完毕后,占用的内存放回内存池备用,不会释放。


对于每一个任务都需要有独立状态的场景,Erlang的process更有优势。


抢占式调度


Erlang的任务调度器有一个reduction budget的概念。进程的任何操作都会造成预算消耗,包括函数调用、调用BIF、进程堆垃圾回收、ETS读写、发消息(目标邮箱堆积的消息越多,消耗越大)。Erlang的正则表达式库也被做了修改以支持reductions。所以如果进程在长时间执行正则表达式匹配,也一样会消耗reductions,也会被抢占。

Go之前的调度器只在syscall发生时调度,优化后可以在任何函数调用时调度。但是要注意,如果在goroutine里写一个死循环,Go的调度器不能有效抢占,同一个调度器的其他goroutine会被挂起。


垃圾回收


像Java一样,Go的垃圾回收是全局的,这意味着一旦垃圾回收被触发,所有的goroutine都会被暂停,造成一段时间的业务延迟。


Erlang的垃圾回收是进程级别的,每一个进程都有自己独立的垃圾回收器,一个进程的垃圾回收被触发,不会造成其他进程被挂起。相对来说带来的业务延迟小。


错误处理


Erlang的每一个进程都有进程ID(PID),同时也可以给进程注册名字,也就是说每一个进程都有独立的身份,可以有效的监控每一个进程的状态。进程异常退出时,可以捕捉到退出事件,并重启进程(参见otp的supervisor/worker)。


Go的goroutine没有身份识别,goroutine的状态没办法监控。


动态反射


Erlang动态语言的特点,使它天然支持REPL,另外Erlang支持remote shell,我们可以在Erlang运行时,连接到remote shell与任何一个进程交互。这些特性对一个需要长期运行的复杂系统的维护带来了极大的便利。开发阶段也能有一些便利。


Go是静态语言,不支持REPL。


静态编译


Erlang是动态语言,有所有动态语言的所有缺点:


  • 运行速度慢

  • 不能做早期错误检查,需要依赖全覆盖单元测试

  • 代码规模大了,给编写带来困扰


Erlang现在也引入了spec,对函数的参数返回值在编译时做类型检查,但是跟静态语言比起来效果差的很远。


不过正是因为是动态语言,Erlang实现了运行时代码替换,这个特性对一个需要长时间运行的工业级产品,是一个非常重要的功能。


Go是静态语言,运行速度快,编译时做严格的类型检查,可以避免很多隐患。


框架


Erlang的OTP框架支持服务器端开发常见的几种模式(applications,supervisors,wokers),方便代码的组织。


Go暂时没看到类似的框架。


第三方库支持


Go是一个相对比较新的语言,虽说现在很多项目都开始支持Go,但很多第三方库的成熟度暂时不如Erlang。


总结


对于要求低延迟、高并发的后端服务,我们近期还是采用Erlang为主。但使用Erlang的过程中,Erlang缺乏静态检查的手段,也是一个很麻烦的问题,目前的做法是要求大家都使用IntelliJ IDEA编写代码,可以通过IDE提前发现部分语言问题。

同时我们会持续关注Go的发展。


weibo:@Tiger_张虎

原文:http://zhang.hu/go-vs-erlang/


以上是关于Go vs Erlang(Yunba.IO)的主要内容,如果未能解决你的问题,请参考以下文章

Erlang:从命令行调用 erl -eval 永远不会退出

不是语言之争--Go vs Erlang

Erlang:当你在 erl 中 f() 一个 Pid 时会发生啥?

Erl 中的记录(Erlang 问题)

如何在不中止 erl 的情况下中止 Erlang shell (erl) 中的接收语句?

如何在 Erlang 中的多个 erl 之间共享记录?