为什么我们放弃了Erlang技术栈

简介: 结合小博无线技术团队的具体经验,深入讨论了Erlang技术栈在云计算环境中所遇到的问题。

至2013年小博无线云端系统上线以来,我们一直是Erlang的重度使用者。尽管小博无线技术团队不乏拥有10年以上经验的精英级Erlang程序员,然而,从2016年开始,我们已不再使用Erlang开发新业务,而我们放弃Erlang技术栈的原因可被简要概括为下面这句话:

让开发和运维更简单

总的来说,Erlang技术栈的优点在云计算环境中要么难以体现,要么容易寻找到成熟的替代方案,但弱点却既顽强又难以绕开。以下逐一展开说明。

优点: 易用的高并发轻量级进程

这一度是Erlang独有的优势,但在今天,基于nginx+lua的openresty框架和golang都能提供,并且后两者还拥有更好的社区生态。

优点: 公平可靠的软实时调度

虽然lua, golang, nodejs在语言层面都内置了高并发机制,然而,不论是lua中需手动调用yield/resume的coroutine,或是golang中在系统调用时插入yield的goroutine,还是nodejs中依靠异步io回调实现的单线程多并发,都存在面对cpu密集型计算任务时调度不均的问题,因为它们都没有实现cpu使用统计与抢占式调度器。

Erlang VM对每个进程[1]的cpu占用进行了统计并实现了抢占式调度,即使某个进程不停计算,其他进程也不会被饿死。

这听上去很好,但在互联网业务系统中,却并没有多少实用价值。如果发现有部分业务计算逻辑需要消耗大量cpu以致影响了系统的整体响应或吞吐,说明应当将这部分计算功能抽离到一个单独的运行环境并给它分配更多的资源,而不是依赖VM的抢占调度!

优点: 位置透明性

Erlang内建的rpc机制可以让任意两个进程相互之间无需知晓对方的所在的结点,仅通过pid就能透明的向对方发送消息。

这一优点可以使用成熟的消息队列中间件获得,消息队列中间件能自然实现业务处理的前后端分离,并且前后端还可独立进行伸缩。

优点: 热更新

采用Erlang构建的系统可以在服务不中断,用户无感知的情况下部署变更。

使用“漂移上线”[2]可以获得同样的效果,并且对于采用任何技术栈构建的系统都是有效的。

弱点:全连通集群

Erlang集群采用的是全连通的组网方式,每加入一个新节点,都需要在当前集群中所有节点的/etc/hosts文件中加入这个新节点的hostname和ip,这样的设计使得伸缩和漂移都非常麻烦。

在云计算环境中,使用以负载均衡器为根,业务容器为叶结点的网络拓扑则要简单很多,可以很方便的实现秒级伸缩和漂移。

一种绕开的方案是自建DNS服务负责集群的域名解析,然而,这个方案又会带来诸如DNS服务的高可用性,新建记录的生效时间以及本地记录的缓存刷新等一系列问题。

弱点:部署之痛

Erlang设计的运行时是直接运行于宿主机上的,当第一次启动Erlang VM, 会随之启动一个epmd进程来负责集群结点之间的通信。这样的设计与容器化的部署方案格格不入,导致很难在一个宿主机上运行两个位于不同集群的Erlang容器。

弱点:数据库之伤

OTP中的mnesia是Erlang技术栈标配的高性能分布式内存数据库,支持对原生erlang term的透明存取,就单一的Erlang系统而言,mnesia的易用性和性能都是不错的。但是,在一个较复杂的云端系统中,它存在下面几个劣势:

  • 定位过于专一,除了erlang外,几乎找不到其他编程语言可用的客户端,只能通过erlang代码代理访问,导致开发成本高
  • 本身太小众,云厂商不会提供基于mnesia的SasS服务,只能自建,而且mnesia的数据分片功能对网络稳定性有很高的要求,导致运维成本高
  • 未对数据进行压缩存储,当数据量上去后,会消耗大量内存,导致资源成本高

现在,我们已从mnesia全面切换到了redis。


[1]这里的“进程”指的是由Erlang VM负责调度的轻量级进程,而不是由内核调度的OS原生进程

[2]《云计算十字真言及其在小博无线的实践》(https://yq.aliyun.com/articles/62686) 一文详细介绍了“漂移上线”的设计思路以及一种具体的实现方法

目录
相关文章
|
6月前
|
消息中间件 Java Linux
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
|
6月前
|
缓存 NoSQL PHP
【PHP开发专栏】PHP缓存机制与实现
【4月更文挑战第29天】本文介绍了PHP缓存的基本概念、策略及实现方式。PHP缓存包括应用缓存、Web服务器缓存、数据库缓存和分布式缓存,常见策略有缓存预热、更新和懒加载。PHP的缓存实现包括文件缓存、APC、OPcache、Memcached和Redis。最佳实践包括缓存热点数据、控制粒度、设置失效策略、保证一致性和确保安全性。文中还提供了一个新闻列表和详情页的缓存实战示例,帮助开发者理解如何在实际项目中应用缓存。
173 1
|
6月前
|
自然语言处理 算法 Java
解锁JDK 12的奇妙之旅:新特性详解
解锁JDK 12的奇妙之旅:新特性详解
50 1
|
缓存 负载均衡 算法
我佛了!Java开发者福音:并发编程源码剖析+高并发系统搭建
多线程和高并发的关系和区别 “高并发和多线程”总是被人一起提起,给人感觉两者好像相等,实则 高并发 ≠ 多线程 多线程 多线程是Java的特性,因为现在cpu都是多核多线程的,可以同时执行几个任务,为了提高jvm的执行效率,Java提供了这种多线程的机制,以增强数据处理效率。多线程对应的是cpu,高并发对应的是访问请求,可以用单线程处理所有访问请求,也可以用多线程同时处理访问请求。
|
6月前
|
开发框架 前端开发 小程序
分享47个PHP框架源码,总有一款适合您
分享47个PHP框架源码,总有一款适合您
138 0
|
存储 程序员 API
程序员这篇文章很重要!放弃FastDFS,拥抱MinIO的7大理由
目前可用于文件存储的网络服务选择也有不少,好比阿里云OSS、七牛云、腾讯云等等,可是收费都有点小贵。为了帮公司节约成本,以前一直是使用FastDFS做为文件服务器,准确的说是图片服务器。直到我发现了MinIO,我决定放弃FastDFS。
1094 1
|
JavaScript 前端开发 Shell
NodeJS 多线程发展史
在开始了解多线程之前先来了解一下程序任务按照性能的分类,从性能方面来看,计算机程序主要分为两个维度,CPU密集型(也叫计算密集型)和UO密集型。
285 0
|
存储 Oracle 关系型数据库
PHP开发和运行环境是什么意思?底层原理是什么?
PHP开发和运行环境是什么意思?底层原理是什么?
209 0
|
开发者
开源软件项目是什么意思?底层原理是什么?
开源软件项目是什么意思?底层原理是什么?
326 0
|
监控 调度 Ruby
【Ruby高级技术】在项目中使用多线程之后的一系列问题解决方案-同步控制、异常处理、死锁处理
【Ruby高级技术】在项目中使用多线程之后的一系列问题解决方案-同步控制、异常处理、死锁处理
179 0