Erlang开发及应用

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    12 Favorites

    Erlang开发及应用 - Presentation Transcript

    1. Erlang 开发及应用 [email_address]
    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("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 - <<&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 开发各种专有应用
    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(&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 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)
    34. 更多应用

    + litaochenglitaocheng, 5 months ago

    custom

    875 views, 12 favs, 0 embeds more stats

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 875
      • 875 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 12
    • Downloads 13
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories