分类:
2008-04-07 11:42:06
erlang当初是为电信系统设计的,电信系统的要求,按照Dacker给出的说法是10个:
* 系统必须处理极大数目的并发活动;
* 动作必须及时在某一个点得到处理,或在一定的时间内得到处理;
* 系统可能分布在数台计算机上
* 系统用于控制硬件
* 软件系统非常庞大
* 系统具备复杂的功能
* 系统应该在很多年间持续运行
* 在不停止系统的前提下进行软件维护(例如重新配置)
* 严格的质量和可靠性需求
* 必须同时对硬件失败和软件错误容错
Joe Armstrong继续针对这些要求分析:
* 并发性--几万人可能同时和交换机交互,因此交换系统具有内在的并发性要求。系统必须能够同时处理数万的并发活动
* 软实时--电信系统中很多操作必须在一个给定的时间段内执行。
o 某些限时的操作是被严格强制的,如果不能再规定的时间间隔内完成,则整个操作将被终止。
o 其他的操作可能只被计时器监视,如果时间到没有完成(计时器事件触发),那么操作将被重复执行
o 编写这样的系统需要非常高效地维护数万个计时器
* 分布式--交换系统内在就是分布式的,系统的结构必须很容易从单节点扩展到多节点的分布式系统
* 硬件交互--交换系统必须控制和监视大量的外设硬件。必须能够编写高效的设备驱动程序,在不同硬件驱动程序之间的上下文切换应该非常高效
* 庞大的软件系统 -- 例如AXE10和AT&T 5ESS有几百万行代码。我们的系统必须能够运行于几百万行的源代码
*
功能复杂性--交换系统功能非常复杂。市场压力鼓励系统的开发和部署需要大量的复杂功能。通常,在没有非常好的理解这些功能之间的交互行为之前,系统就被
部署了。在系统的生命周期中,可能需要用很多方式更改和扩展系统的功能。但是这些更改不能停止系统。
* 持续运作--电信系统必须在很多年内持续运作。软件和硬件维护必须不能停止系统
* 质量需求--交换系统必须在一定的接受层次上容忍错误的发生。电话交换必须极端可靠
*
容错--交换系统应该是“容错的“。意味着我们知道错误会发生,必须设计一种软硬件基础结构,能够处理这些失败,提供一个可接受层次的服务,即使发生错误。
erlang针对这些方面提出的解决方案包括:
总体原则是任何软件(硬件)系统都是会包含错误的,你认识到错误是必然发生的来编写代码。看起来是矛盾的,但却更容易编写出更加强壮的代码。采用的方式是fail-fast(这个我以后解释)
1。采用轻量无共享的process,按照Ulf Winger的说法 Also, the number of processes can
be way larger than 50,000. We consider 30-50,000 processes to be
afairly normal number.有一套完备的process调度机制,最新版本已经支持SMP。
2。无共享有很多意义,包括能够得到极高的并行度和效率提升(Amdahl's
Law).另一方面,无共享也意味着一个process失败不会导致其他process的死锁和失败,实现失败隔离
3。erlang有一套完备的库,其中提供了各种各样的抽象behaviour,特别是supervisor
tree,能够管理其他进程的活动,包括监控、重新启动的策略等等、这是一个树
4。erlang是一种functional 语言,其中很多的行为有利于编写更加可靠的代码,例如single
assignment,就是一次赋植,不再变化,这样在发生错误的时候,你就可以从原先的状态开始,重新启动任务。从可靠性的角度来说,这相当于内存事务。这方面很多组织和大学,包括微软也有研究
5。进程间没有任何共享,所有的通讯都是消息传递,而即使在同一台机器上,erlang也是假设这些消息传递是不可靠的,因此不管是在单台机器还是分布式处理上,你的编程方法和思路没有任何变化,因此非常适合进行分布式运算,并且非常容易伸缩
6。函数性语言以其精确和抽象闻名于世,可以编写复杂且易于维护的项目
7。独立的代码服务进程,可以同时允许统一份代码的不同版本在某一时刻同时运行,最后不停止系统切换到新的版本,也是通过消息处理机制进行处理
8。一套完整的机制进行程序打包、组织,模块更新,应用更新等等
9。erlang的虚拟机是比较高效的,除了函数性语言本身的一些特点(例如GC的很多方面可以更加高效、简洁)外,还支持直接编译到native
code(HiPE)等等