【摘 要】Erlang語言是一種函數(shù)式語言,使用面向并發(fā)的編程方法。Erlang與分布式系統(tǒng)天性互相吻合,決定了使用Erlang開發(fā)分布式系統(tǒng)具有得天獨(dú)厚的優(yōu)勢。本文主要介紹了Erlang語言的來源和特性,以及如何使用Erlang進(jìn)行分布式編程,并分析了Erlang語言的應(yīng)用前景。
【關(guān)鍵詞】Erlang 分布式 并發(fā) 編程
一、引言
在計(jì)算機(jī)多核化發(fā)展日新月異、“云計(jì)算”“云存儲(chǔ)”異?;鸨慕裉?,一些主流語言面向?qū)ο蟮某绦蛟O(shè)計(jì)語言(C++、JAVA、C#等)對(duì)并發(fā)和分布式程序的支持不是那么得心應(yīng)手。越來越多的鎖、信號(hào)量、線程、同步、互斥之類的概念讓程序日益復(fù)雜,出錯(cuò)概率大增。
為了適應(yīng)并行計(jì)算和分布式應(yīng)用的大趨勢,Java 5.0引入了concurrency庫,C++有了標(biāo)準(zhǔn)化的OpenMP和MPI,微軟發(fā)布了Parrallel FX和MPI.NET等一系列產(chǎn)品。然而,這些亡羊補(bǔ)牢的手段卻不能彌補(bǔ)它們的“先天不足”——即這些語言在創(chuàng)作時(shí)就沒有把并行化的問題放到優(yōu)先的位置上去考慮。而天生面向并發(fā)的Erlang語言很好地解決了這個(gè)問題。
二、Erlang語言簡介
Erlang是一種“函數(shù)式語言(Functional programming,F(xiàn)P)”,使用的是面向并發(fā)編程(COP,Concurrency Oriented Programmi ng)的方法。
1987年,Erlang語言創(chuàng)始人Joe Armstrong在在愛立信做電話網(wǎng)絡(luò)方面的開發(fā)工作時(shí),出于對(duì)高性能和并發(fā)的需求,在Prolog的基礎(chǔ)上增加了并發(fā)處理和錯(cuò)誤恢復(fù),從而誕生了Erlang語言。
Erlang語言非常有特色,并發(fā)、分布、容錯(cuò)貫穿于程序的始終,具有許多與其它語言不同的特性:
(一)跨平臺(tái)性
Erlang運(yùn)行時(shí)環(huán)境是一個(gè)虛擬機(jī),類似Java虛擬機(jī),這樣的代碼一經(jīng)編譯,同樣可以隨處運(yùn)行。當(dāng)然,如果你需要更高效的話,字節(jié)代碼也可以編譯成本地代碼運(yùn)行。
(二)并發(fā)性
Erlang可以非常快地創(chuàng)建和銷毀進(jìn)程,一個(gè)Erlang程序可以由多達(dá)幾百萬個(gè)超輕量級(jí)的進(jìn)程組成,這些進(jìn)程可以運(yùn)行于單處理器、多核處理器或者處理器網(wǎng)絡(luò)上。Erlang進(jìn)程之間高度隔離,沒有共享任何數(shù)據(jù),只能通過消息傳遞來進(jìn)行交互,并且這種消息傳遞也是非常迅捷的。
消除了共享內(nèi)存以及進(jìn)程之間通過消息進(jìn)行通信是Erlang最明顯的優(yōu)勢之一,這一特點(diǎn)為進(jìn)行并行與分布式應(yīng)用的開發(fā)提供了非常好的基礎(chǔ)。
(三)分布式
Erlang被設(shè)計(jì)用于運(yùn)行在分布式環(huán)境下。一個(gè)Erlang虛擬機(jī)作為一個(gè)Erlang節(jié)點(diǎn)。一個(gè)分布式Erlang系統(tǒng)是由多個(gè)Erlang節(jié)點(diǎn)組成的網(wǎng)絡(luò)。使用Erlang來編寫分布式應(yīng)用要簡單的多,因?yàn)樗姆植际綑C(jī)制是透明的:對(duì)于程序來說并不知道自己是在分布式運(yùn)行。
(四)健壯性
Erlang可以說是一門為健壯而生動(dòng)語言。它不像其它語言一樣假設(shè)不會(huì)發(fā)生錯(cuò)誤,而是假定錯(cuò)誤隨時(shí)可能發(fā)生,并隨時(shí)準(zhǔn)備修正錯(cuò)誤。
在一個(gè)分布式系統(tǒng)中,如果一個(gè)進(jìn)程出錯(cuò),讓這個(gè)進(jìn)程自己修復(fù)錯(cuò)誤有時(shí)并不可行,有時(shí)節(jié)點(diǎn)可能徹底崩潰(死機(jī)),因此將錯(cuò)誤交給其他進(jìn)程去處理是更恰當(dāng)?shù)倪x擇。
Erlang錯(cuò)誤偵測的工作機(jī)制正是如此,通過進(jìn)程間的相互“鏈接”來實(shí)現(xiàn)進(jìn)程監(jiān)控(這些進(jìn)程可以運(yùn)行于不同節(jié)點(diǎn)之上)機(jī)制,將錯(cuò)誤進(jìn)行分層處理,從而實(shí)現(xiàn)構(gòu)造“容錯(cuò)系統(tǒng)”。Erlang引入了“速錯(cuò)(Fail fast)”的理念,在一個(gè)進(jìn)程出錯(cuò)時(shí)不會(huì)試圖自行處理,而是直接退出,并發(fā)出錯(cuò)誤消息讓其他進(jìn)程進(jìn)行錯(cuò)誤處理、故障恢復(fù)等工作。
(五)軟實(shí)時(shí)性
Erlang支持可編程的“軟”實(shí)時(shí)系統(tǒng),這種系統(tǒng)需要反應(yīng)時(shí)間在毫秒級(jí)。而在這種系統(tǒng)中,長時(shí)間的垃圾收集(garbage collection)延遲是無法接受的,因此Erlang使用了遞增式垃圾收集技術(shù)。
(六)熱部署(Hot swap)
有些系統(tǒng)是不能夠由于軟件維護(hù)而停止運(yùn)行的。Erlang允許程序代碼在系統(tǒng)運(yùn)行中被修改。舊第代碼能被逐步淘汰而后被新代碼替換。在此過渡期間,新舊代碼是共存的。這也使得安裝bug補(bǔ)丁、系統(tǒng)升級(jí)而不干擾系統(tǒng)運(yùn)行成為了可能。
(七)遞增式代碼裝載
用戶能夠控制代碼如何被裝載的細(xì)節(jié)。在嵌入式系統(tǒng)中,所有代碼通常是在啟動(dòng)時(shí)就被完全裝載。而在開發(fā)系統(tǒng)中,代碼是按需裝載的,甚至在系統(tǒng)運(yùn)行時(shí)被裝載的。如果測試到了未覆蓋的bug,那么只有具有bug的代碼需要被替換。
(八)外部接口
Erlang進(jìn)程與外部世界之間的通訊機(jī)制與Erlang進(jìn)程之間相同的消息傳送機(jī)制相同。這種機(jī)制被用于和操作系統(tǒng)通訊、與其它語言編寫的程序交互。如果出于高效率的需要,這種機(jī)制的一個(gè)特殊版本也允許例如C程序這樣的代碼直接鏈接到Erlang運(yùn)行時(shí)系統(tǒng)中來。
三、Erlang語言的分布式編程
(一)分布式系統(tǒng)的特性
George Coulouris認(rèn)為:分布式系統(tǒng)是由位于網(wǎng)絡(luò)中的一些計(jì)算機(jī)組成的系統(tǒng),這些網(wǎng)絡(luò)中的計(jì)算機(jī)之間只能通過傳遞消息來進(jìn)行溝通和協(xié)調(diào)。Andrew S.Tanenbaum說:一個(gè)分布式系統(tǒng)是一些獨(dú)立計(jì)算機(jī)的集合,但是對(duì)這個(gè)系統(tǒng)的用戶來說,系統(tǒng)就像一臺(tái)計(jì)算機(jī)一樣。
盡管分布式系統(tǒng)還沒有一個(gè)公認(rèn)令人滿意的定義,但是所有分布式系統(tǒng)都有以下兩個(gè)特點(diǎn):一、系統(tǒng)的各個(gè)節(jié)點(diǎn)(計(jì)算機(jī))是相互獨(dú)立的;二、各個(gè)節(jié)點(diǎn)之間只能通過消息傳遞來進(jìn)行溝通和協(xié)調(diào)??梢钥吹?,分布式系統(tǒng)的這兩個(gè)特點(diǎn)也正是Erlang程序的特點(diǎn):各進(jìn)程相互獨(dú)立,且只能通過消息傳遞來進(jìn)行交互。
Erlang與分布式系統(tǒng)天性互相吻合,決定了使用Erlang開發(fā)分布式系統(tǒng)具有得天獨(dú)厚的優(yōu)勢。Erlang天生面向并發(fā),在Erlang開發(fā)的分布式系統(tǒng)增加和刪除節(jié)點(diǎn)非常簡便,具有良好的伸縮性。
(二)Erlang語言分布式編程的兩種基本模型
1. 分布式Erlang
這種模型用于在一個(gè)緊密耦合的計(jì)算機(jī)集群上編寫程序,幾乎不需要額外操作,一切就像在單節(jié)點(diǎn)編程時(shí)一樣:可以在任何一個(gè)節(jié)點(diǎn)創(chuàng)建進(jìn)程,所有的消息傳遞和錯(cuò)誤處理原語都可以照搬。分布式Erlang運(yùn)行于一個(gè)可信任的環(huán)境中——因?yàn)槿魏喂?jié)點(diǎn)都可以運(yùn)行其他節(jié)點(diǎn)上的操作,這就需要一個(gè)高度信任的網(wǎng)絡(luò)環(huán)境。
2. 基于套接字的分布式應(yīng)用
使用TCP/IP套接字,可以編寫運(yùn)行在非信任環(huán)境中的分布式應(yīng)用程序。這種編程模型的功能比分布式Erlang要弱一些,但是卻更加可靠。
四、Erlang語言應(yīng)用前景
Erlang已經(jīng)有二十多年歷史,利用它也成功地實(shí)現(xiàn)了一批項(xiàng)目,例如:Facebook用它重寫了超大型聊天系統(tǒng);Amazon用它開發(fā)了SimpleDB云存儲(chǔ)系統(tǒng);Yahoo!用它開發(fā)了Deliciou2.0……但是,Erlang迄今為止還是一門小眾語言。
Erlang至今未能廣泛應(yīng)用既有傳統(tǒng)程序員固有的面向?qū)ο缶幊趟季S難以適應(yīng)COP編程模式的原因,也有Erlang語言本身語法“怪異”,難以學(xué)習(xí)和理解等方面的原因。
除了Erlang,還有其它一些面向并發(fā)的編程語言,例如Scala、Go、F#等。這些語言各有特點(diǎn),很難分出高下。盡管不能斷定Erlang是不是在并行領(lǐng)域是最優(yōu)的語言,但至少目前來說Erlang是比較好的選擇。Erlang憑借20多年的發(fā)展經(jīng)驗(yàn),在支持高并發(fā)、濃縮性和數(shù)據(jù)的持續(xù)性存儲(chǔ)都有相當(dāng)多的成熟庫(OTP)和開源軟件,使得它有極高的實(shí)用價(jià)值。此外,Erlang還有非常活躍和成熟的社區(qū)為開發(fā)者解疑釋惑。
目前,隨著對(duì)高并發(fā)、分布部署、持續(xù)服務(wù)的需求日益增加,以及多核CPU的全面普及,Erlang必將得到越來越多廣泛的應(yīng)用。
參考文獻(xiàn):
[1]Armstrong Joe. Programming erlang [M]. Pragmatic Bookshelf, 2007.
[2]Armstrong Joe. A history of erlang [C]. Proceedings of the third ACM SIGPLAN conference on History of programming languages. ACM, 2007:6-1.
[3]Vinoski Steve. Concurrency and message passing in erlang [J]. 2012.
[4]Armstrong Joe, Virding Robert, Wikstr Claes, Williams Mike. Concurrent programming in erlang [J]. 1996.
[5]J?rleberg Anders, Nilsson Kim. Go, f# and erlang [J]. 2012.
[6]陳寅秋. Erlang——一種支持大規(guī)模并發(fā)處理的高可靠性編程語言 [J]. 電腦與電信, 2009, 11: 030.