Erlang开发及应用.ppt
Erlang开发及应用,What is Erlang?,ERicsson LANGuage?函数式编程语言(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).34 main()-5 io:format(hello world!n).编译:$erlc hello.erl运行:$erlEshell V5.7.1(abort with G)1 hello:main().hello world!ok,Erlang Hello World CONT,1-module(hello).声明模块名称,其必须和文件名一致.模块是Erlang项目中代码组织的基本方式.2-compile(export_all).指明编译选项,export_all 用来导出所有本模块中的函数,exported function是模块的接口,其他模块只能调用exported function4 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,roothost,IsAtombinary-reference-make_ref(),一个随机值fun-fun()-some_expr endport-与外部应用进行交互的接口pid-process identifier,用来操作process 2种复合类型tuple-foo,male,28,china,list-ip,any,port,1234,binary,Erlang 语法 CONT,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),Erlang 语法 CONT,Binary匹配使用binary可以轻松的实现二进制协议.(1)解析IP包:-define(IP_VERSION,4).-define(IP_MIN_HDR_LEN,5).DgramSize=size(Dgram),case Dgram of when HLen=5,4*HLen=OptsLen=4*(HLen-?IP_MIN_HDR_LEN),=RestDgram,Erlang 语法 CONT,(2)自定义协议假如我们定义了一个协议,前2 bytes(16位)标记消息体的长度,后面为消息体,最后为占用1个byte的结尾符0 xef,示意图如下:-length-payload-ef|-2-|-Length-|-1-|(单位byte)则对应的binary匹配表达式如下:.Packet=.case Packet of-body,PayLoad;_-error,invalid_packetend.,Erlang 语法 CONT,序列化与反序列化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 语法 CONT,函数 一切皆函数,每个调用都有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 语法 CONT,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 语法 CONT,发送Message!基于消息通信,No Lock!No Shared Memroy!Pid!msg,hello,I love erlang 向Pid(本地或远程主机)代表的进程发送消息receive,1,阻塞等待任意消息:receive Msg-okend3,等待消息,超时为5 sec:receive Msg-okafter 5000-timeoutend,2,实现sleep:receiveafter Time-okend4,检测是否存在消息:receive SomeMsg-existafter 0-no_existend,Erlang 并发,关于Process每个Process拥有一个mailbox,保存消息 Processes之间通过发送异步Message进行交互,无共享状态轻量,兼有OS Process的隔离及OS Thread的高效Process具有自己Stack,Heap,GCProcess可以位于Local,也可以位于Remote MachineProcess能够进行多种形式的管理及控制(link,monitor,exit signal)Process为erlang高并发,高容错,分布式的基础并发Process数:default 32768,max 268435456,Erlang 并发 CONT,创建Processspawn(Fun),比如 spawn(fun()-io:format(im pn,self()end).im spawn(Mod,Fun,Args),比如 spawn(io,format,im pn,self().im spawn_link,spawn_opt,spawn_monitor.销毁Process进程内部调用 exit(Reason),比如 exit(normal),正常退出进程内部发生异常导致程序退出其他进程调用 exit(PidBeTerminate,Reason),Erlang 并发 CONT,基于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)loopin client_process:process protocol,close socket.,Erlang 并发 CONT,使用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 分布式 CONT,rpc 模块可以在其他Node上执行操作slave,remsh,remote shell等方式启动,连接Erlang NodeErlang中进程具有位置透明性通过message及receive表达式,轻松实现同步or异步,timeout等网络通信中多种机制Erlang本身提供tcp,udp等常规的网络编程方式使用Erlang内建分布式机制,可以快速开发多种应用,也可以基于socket开发各种专有应用,Erlang 分布式 CONT,Erlang 分布式 CONT,节点A2连接节点B2步骤Node A2,B2启动,绑定一个本机端口,并注册到本机的epmd(default port 4396)A2连接HostB epmd,请求获取B2节点的绑定端口HostB epmd将B2的bind port及dist协议版本等信息返回给A2A2与B2协商,建立tcp连接,如果连接成功,维护一个tick,来定期检测B2节点A2与B2节点之间的消息,通过此连接进行发送,Erlang OTP,OTP(Open Telecom Platform),其定义了一系列项目开发中需要的模式及部署升级策略,为提高开发效率,构建高效,稳定系统提供了巨大的帮助。同最初时的专有电信平台应用已没有太多关系当前系统都是采用OTP进行开发Erlang中各种lib都是基于OTP开发可以理解成某种轻量的框架,或者具体化的设计模式behaviours包含:application,supervisor,gen_server,gen_fsm,gen_eventapplication,release,release handling提供应用的部署,升级,回退等实现,Erlang OTP CONT,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 Drivershared library(SO in Unix,DLL in Windows),影响Erlang虚拟机稳定性(不推荐)Port dirvers-提供c封装,运行在erlang虚拟机内部C Nodes 遵照erlang的交互协议,使用c实现的一个erlang nodeJinterface提供一系列与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 代码片段 CONt,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:sn,Issue)after 1000-io:format(receive issue time outn)end.调用:$erl-sname server(serverlitao)1 issue:server().true$erl-sname client(clientlitao)1 issue:client(serverlitao).server issue:Ubuntu 9.04 n l,产品开发流程,架构设计单台 or 分布式?Master-Slave or Grid?Monitor,Failover,Net Comunication,Database,Replica.OTP Behaviourhow many application?use supervisor,gen_server,gen_fsm,gen_eventCoding,及单元测试用例.每个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官方网站Erlang China Erlang MailistErlang PlanetErlang非业余研究Erlang Display,开源项目,ejabberd-the Erlang Jabber/XMPP daemon RabbitMQ-AMQP serverCouchDB-schema-free document databaseTsung-multi-protocol distributed load testing Scalaris-distributed key-value storeDisco-MapReduce Framework Mochiweb-Powerful Http Server Tookit自己动手发起erlang开源项目!,案例,AXD301 高并发的电信交换机99.9999999%可靠性(3ms 故障/年)超过100万行Erlang代码软实时系统 高容错,案例,WEB IM后台(mochiweb)7+百万活跃用户100 serverajax+comet(long-polling),更多应用,