匪是语言的如何–Go vs Erlang

因为 云巴 系统针对强起、低顺延的需要,我们对各个语言、平台举行了很多底调研比较工作。这自就包括从事为付出高并发应用的
Go 和 Erlang。

并发

Go 对高起的支撑通过 goroutine 实现。goroutine 可以知晓啊轻量级的
线程(thread)。同一个 Go 应用创建的 goroutine 共享地址空间。

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 暂时并未顾Oracle类似之框架。

其三方库支持

Go 是一个相对比新的语言,虽说本多档次都从头支持
Go,但许多叔方库的成熟度暂时不使 Erlang。

总结

对要求低顺延、高并发的后端服务,我们多年来或者采取 Erlang 为主。但使用
Erlang 的进程被,Erlang
缺乏静态检查的手腕,也是一个好辛苦的问题,目前的做法是要求大家都施用
IntelliJ IDEA 编写代码,可以通过 IDE 提前意识有些语言问题。

而我们见面随地关注 Go 的前行。

 

有关作者

Tiger

weibo: @Tiger_张虎, 云巴 (yunba.io) 创始人,yunba.io 云后端服务。
JPush 创始人,原CTO。 Oracle VM 创始团队成员。

相关文章