SlideShare a Scribd company logo
Erlang 开发及应用 [email_address]
What is Erlang?   ER icsson   LANG uage? 函数式编程语言 (FP) 面向并发 (OC), 基于消息 Ericsson 创建 ,  最初用于电信系统开发 成熟 ,  稳定 ,  具有 20 多年历史 适于电信系统 ,  分布式系统 ,  高并发服务器  Open Source,  跨平台 , GC          不适于底层系统开发
History 1980s Ericsson 实验室思考如何轻松开发电信系统应用 1987 年左右 , Erlang 浮出水面 1989 年 JAM 虚拟机 C 语言实现  1996 年 OTP 项目启动 ,  融合开发经验 ,  提供易用 ,  强大的 Erlang 开发库  1998 年开源 2007 年《 Programming Erlang 》出版 目前版本 Erlang R13B1 (5.7.2)
Erlang 优势 多核 SMP 支持 内建分布式支持 基于轻量进程及消息的高并发模型 代码热替换 开发速度快 ,  高性能 ,  高稳定性 FP 编程 , 代码灵活高效 ,  副作用小 丰富的分析及监控程序 经过商业产品 ,  长久大规模验证 OpenSource,  代码面前无秘密
Erlang Hello World 代码 hello.erl:  1 -module(hello). 2 -compile([export_all]). 3 4 main() -> 5    io:format("hello world!~n"). 编译 :  $ erlc hello.erl 运行 :  $ erl Eshell V5.7.1  (abort with ^G) 1> hello:main(). hello world! ok    
Erlang Hello World CON'T 1 -module(hello). 声明模块名称 , 其必须和文件名一致 . 模块是 Erlang 项目中代码组织的基本方式 . 2 -compile([export_all]). 指明编译选项 ,export_all  用来导出所有本模块中的函数 ,exported function 是模块的接口 , 其他模块只能调用 exported function 4 main() -> 为函数头 (head), 包含函数名称和参数 ,  后紧随一个  '->' 分割符 5    io:format("hello world!~n"). 为函数体 (body), 包含 Erlang 表达式 , 这里调用 io 模块的 format 函数在默认输出中打印 "hello world!" 在上面的运行结果中 , 最后有一个 "ok", 这是 io:format/1 的返回值 , 表示打印成功 ,Erlang 中任何函数都有返回值 .
Erlang  语法 Data Types       8 种基本类型 integer - 4,  -4, 2#100, 16#4, 920828990801238101010.. float - 3.0, 3.5e2, 6.5e-2, (IEEE754 64bit) atom - hello, your_name, root@host, 'IsAtom' binary - <<&quot;some text&quot;>> reference - make_ref(), 一个随机值 fun - fun() -> some_expr end port -  与外部应用进行交互的接口 pid - process identifier,  用来操作 process       2 种复合类型 tuple - {foo, male, 28, china, <<&quot;i love erlang&quot;>>}  list - [{ip, any}, {port, 1234}, binary]
Erlang  语法  CON'T Pattern Match      语言层级的模式匹配 ,  代码更加简洁 .      适用于函数调用 , case, receive, try 表达式及  &quot;=&quot; 操作       case Value of         N when is_integer(N) -> N;         _ when is_list(Value) -> list_to_integer(Value)      end   变量 大写字母或  &quot;_&quot;  开头 ,  只能包含数字 , 字母 ,&quot;_&quot;, &quot;@&quot;. 如  X, Name1, _Phone, _, Host@ 变量分为  Unbound 和 Bound, Unbound 变量只能用在模式匹配中 . 变量 Bound 后 ,Value 就不可修改  变量只能单次赋值 ( 并发及调试考虑 ) N = 3 (ok)  N = 4 ( oops! not match)          
Erlang  语法  CON'T Binary 匹配 使用 binary 可以轻松的实现二进制协议 . (1) 解析 IP 包 : -define(IP_VERSION, 4). -define(IP_MIN_HDR_LEN, 5). ... DgramSize = size(Dgram), case Dgram of <<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16, ID:16, Flgs:3, FragOff:13, TTL:8, Proto:8, HdrChkSum:16, SrcIP:32, DestIP:32, RestDgram/binary>> when HLen >= 5, 4*HLen =< DgramSize -> OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN), <<Opts:OptsLen/binary,Data/binary>> = RestDgram,    
Erlang  语法  CON'T   (2) 自定义协议 假如我们 定义了一个协议 ,  前 2 bytes(16 位 )  标记消息体的长度 ,  后面为消息体 ,  最后为占用 1 个 byte 的结尾符 0xef,  示意图如下 : [--- length ---][--------- payload ------][ef] |------ 2 -------|---------- Length -------|-1-| ( 单位 byte) 则对应的 binary 匹配表达式如下 : ...  Packet = ... case Packet of      <<Len:16,  PayLoad:Len/binary, 16#ef>> ->          {body, PayLoad};      _ ->          {error, invalid_packet} end.    
Erlang  语法  CON'T 序列化与反序列化 Erlang 中序列化非常简单 term_to_binary/1 -  将任意数据转化为二进制序列 binary_to_term/1 -  将编码的二进制数据转化为 Erlang 数据 比如 : Obj = {apple, {price, 2.0}, {origin, shandong}}, Bin = term_to_binary(Obj), Obj = binary_to_term(Bin) CouchDB 中大量使用 erlang 的序列化相关函数,完成数据的存储与加载 .    
Erlang  语法  CON'T 函数       一切皆函数 ,  每个调用都有 return,  函数可以作为基本数      据类型 . 作为返回值 : op_fun('+') ->      fun(N1, N2) -> N1 + N2 end; op_fun('-') ->       fun(N1, N2) -> N1 - N2 end. 作为参数 : > FIsEven = fun(E) -> E band 2#1 =:= 0 end. > lists:filter(FIsEven, [1, 2, 3, 4, 5, 6]). > [2, 4, 6]    
Erlang  语法  CON'T Tail Recursion 尾递归 Erlang 中没有 for, while 关键字 可以利用递归实现循环 在 server 开发中 , 确保使用尾递归 : server_loop(Args) ->      ...some action...      server_loop(Args).  使用尾递归 , 可以消耗很少的内存 , 仅仅是一个地址跳转 . server_loop(Args) ->      ...some action...      server_loop(Args),      other_fun().
Erlang  语法  CON'T   发送 Message &quot;!&quot;       基于消息通信 ,No Lock! No Shared Memroy!       Pid ! {msg, &quot;hello, I love erlang&quot;}       向 Pid( 本地或远程主机 ) 代表的进程发送消息 receive 1,  阻塞等待任意消息 : receive       Msg -> ok end 3, 等待消息 , 超时为 5 sec: receive        Msg -> ok after 5000 ->       timeout end  2, 实现 sleep: receive after Time ->      ok end 4, 检测是否存在消息 : receive       SomeMsg -> exist after 0 ->        no_exist end
Erlang  并发 关于 Process 每个 Process 拥有一个 mailbox ,保存消息  Processes 之间通过发送异步 Message 进行交互 , 无共享状态 轻量 , 兼有 OS Process 的隔离及 OS Thread 的高效 Process 具有自己 Stack, Heap, GC Process 可以位于 Local, 也可以位于 Remote Machine Process 能够进行多种形式的管理及控制 (link, monitor, exit signal) Process 为 erlang 高并发 , 高容错 , 分布式的基础 并发 Process 数 : default 32768, max 268435456
Erlang  并发  CON'T 创建 Process spawn(Fun),  比如 > spawn(fun() -> io:format(&quot;i'm ~p~n&quot;, [self()]) end). i'm <0.33.0> <0.39.0> spawn(Mod, Fun, Args), 比如 > spawn(io, format, [&quot;i'm ~p~n&quot;, [self()]]).  i'm <0.33.0> <0.41.0> spawn_link,  spawn_opt, spawn_monitor ... 销毁 Process 进程内部调用  exit(Reason),  比如  exit(normal),  正常退出 进程内部发生异常导致程序退出 其他进程调用  exit(PidBeTerminate, Reason)  
Erlang  并发  CON'T 基于 Process 的 http server  框架 (one loop process, per conection per process):   setup up listen socket, spawn(listen_process). in listen_process:     while can accept new  client connect          accept ,          spawn(client_process)     loop in client_process:      process protocol,      close socket.       
Erlang  并发  CON'T 使用 Erlang 我们可以 : 以清晰的风格开发高并发的应用   我们将不在受困于 : 线程池的复杂 死锁 , 竞赛的窘迫 内存泄露 局部问题 , 导致的全局崩溃  与跨平台多核 SMP 的格格不入     
Erlang  分布式 Erlang Node 是分布式通讯的基本单元 , 可以位于同一机器  or  多台机器 ,  实现了原语级的节点通讯 Erlang Node  通过  erl -sname Name  or erlang -name Name 启动 ,  同一台机器可以启动多个 Node 每台机器上启动 Erlang Node 时 , 都会启动一个 epmd(Erlang Port Mapper Daemon, port 4396), 用来进行 Node 和 Machine 之间的映射 不同机器的 Node 之间通过 Tcp 连接进行 Message 传输 ( 可以自定义分布式通讯实现 , 如通过 ssh) global 维护一个全局的 Nodes 网络 spawn[_link|_opt] 都具有分布式版本 , 可以再其他节点创建 Process
Erlang  分布式  CON'T rpc  模块可以在其他 Node 上执行操作 slave, remsh, remote shell 等方式启动 , 连接 Erlang Node Erlang 中进程具有位置透明性 通过 message 及 receive 表达式 , 轻松实现同步 or 异步 , timeout 等网络通信中多种机制 Erlang 本身提供 tcp,udp 等常规的网络编程方式 使用 Erlang 内建分布式机制 , 可以快速开发多种应用 , 也可以基于 socket 开发各种专有应用
Erlang  分布式  CON'T
Erlang  分布式  CON'T 节点 A2 连接节点 B2 步骤 Node A2, B2 启动 , 绑定一个本机端口 , 并注册到本机的 epmd(default port 4396) A2 连接 HostB epmd, 请求获取 B2 节点的绑定端口 HostB epmd 将 B2 的 bind port 及 dist 协议版本等信息返回给 A2   A2 与 B2 协商 , 建立 tcp 连接 , 如果连接成功 , 维护一个 tick, 来定期检测 B2 节点  A2 与 B2 节点之间的消息 , 通过此连接进行发送   
Erlang OTP OTP(Open Telecom Platform) ,其定义了一系列项目开发中需要的模式及部署升级策略,为提高开发效率,构建高效,稳定系统提供了巨大的帮助。 同最初时的专有电信平台应用已没有太多关系 当前系统都是采用 OTP 进行开发 Erlang 中各种 lib 都是基于 OTP 开发 可以理解成某种轻量的框架,或者具体化的设计模式 behaviours 包含 :application, supervisor, gen_server, gen_fsm, gen_event application , release , release handling 提供应用的部署,升级,回退等实现
Erlang OTP CON'T Behaviours 通过定义一些简单的 callback 模块实现特定功能 . application  - 定义 application ,实现某种功能,由其他 behaviours 组成 supervisor -  定义一个 supervisor tree ,实现各种策略的任务重启机制 gen_server -  定义一个通用的 server 模型,一个 process loop ,提供同步异步接口 gen_fsm -  实现一个状态机 gen_event -  实现一个 event manager 及 event handler 模型
与其它语言的交互 External App  外部应用崩溃不会影响 Erlang 虚拟机 Ports -  通过 port 与外部应用交互 (stdin/stdout) Erl_Iterface -  提供 c 的封装,方便开发 port 应用 Link in Driver shared library (SO in Unix, DLL in Windows) ,影响 Erlang 虚拟机稳定性(不推荐) Port dirvers - 提供 c 封装,运行在 erlang 虚拟机内部 C Nodes  遵照 erlang 的交互协议, 使用 c 实现的一个 erlang node Jinterface 提供一系列与 Erlang 进行交互的 Java 包
Erlang  代码片段 求某个数的阶乘                     factorial(0) -> 1;          factorial(N) -> N  *  factorial(N-1). 获取远程机器的 issue 信息( linux)         -module(issue).        -compile([export_all]).         %% start server        server() ->             register(issue_server, spawn(fun server_loop/0)).        server_loop() ->             receive                    {From, {get, issue}} ->                   From ! {issue, get_issue()};             _ ->                 ok              end,            server_loop().     
Erlang  代码片段  CON't get_issue() ->     {ok, Bin} = file:read_file(&quot;/etc/issue&quot;),     Bin. %% start client client(ServerNode) ->     true = net_kernel:connect_node(ServerNode),     {issue_server, ServerNode} ! {self(), {get, issue}},     receive         {issue, Issue} ->             io:format(&quot;server issue:~s~n&quot;, [Issue])     after 1000 ->             io:format(&quot;receive issue time out~n&quot;)     end.  调用: $ erl -sname server (server@litao)1> issue:server(). true $ erl -sname client (client@litao)1> issue:client('server@litao'). server issue:Ubuntu 9.04 \n \l     
产品开发流程 架构设计 单台  or  分布式?  Master-Slave or Grid?  Monitor,     Failover, Net Comunication, Database, Replica ... OTP Behaviour how many application? use supervisor, gen_server, gen_fsm, gen_event Coding,  及单元测试用例 .  每个 module 都经过测试 (eunit) 编写系统测试框架,覆盖测试,确保系统正确 (common test) 压力测试,分析性能瓶颈,进行优化 (fprof) 系统上线,监控功能 (ganglia, nagios, monit) 新的功能或需求,重复 2-7
一些工具 appmon - OTP application 监控工具 cover -  erlang 代码覆盖测试 ntop -  显示 Node 中进程信息 (unix top) make - erlang 中的 make 工具 pman - erlang 中进程管理器 tv - ets  和  mnesia  查看器 fprof -  erlang 系统性能分析 common_test - erlang 测试框架 dialyzer -  代码静态分析 debugger -  单步调试工具,基于 (tcl/tk )
学习资源 Erlang 官方网站 http://www.erlang.org/doc  Erlang China  http://www.erlang-china.org/ Erlang Mailist http://www.nabble.com/Erlang-Questions-f14096.html Erlang Planet http://www.planeterlang.org/ Erlang 非业余研究 http://mryufeng.javaeye.com/ Erlang Display  http://erlangdisplay.javaeye.com/
开源项目 ejabberd - the Erlang Jabber/XMPP daemon   RabbitMQ - AMQP server CouchDB - schema-free document database Tsung - multi-protocol distributed load testing   Scalaris - distributed key-value store Disco - MapReduce Framework   Mochiweb - Powerful Http Server Tookit 自己动手发起 erlang 开源项目 !
案例 AXD301  高并发的电信交换机 99.9999999%  可靠性 (~3ms  故障 / 年 ) 超过 100 万行 Erlang 代码 软实时系统  高容错
案例 WEB IM 后台 (mochiweb)   7+  百万活跃用户 ~ 100 server ajax + comet(long-polling)
更多应用

More Related Content

PPTX
Introduction of netty
PPTX
Unix socket
DOC
嵌入式inux應用專題文件-智慧家庭系統
PPT
智慧家庭 簡報
PPT
MPI use c language
PDF
C++工程实践
PDF
深入浅出Netty l.t
DOC
Wbm9000动态库说明L
Introduction of netty
Unix socket
嵌入式inux應用專題文件-智慧家庭系統
智慧家庭 簡報
MPI use c language
C++工程实践
深入浅出Netty l.t
Wbm9000动态库说明L

What's hot (20)

PPTX
Nio trick and trap
PPT
Lysu's Java Socket notes
PDF
系統程式 -- 第 11 章
PPTX
Computer Network 1 TCP/IP
DOCX
系統程式 -- 第 5 章 連結與載入
PDF
Learning python in the motion picture industry by will zhou
PDF
《Python 3.5 技術手冊》第二章草稿
PPTX
Totem协议(SRP/RRP)讲解
PPTX
Hcsm lect-20120913
DOC
Project gps
PDF
COSCUP 2016 - LLVM 由淺入淺
PDF
COSCUP 2014 : open source compiler 戰國時代的軍備競賽
DOC
H264 on rtp
PDF
Juniper ScreenOS 基于Policy的
PPT
network2
PPT
第20讲 帧中继
PDF
Linux firewall
PPT
Go语言: 互联网时代的C
PDF
Android C Library: Bionic 成長計畫
PPT
第14讲 交换机基本操作
Nio trick and trap
Lysu's Java Socket notes
系統程式 -- 第 11 章
Computer Network 1 TCP/IP
系統程式 -- 第 5 章 連結與載入
Learning python in the motion picture industry by will zhou
《Python 3.5 技術手冊》第二章草稿
Totem协议(SRP/RRP)讲解
Hcsm lect-20120913
Project gps
COSCUP 2016 - LLVM 由淺入淺
COSCUP 2014 : open source compiler 戰國時代的軍備競賽
H264 on rtp
Juniper ScreenOS 基于Policy的
network2
第20讲 帧中继
Linux firewall
Go语言: 互联网时代的C
Android C Library: Bionic 成長計畫
第14讲 交换机基本操作
Ad

Viewers also liked (6)

PDF
Couchdb Beijing Openparty
PPT
Erlang游戏开发
PDF
Memcached 剖析
PDF
KISSY Mechanism
PDF
Erlang Practice
PPT
Dialysis dose prescription (the basics) dr ujjawal
Couchdb Beijing Openparty
Erlang游戏开发
Memcached 剖析
KISSY Mechanism
Erlang Practice
Dialysis dose prescription (the basics) dr ujjawal
Ad

Similar to Erlang开发及应用 (20)

PPT
Erlang全接触
PPTX
Erlang分布式系统的的领域语言
PDF
用Erlang构建容错系统
PPT
基于Erlang的
PDF
Erlang不能错过的盛宴
ODP
Erlang培训
PPT
Erlang高级原理和应用
PDF
Erlang在网页游戏开发领域的应用
PPTX
高性能集群服务器(Erlang解决方案)
PPTX
高性能集群服务器Erlang解决方案
PPT
Erlang low cost_clound_computing
PDF
rebar erlang 2
PDF
Inside Erlang Vm II
PPT
Erlang Optimize
PDF
rebar erlang
DOC
Erlang jiacheng
PPTX
当Webgame邂逅erlang
PDF
Python 于 webgame 的应用
DOC
Linux 源代码分析 消息管理
PPT
高性能并发Web服务器实现核心内幕
Erlang全接触
Erlang分布式系统的的领域语言
用Erlang构建容错系统
基于Erlang的
Erlang不能错过的盛宴
Erlang培训
Erlang高级原理和应用
Erlang在网页游戏开发领域的应用
高性能集群服务器(Erlang解决方案)
高性能集群服务器Erlang解决方案
Erlang low cost_clound_computing
rebar erlang 2
Inside Erlang Vm II
Erlang Optimize
rebar erlang
Erlang jiacheng
当Webgame邂逅erlang
Python 于 webgame 的应用
Linux 源代码分析 消息管理
高性能并发Web服务器实现核心内幕

Erlang开发及应用

  • 2. What is Erlang?   ER icsson LANG uage? 函数式编程语言 (FP) 面向并发 (OC), 基于消息 Ericsson 创建 , 最初用于电信系统开发 成熟 , 稳定 , 具有 20 多年历史 适于电信系统 , 分布式系统 , 高并发服务器 Open Source, 跨平台 , GC        不适于底层系统开发
  • 3. History 1980s Ericsson 实验室思考如何轻松开发电信系统应用 1987 年左右 , Erlang 浮出水面 1989 年 JAM 虚拟机 C 语言实现  1996 年 OTP 项目启动 , 融合开发经验 , 提供易用 , 强大的 Erlang 开发库 1998 年开源 2007 年《 Programming Erlang 》出版 目前版本 Erlang R13B1 (5.7.2)
  • 4. Erlang 优势 多核 SMP 支持 内建分布式支持 基于轻量进程及消息的高并发模型 代码热替换 开发速度快 , 高性能 , 高稳定性 FP 编程 , 代码灵活高效 , 副作用小 丰富的分析及监控程序 经过商业产品 , 长久大规模验证 OpenSource, 代码面前无秘密
  • 5. Erlang Hello World 代码 hello.erl: 1 -module(hello). 2 -compile([export_all]). 3 4 main() -> 5    io:format(&quot;hello world!~n&quot;). 编译 :  $ erlc hello.erl 运行 :  $ erl Eshell V5.7.1  (abort with ^G) 1> hello:main(). hello world! ok    
  • 6. Erlang Hello World CON'T 1 -module(hello). 声明模块名称 , 其必须和文件名一致 . 模块是 Erlang 项目中代码组织的基本方式 . 2 -compile([export_all]). 指明编译选项 ,export_all 用来导出所有本模块中的函数 ,exported function 是模块的接口 , 其他模块只能调用 exported function 4 main() -> 为函数头 (head), 包含函数名称和参数 , 后紧随一个 '->' 分割符 5    io:format(&quot;hello world!~n&quot;). 为函数体 (body), 包含 Erlang 表达式 , 这里调用 io 模块的 format 函数在默认输出中打印 &quot;hello world!&quot; 在上面的运行结果中 , 最后有一个 &quot;ok&quot;, 这是 io:format/1 的返回值 , 表示打印成功 ,Erlang 中任何函数都有返回值 .
  • 7. Erlang 语法 Data Types      8 种基本类型 integer - 4,  -4, 2#100, 16#4, 920828990801238101010.. float - 3.0, 3.5e2, 6.5e-2, (IEEE754 64bit) atom - hello, your_name, root@host, 'IsAtom' binary - <<&quot;some text&quot;>> reference - make_ref(), 一个随机值 fun - fun() -> some_expr end port - 与外部应用进行交互的接口 pid - process identifier, 用来操作 process      2 种复合类型 tuple - {foo, male, 28, china, <<&quot;i love erlang&quot;>>}  list - [{ip, any}, {port, 1234}, binary]
  • 8. Erlang 语法 CON'T Pattern Match     语言层级的模式匹配 , 代码更加简洁 .     适用于函数调用 , case, receive, try 表达式及 &quot;=&quot; 操作     case Value of        N when is_integer(N) -> N;        _ when is_list(Value) -> list_to_integer(Value)     end   变量 大写字母或 &quot;_&quot; 开头 , 只能包含数字 , 字母 ,&quot;_&quot;, &quot;@&quot;. 如 X, Name1, _Phone, _, Host@ 变量分为 Unbound 和 Bound, Unbound 变量只能用在模式匹配中 . 变量 Bound 后 ,Value 就不可修改  变量只能单次赋值 ( 并发及调试考虑 ) N = 3 (ok) N = 4 ( oops! not match)         
  • 9. Erlang 语法 CON'T Binary 匹配 使用 binary 可以轻松的实现二进制协议 . (1) 解析 IP 包 : -define(IP_VERSION, 4). -define(IP_MIN_HDR_LEN, 5). ... DgramSize = size(Dgram), case Dgram of <<?IP_VERSION:4, HLen:4, SrvcType:8, TotLen:16, ID:16, Flgs:3, FragOff:13, TTL:8, Proto:8, HdrChkSum:16, SrcIP:32, DestIP:32, RestDgram/binary>> when HLen >= 5, 4*HLen =< DgramSize -> OptsLen = 4*(HLen - ?IP_MIN_HDR_LEN), <<Opts:OptsLen/binary,Data/binary>> = RestDgram,    
  • 10. Erlang 语法 CON'T   (2) 自定义协议 假如我们 定义了一个协议 , 前 2 bytes(16 位 ) 标记消息体的长度 , 后面为消息体 , 最后为占用 1 个 byte 的结尾符 0xef, 示意图如下 : [--- length ---][--------- payload ------][ef] |------ 2 -------|---------- Length -------|-1-| ( 单位 byte) 则对应的 binary 匹配表达式如下 : ... Packet = ... case Packet of     <<Len:16,  PayLoad:Len/binary, 16#ef>> ->         {body, PayLoad};     _ ->         {error, invalid_packet} end.    
  • 11. Erlang 语法 CON'T 序列化与反序列化 Erlang 中序列化非常简单 term_to_binary/1 - 将任意数据转化为二进制序列 binary_to_term/1 - 将编码的二进制数据转化为 Erlang 数据 比如 : Obj = {apple, {price, 2.0}, {origin, shandong}}, Bin = term_to_binary(Obj), Obj = binary_to_term(Bin) CouchDB 中大量使用 erlang 的序列化相关函数,完成数据的存储与加载 .    
  • 12. Erlang 语法 CON'T 函数      一切皆函数 , 每个调用都有 return, 函数可以作为基本数     据类型 . 作为返回值 : op_fun('+') ->     fun(N1, N2) -> N1 + N2 end; op_fun('-') ->      fun(N1, N2) -> N1 - N2 end. 作为参数 : > FIsEven = fun(E) -> E band 2#1 =:= 0 end. > lists:filter(FIsEven, [1, 2, 3, 4, 5, 6]). > [2, 4, 6]    
  • 13. Erlang 语法 CON'T Tail Recursion 尾递归 Erlang 中没有 for, while 关键字 可以利用递归实现循环 在 server 开发中 , 确保使用尾递归 : server_loop(Args) ->     ...some action...     server_loop(Args). 使用尾递归 , 可以消耗很少的内存 , 仅仅是一个地址跳转 . server_loop(Args) ->     ...some action...     server_loop(Args),     other_fun().
  • 14. Erlang 语法 CON'T   发送 Message &quot;!&quot;      基于消息通信 ,No Lock! No Shared Memroy!      Pid ! {msg, &quot;hello, I love erlang&quot;}      向 Pid( 本地或远程主机 ) 代表的进程发送消息 receive 1, 阻塞等待任意消息 : receive      Msg -> ok end 3, 等待消息 , 超时为 5 sec: receive       Msg -> ok after 5000 ->      timeout end 2, 实现 sleep: receive after Time ->     ok end 4, 检测是否存在消息 : receive      SomeMsg -> exist after 0 ->       no_exist end
  • 15. Erlang 并发 关于 Process 每个 Process 拥有一个 mailbox ,保存消息 Processes 之间通过发送异步 Message 进行交互 , 无共享状态 轻量 , 兼有 OS Process 的隔离及 OS Thread 的高效 Process 具有自己 Stack, Heap, GC Process 可以位于 Local, 也可以位于 Remote Machine Process 能够进行多种形式的管理及控制 (link, monitor, exit signal) Process 为 erlang 高并发 , 高容错 , 分布式的基础 并发 Process 数 : default 32768, max 268435456
  • 16. Erlang 并发 CON'T 创建 Process spawn(Fun), 比如 > spawn(fun() -> io:format(&quot;i'm ~p~n&quot;, [self()]) end). i'm <0.33.0> <0.39.0> spawn(Mod, Fun, Args), 比如 > spawn(io, format, [&quot;i'm ~p~n&quot;, [self()]]).  i'm <0.33.0> <0.41.0> spawn_link,  spawn_opt, spawn_monitor ... 销毁 Process 进程内部调用 exit(Reason), 比如 exit(normal), 正常退出 进程内部发生异常导致程序退出 其他进程调用 exit(PidBeTerminate, Reason)  
  • 17. Erlang 并发 CON'T 基于 Process 的 http server 框架 (one loop process, per conection per process):   setup up listen socket, spawn(listen_process). in listen_process:    while can accept new  client connect         accept ,         spawn(client_process)    loop in client_process:     process protocol,     close socket.     
  • 18. Erlang 并发 CON'T 使用 Erlang 我们可以 : 以清晰的风格开发高并发的应用   我们将不在受困于 : 线程池的复杂 死锁 , 竞赛的窘迫 内存泄露 局部问题 , 导致的全局崩溃 与跨平台多核 SMP 的格格不入    
  • 19. Erlang 分布式 Erlang Node 是分布式通讯的基本单元 , 可以位于同一机器 or 多台机器 , 实现了原语级的节点通讯 Erlang Node 通过 erl -sname Name  or erlang -name Name 启动 , 同一台机器可以启动多个 Node 每台机器上启动 Erlang Node 时 , 都会启动一个 epmd(Erlang Port Mapper Daemon, port 4396), 用来进行 Node 和 Machine 之间的映射 不同机器的 Node 之间通过 Tcp 连接进行 Message 传输 ( 可以自定义分布式通讯实现 , 如通过 ssh) global 维护一个全局的 Nodes 网络 spawn[_link|_opt] 都具有分布式版本 , 可以再其他节点创建 Process
  • 20. Erlang 分布式 CON'T rpc 模块可以在其他 Node 上执行操作 slave, remsh, remote shell 等方式启动 , 连接 Erlang Node Erlang 中进程具有位置透明性 通过 message 及 receive 表达式 , 轻松实现同步 or 异步 , timeout 等网络通信中多种机制 Erlang 本身提供 tcp,udp 等常规的网络编程方式 使用 Erlang 内建分布式机制 , 可以快速开发多种应用 , 也可以基于 socket 开发各种专有应用
  • 22. Erlang 分布式 CON'T 节点 A2 连接节点 B2 步骤 Node A2, B2 启动 , 绑定一个本机端口 , 并注册到本机的 epmd(default port 4396) A2 连接 HostB epmd, 请求获取 B2 节点的绑定端口 HostB epmd 将 B2 的 bind port 及 dist 协议版本等信息返回给 A2   A2 与 B2 协商 , 建立 tcp 连接 , 如果连接成功 , 维护一个 tick, 来定期检测 B2 节点  A2 与 B2 节点之间的消息 , 通过此连接进行发送  
  • 23. Erlang OTP OTP(Open Telecom Platform) ,其定义了一系列项目开发中需要的模式及部署升级策略,为提高开发效率,构建高效,稳定系统提供了巨大的帮助。 同最初时的专有电信平台应用已没有太多关系 当前系统都是采用 OTP 进行开发 Erlang 中各种 lib 都是基于 OTP 开发 可以理解成某种轻量的框架,或者具体化的设计模式 behaviours 包含 :application, supervisor, gen_server, gen_fsm, gen_event application , release , release handling 提供应用的部署,升级,回退等实现
  • 24. Erlang OTP CON'T Behaviours 通过定义一些简单的 callback 模块实现特定功能 . application - 定义 application ,实现某种功能,由其他 behaviours 组成 supervisor - 定义一个 supervisor tree ,实现各种策略的任务重启机制 gen_server - 定义一个通用的 server 模型,一个 process loop ,提供同步异步接口 gen_fsm - 实现一个状态机 gen_event - 实现一个 event manager 及 event handler 模型
  • 25. 与其它语言的交互 External App 外部应用崩溃不会影响 Erlang 虚拟机 Ports - 通过 port 与外部应用交互 (stdin/stdout) Erl_Iterface - 提供 c 的封装,方便开发 port 应用 Link in Driver shared library (SO in Unix, DLL in Windows) ,影响 Erlang 虚拟机稳定性(不推荐) Port dirvers - 提供 c 封装,运行在 erlang 虚拟机内部 C Nodes 遵照 erlang 的交互协议, 使用 c 实现的一个 erlang node Jinterface 提供一系列与 Erlang 进行交互的 Java 包
  • 26. Erlang 代码片段 求某个数的阶乘                   factorial(0) -> 1;          factorial(N) -> N * factorial(N-1). 获取远程机器的 issue 信息( linux)        -module(issue).        -compile([export_all]).        %% start server        server() ->             register(issue_server, spawn(fun server_loop/0)).        server_loop() ->             receive                   {From, {get, issue}} ->                   From ! {issue, get_issue()};             _ ->                 ok             end,            server_loop().     
  • 27. Erlang 代码片段 CON't get_issue() ->     {ok, Bin} = file:read_file(&quot;/etc/issue&quot;),     Bin. %% start client client(ServerNode) ->     true = net_kernel:connect_node(ServerNode),     {issue_server, ServerNode} ! {self(), {get, issue}},     receive         {issue, Issue} ->             io:format(&quot;server issue:~s~n&quot;, [Issue])     after 1000 ->             io:format(&quot;receive issue time out~n&quot;)     end. 调用: $ erl -sname server (server@litao)1> issue:server(). true $ erl -sname client (client@litao)1> issue:client('server@litao'). server issue:Ubuntu 9.04 \n \l     
  • 28. 产品开发流程 架构设计 单台 or 分布式? Master-Slave or Grid?  Monitor,     Failover, Net Comunication, Database, Replica ... OTP Behaviour how many application? use supervisor, gen_server, gen_fsm, gen_event Coding, 及单元测试用例 . 每个 module 都经过测试 (eunit) 编写系统测试框架,覆盖测试,确保系统正确 (common test) 压力测试,分析性能瓶颈,进行优化 (fprof) 系统上线,监控功能 (ganglia, nagios, monit) 新的功能或需求,重复 2-7
  • 29. 一些工具 appmon - OTP application 监控工具 cover -  erlang 代码覆盖测试 ntop - 显示 Node 中进程信息 (unix top) make - erlang 中的 make 工具 pman - erlang 中进程管理器 tv - ets 和 mnesia 查看器 fprof -  erlang 系统性能分析 common_test - erlang 测试框架 dialyzer - 代码静态分析 debugger - 单步调试工具,基于 (tcl/tk )
  • 30. 学习资源 Erlang 官方网站 http://www.erlang.org/doc Erlang China http://www.erlang-china.org/ Erlang Mailist http://www.nabble.com/Erlang-Questions-f14096.html Erlang Planet http://www.planeterlang.org/ Erlang 非业余研究 http://mryufeng.javaeye.com/ Erlang Display http://erlangdisplay.javaeye.com/
  • 31. 开源项目 ejabberd - the Erlang Jabber/XMPP daemon RabbitMQ - AMQP server CouchDB - schema-free document database Tsung - multi-protocol distributed load testing Scalaris - distributed key-value store Disco - MapReduce Framework Mochiweb - Powerful Http Server Tookit 自己动手发起 erlang 开源项目 !
  • 32. 案例 AXD301 高并发的电信交换机 99.9999999% 可靠性 (~3ms 故障 / 年 ) 超过 100 万行 Erlang 代码 软实时系统 高容错
  • 33. 案例 WEB IM 后台 (mochiweb)   7+ 百万活跃用户 ~ 100 server ajax + comet(long-polling)