佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > Erlang初學(xué):Erlang的一些特點和個人理解總結(jié)

Erlang初學(xué):Erlang的一些特點和個人理解總結(jié)

熱門標簽:Linux服務(wù)器 網(wǎng)站排名優(yōu)化 AI電銷 鐵路電話系統(tǒng) 百度競價排名 呼叫中心市場需求 服務(wù)外包 地方門戶網(wǎng)站

我對 Erlang 編程理念的理解:以分布式架構(gòu)師的角度寫代碼。

函數(shù)式編程

Erlang 里面的函數(shù)是數(shù)學(xué)里面的函數(shù):必須有返回值。 只要是函數(shù)必然有返回值,函數(shù)是一個過程,以英文的句號為函數(shù)結(jié)束符。 函數(shù)結(jié)束之前的表達式就是該函數(shù)的返回值。 所以這也是在 Erlang 里面的函數(shù)不會看到任何 return 語句的原因。 C++ 等其他語言的函數(shù)和函數(shù)之前可以通過共享變量來實現(xiàn)消息傳遞。 Erlang 里面的函數(shù)不可以,消息的傳遞通過函數(shù)的傳入和傳出。 也只是為什么 Erlang 號稱天生之處并行處理的原因, 因為他們不共享變量,也就不需要加鎖。

很多人聽到函數(shù)式編程都會覺得高大上或者晦澀難懂。 因為函數(shù)是編程沒有 for 循環(huán)語句, 但是在我看來,關(guān)鍵在于會使用【列表推倒】和【尾遞歸】來進行循環(huán)遍歷。 說到函數(shù)式編程就會拿快速排序說事,下面這個示例是 Erlang 版本的快速排序:

復(fù)制代碼 代碼如下:

-module(sort).

-export([qsort/1]).

qsort([]) -> [];
qsort([Pivot | T]) ->
    qsort([X || X - T, X Pivot]
         ++ [Pivot] ++
         qsort([X || X - T, X >= Pivot]).


非常簡潔,[Pivot | T] 就是拿列表的第一個元素當快排中的 Pivot 。
復(fù)制代碼 代碼如下:

[X || X - T, X Pivot]

上式就是【列表推導(dǎo)】, 含義就是找出列表 T 中所有元素小于 Pivot 中的元素組成一個新的列表。 不過,這個例子顯然性能不高,只是一個示例。

很多人一直在鼓吹函數(shù)式語言馬上就要迎來朝陽, 但是在我看來,函數(shù)式編程永遠只能是小眾語言, 這就像當年的 lisp machine ,被鼓吹的天花亂墜還是夭折了。 現(xiàn)在主流的計算機架構(gòu)都是馮諾依曼體系的,并不是最適合函數(shù)式語言的生存土壤。

一切都是常量

沒有變量,也就沒有通過變量共享狀態(tài)導(dǎo)致的資源競爭,也就不需要加鎖。 任何狀態(tài)的變化都是通過函數(shù)的輸入輸出來進行改變, 輕量級進程的狀態(tài)變化也是靠消息傳遞(函數(shù)的輸入輸出)來實現(xiàn)。 這也是為什么有人說函數(shù)式編程適合高并發(fā)的原因,因為他們沒有變量, 一切都是常量。

輕量進程

Erlang 里面有 spawn 函數(shù),可以快速的創(chuàng)建一個 process , 這里的 process 不是操作系統(tǒng)的進程,而是 Erlang 自己的輕量進程。 Erlang 輕量到超乎你想象, 構(gòu)建 kv 數(shù)據(jù)庫的時候,甚至可以對不同的 key 分配給不同的進程。 而且進程的表示單位是 Pid ,只要知道進程的 Pid, 哪怕該進程是在別的機器上面,都可以很輕易的發(fā)送給它。 原因是 Erlang 的【天生自帶RPC通信】和【自帶端口映射】

天生自帶RPC通信

復(fù)制代碼 代碼如下:

ToPid ! Data

ToPid 是接受方進程的id , Data 可以是 Erlang 的任何類型,比如
復(fù)制代碼 代碼如下:

Pid ! {name, "jb51.net"}.

也就是可以直接把任何數(shù)據(jù)結(jié)構(gòu)當成消息發(fā)送,天生自帶 RPC 通信。 (雖然本來 RPC 的含義是“遠程過程調(diào)用”,不過其實反正就是幫你序列化了數(shù)據(jù)結(jié)構(gòu),Erlang 的 ! 操作符也是如此。)

進程端口映射

節(jié)點之間發(fā)消息在代碼里面的表示也還是

復(fù)制代碼 代碼如下:

ToPid ! Data

也就是在寫代碼的時候,根本不用考慮該進程是在哪臺機器上面, 無論是本 Erlang 進程(這里的進程是操作系統(tǒng)級別的進程,不是 Erlang 的輕量進程) 內(nèi), 還是其他機器的進程,都不用管。 這是因為有 epmd 的存在。

Epmd是Erlang Port Mapper Daemon的縮寫,在Erlang集群中相當于dns的作用,供給節(jié)點名稱到端口的查詢辦事,epmd綁定在總所周知的4369端口上。

有了 epmd ,寫分布式程序就好像寫單機程序一樣簡單。

嚴密的模塊化管理

Erlang 的模塊類似 C++ 中的 namespace(命名空間),但是比命名空間更利于高效的軟件工程管理。

在 Erlang 項目源碼中處處可見如下代碼。

復(fù)制代碼 代碼如下:

-module(my_app).
-export([start/2, stop/1]).

-module 指明模塊名,-export 指明導(dǎo)出的函數(shù)。 未被導(dǎo)出的函數(shù)都無法被外界調(diào)用。 從軟件工程上看的話,這樣使得模塊功能和使用方法更加清晰。 使用者只需要關(guān)心如何 -export 里面的函數(shù)即可。 相比較之下 C++ 對這方面特別不規(guī)范,而 Java 通過對類聲明為 public class 指明可以被外界使用, Node.js 也是使用 export 來顯示聲明可以被外界使用的函數(shù)。

行為模式

復(fù)制代碼 代碼如下:

-module(ecomet_app).

-behaviour(application).

%% comment: Application callbacks
-export([start/2, stop/1]).
-behavior(application).

Erlang/otp 里面的【行為模式】概念等價于 OOP 里面的接口概念。 上面代碼示例的意思就是該模塊(ecomet_app)遵守的行為模式是(application)。 剛行為模式需要實現(xiàn)的兩個接口函數(shù)就是 -export([start/2, stop/1]). 。

另一個示例如下是遵守監(jiān)督者(supervisor)行為模式, 實現(xiàn)的一個接口函數(shù)是 -export([init/1]). 。

復(fù)制代碼 代碼如下:

-module(ecomet_sup).

-behaviour(supervisor).

%% Supervisor callbacks
-export([init/1]).

監(jiān)督者機制

Erlang/otp 的天生分布式特性在監(jiān)督機制里面體現(xiàn)的很好, 每一個 otp 應(yīng)用啟動的時候,都是啟動監(jiān)督者(supervisor)和工作者(worker)。 他們的關(guān)系是樹形結(jié)構(gòu),每個工作者的上級都會有監(jiān)督者, 每個監(jiān)督者的上級也可能有監(jiān)督者。 當工作者異常退出的時候,監(jiān)督者會根據(jù)相應(yīng)的參數(shù)決定是否對工作者進行重啟。 如果重啟失敗的話監(jiān)督者也會退出,而更加上層的監(jiān)督者收到信號后會對他們進行重啟等處理。 這個監(jiān)督者機制非常好理解,其實就是 OOP 編程里面的 try ... catch 異常處理機制。 當出現(xiàn)異常的時候一層一層的往上拋出,直到有人重啟。

otp平臺

Erlang 最強大的地方也是最讓我感覺難學(xué)的地方,就是它的 otp 平臺。 各種行為模式, 讓我感覺就像多年以前學(xué)習 MFC 的時候, 感覺很強大,但是卻總是感覺自己被按死在一條特定的軌道上面奔跑, 有種不自由的疲憊感。

代碼熱切換

熱切換也叫熱升級,大部分情況下,如果需要對 C++/Java 程序進程版本升級, 則需要重啟進程。 Erlang 支持熱切換的意思就是可以在運行的時候進行代碼升級。 升級過程不影響進程的運行, 而且在過渡階段新舊版本還可以共存。 是不是碉堡了。這個功能對于那些需要 7x24 高可用的服務(wù)來說簡直就是爽爆了。

Erlang 進程本身可以通過一個類似“后門”的控制臺 erl 來實時的查看狀態(tài), 甚至直接使用控制臺來修改配置等,非常方便,這對于大部分其他語言來說, 簡直就是黑魔法般神奇的存在。

典型缺點

1.文檔太少,出現(xiàn)問題搜索出來的答案也少。
2.Erlang 人才稀缺,招聘不易。
3.動態(tài)語言最典型的就是調(diào)試不易。
4.上手門檻較高。

最后,我只是 Erlang 的入門初學(xué)者, 因為工作中需要使用 ejabberd (Erlang 的開源項目), 從而學(xué)習了 Erlang , 欠缺實戰(zhàn)經(jīng)驗,所以這篇文章標題起為 【Erlang初體驗】。

您可能感興趣的文章:
  • Go/Python/Erlang編程語言對比分析及示例代碼
  • python讀取excel表格生成erlang數(shù)據(jù)
  • Erlang實現(xiàn)的一個Web服務(wù)器代碼實例
  • Erlang中的Record詳解
  • CentOS 6.5源碼安裝Erlang教程
  • ERLANG和PYTHON互通實現(xiàn)過程詳解

標簽:崇左 湘潭 蘭州 黃山 仙桃 銅川 衡水 湖南

巨人網(wǎng)絡(luò)通訊聲明:本文標題《Erlang初學(xué):Erlang的一些特點和個人理解總結(jié)》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    岳阳县| 运城市| 百色市| 张家口市| 嫩江县| 高邮市| 泊头市| 玉田县| 镇平县| 吉林省| 华坪县| 杭锦旗| 无为县| 贵阳市| 游戏| 镇江市| 纳雍县| 比如县| 秀山| 友谊县| 莱西市| 珠海市| 蒙山县| 渝中区| 凭祥市| 曲松县| 中方县| 白山市| 宽城| 同心县| 鹰潭市| 莆田市| 临潭县| 虞城县| 平山县| 从化市| 互助| 黎城县| 龙口市| 武平县| 邛崃市|