1 / 34

Erlang开发及应用

Erlang开发及应用. litaocheng@gmail.com. What is Erlang?. ER icsson LANG uage? 函数式编程语言(FP) 面向并发(OC),基于消息 Ericsson创建, 最初用于电信系统开发 成熟, 稳定, 具有20多年历史 适于电信系统, 分布式系统, 高并发服务器 Open Source, 跨平台, GC        不适于底层系统开发. History. 1980s Ericsson实验室思考如何轻松开发电信系统应用 1987年左右, Erlang浮出水面 1989年JAM虚拟机C语言实现 

laszlo
Download Presentation

Erlang开发及应用

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Erlang开发及应用 litaocheng@gmail.com

  2. What is Erlang? • ERicssonLANGuage? • 函数式编程语言(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]). 34 main() -> 5    io:format("hello world!~n"). 编译:  $ 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("hello world!~n"). 为函数体(body),包含Erlang表达式,这里调用io模块的format函数在默认输出中打印"hello world!" 在上面的运行结果中,最后有一个"ok",这是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 - <<"some text">> • reference - make_ref(),一个随机值 • fun - fun() -> some_expr end • port - 与外部应用进行交互的接口 • pid - process identifier, 用来操作process      2种复合类型 • tuple - {foo, male, 28, china, <<"i love erlang">>}  • list - [{ip, any}, {port, 1234}, binary]

  8. Erlang 语法 CON'T • Pattern Match     语言层级的模式匹配, 代码更加简洁.     适用于函数调用, case, receive, try表达式及 "="操作     case Value of        N when is_integer(N) -> N;        _ when is_list(Value) -> list_to_integer(Value)     end •  变量 • 大写字母或 "_" 开头, 只能包含数字,字母,"_", "@". • 如 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 "!"      基于消息通信,No Lock! No Shared Memroy!      Pid ! {msg, "hello, I love erlang"}      向Pid(本地或远程主机)代表的进程发送消息 • receive 2,实现sleep: receive after Time ->     ok end 4,检测是否存在消息: receive      SomeMsg -> exist after 0 ->       no_exist end 1, 阻塞等待任意消息: receive      Msg -> ok end 3,等待消息,超时为5 sec: receive       Msg -> ok after 5000 ->      timeout 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("i'm ~p~n", [self()]) end). • i'm <0.33.0><0.39.0> • spawn(Mod, Fun, Args),比如 • > spawn(io, format, ["i'm ~p~n", [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开发各种专有应用

  21. Erlang 分布式 CON'T

  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("/etc/issue"),    Bin.%% start clientclient(ServerNode) ->    true = net_kernel:connect_node(ServerNode),    {issue_server, ServerNode} ! {self(), {get, issue}},    receive        {issue, Issue} ->            io:format("server issue:~s~n", [Issue])    after 1000 ->            io:format("receive issue time out~n")    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 Behaviourhow 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)

  34. 更多应用

More Related