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 永远不会退出
Erlang:当你在 erl 中 f() 一个 Pid 时会发生啥?