今天细致的看了下supervisor,现在做个总结:
其中,方块代表supervisor process,它的功能很简单,就负责看管它下面的“小弟”(child processes) 并且在必要的时候对某个child process执行restart或者terminate操作;而圆形就代表worker process,它才是真正负责干活的process;特别注意,supervisor process 监控的不一定都是worker process 可以是别的supervisor(如上图)。通过以上方式,我们就可以按照一定层次结构将process管理起来,构建一个强健的容错系统 。
现在我们就看看如何创建一个supervisor:
类似gen_server, gen_event模块,erlang已经把如何创建一个supervisor解耦:分成非功能模块和功能模块。非功能模块是一个叫supervisor的module(后面简称为 S module),功能模块则由各个使用方以callback module形式提供,在callback模块中,你
只需要编写一个init方法供S module回调即可,该init方法指定了将要创建的supervisor的三个属性:
1.重启策略(Restart Strategy)
a. one_for_one
当一个child process挂掉时,它的监控者(supervisor)仅重启该child process,而不会影响其他child process
b.one_for_all
当一个child process挂掉时,它的监控者(supervisor)将会terminate其余所有child process,然后再重启所有child process
c.rest_for_one
当一个child process挂掉时,它的监控者(supervisor)只会terminate在该child process之后启动的process,然后再将这些process 通通重启
d.simple_one_for_one
重启策略与one_for_one相同,唯一的区别是:所有的child process都是动态添加的并且执行同样一份代码(稍后详述)
2.最大重启频率(Maximum Restart Frequency)
该属性的主要目的是为了防止child proces 频繁的terminate-restart,当某个child process超过这个频率,supervisor将会terminate所有的child process然后再terminate掉自己(根据我的测试结果,这个频率的计算是这次重启距离上次重启的的时间间隔)
3.Child Specification
这个属性说白了,就是告诉supervisor,你要监控哪些child process,你该怎么启动这些child process以及如何结束它们等等,该属性的详细格式如下:
{Id, StartFunc, Restart, Shutdown, Type, Modules}
Id = term()
StartFunc = {M, F, A}
Restart = permanent | transient | temporary
Shutdown = brutal_kill | integer()>0 | infinity
Type = worker | supervisor
Modules = [Module] | dynamic
其中:
Id 唯一标示了一个child process; |
StartFunc告诉supervisor如何启动它(即调用哪一个方法),特别要注意的是:1. StartFunc 必须 create a link to the child process(只有这样 supervisor才能够监控到child process,感知它的生死)2.若child process 创建成功,它必须返回 {ok, Child} 或者 {ok, Child, Info},其中Child 为child process的Pid,Info值被supervisor忽略(我一开就在这里栽了跟头,没有按标准格式返回) |
Restart 这个参数用来告诉supervisor,当该child process挂掉时,是否能够重启它,permanent表示永远可以(不管child process是以何种原因挂掉),temporary表示永远不可以(即挂掉了将不再重启),transient 有点特殊,它表示child process若是因为normal或者shutdown原因结束,则不再重启,否则可以restart(ps:Restart参数设置会覆盖Restart Strategy,譬如一个child process的Restart设置为temporary,supervisor的Restart Strategy是one_for_all,那么当其他某个child process挂掉后,将会导致该child process(temporay)被terminate并且不再被重启) |
Shutdown 用来告诉supervisor当它想terminate某个child process该如何terminate,brutal_kill 顾名思义就是很粗鲁,很暴力的结束一个child process(supervisor内部调用exit(ChildPid, kill)方法,注意exit reason为kill的exit signal是不可被捕获的,无论ChildPid是否为system process);整型值TimeOut表示当supervisor想结束一个child process时,它调用exit(ChildPid, shutdow),若在Timout时间范围内supervisor没有收到来自child process的exit signal(因为supervisor linked to child process,所以当child process挂掉时,supervisor会收到一个exit signal),那么supervisor将会调用exit(ChildPid, kill)方法,暴力的terminate child process(这里我突然疑惑了?这样不也是会导致supervisor 收到一个不可捕获的exit signal?);infinity:当你的child process 也是一个supervisor并且你需要terminate,这时你需要将Shutdown参数设置为infinity,从而保证child process(supervisor)能够有充分的时间结束它的supervision tree; |
Type:用来指定child process的类型(worker or superviosr) |
Module: 这个参数我目前还不是很明白,暂且搁置 |
说完了这么多,我们来看一个简单的例子(child process 每5s由它的supervisor重启一次):
worker process
该worker process做的事情很简单,启动时会打印start...,然后暂停5s,最后退出打印一条quit...消息,其中start_link供supervisor调用
supervisor
我们重点看下几个参数的设置:
supervisor重启策略:one_for_one
supervisor最大重启频率:1 / s
child process的StartFunc: tick模块的start_link方法,参数为空
child process的Restart属性:permanent(这个是child process 挂掉后能被重启的关键)
我们看下程序运行效果:
第一行调用supervisor:start_link(my_supervisor, []) 创建一个supervisor(其中my_supervisor是callback module),若成功创建supervisor(它所监控的child process也创建成功),则返回{ok, SupPid}(譬如这里的{ok, <0.34.0>),之后我们就看到屏幕上一直循环打印start.... quit.... 并且每一个pid都不一样,这就说明,当supervisor发现child process挂掉后(不论什么原因,哪怕是正常退出),都会restart child process(你可以尝试把child process的permanent修改为temporary,看看运行结果又是如何)
至此我们已经完成了一个supervisor的例子,别看它简单,但确实构建了一个supervision tree,关于supervisor的更多细节,请参看下列文档:
http://www.erlang.org/doc/design_principles/sup_princ.html
http://www.erlang.org/doc/man/supervisor.html
最后我们在看下:simple_one_for_one,这种Restart Strategy和one_for_one基本相同(即当一个child process挂掉后,仅仅重启该child process 而不影响其他child process),唯一不同的是:simple_one_for_one 只能够动态的添加child process并且所有的child process执行同一份代码 ,我们来看一个例子(来自otp 官方文档)
注意这里的StartFunc: {call, start_link, []} 并不会真正的去启动一个child process,而必须通过调用 supervisor:start_child(Sup, List) 动态添加child process,其中第一个参数Sup是表示你要往哪个supervisor下添加child process,第二个参数用来在创建child process时传递给它(内部调用apply(M, F, A++List))
好了,关于supervisor先就说到这里,若有不对的地方恳请指出!
- 大小: 3.7 KB
- 大小: 16.2 KB
- 大小: 10.9 KB
- 大小: 19.3 KB
- 大小: 12.4 KB
分享到:
相关推荐
3. **容错**:Erlang OTP通过“软实时”系统实现高可用性,它允许错误发生并提供恢复机制,比如监控和链接机制,确保系统的健壮性。 4. **模块化**:OTP包含一组预定义的行为模式(如GenServer、GenEvent、...
Erlang OTP 19_win64是一款专为Windows 64位系统设计的Erlang软件开发工具包,它包含Erlang编程...通过学习和掌握Erlang OTP,开发者可以利用其强大的并发机制和分布式特性,构建出能够应对复杂并发场景的高可靠系统。
OTP是Erlang生态系统的重要组成部分,提供了许多预先设计好的行为模式(如 gen_server、gen_event 和 supervisor),这些模式使得开发者能够快速构建出符合Erlang并发哲学的应用程序。 otp_src_21.3.tar是Erlang ...
3. **Supervisor** 和 **Gen Supervision Tree**:Supervisor 是 OTP 的一部分,负责管理和重启因故障崩溃的进程。通过构建 Gen Supervision Tree,可以创建一个自我修复的系统,确保服务的高可用性。 4. **ETS ...
3. 分布式系统构建:学习如何在Erlang节点间进行通信,以及如何构建分布式应用程序。 4. 并发编程:探讨Erlang进程间的同步和异步通信,以及避免竞态条件和死锁的方法。 5. 容错与恢复:了解Erlang的故障检测和恢复...
10. **编译器和工具链**:Erlang OTP 20.2可能包含了改进的编译器和其他开发工具,如rebar3(一个流行的Erlang构建工具)。 在下载并解压"otp_win64_20.2.exe"后,你可以安装Erlang OTP的这个版本,从而在Windows ...
它包括Erlang虚拟机(BEAM)、进程间通信机制、错误处理工具以及一系列预先设计好的行为模式(Behaviours),如GenServer、GenEvent和Supervisor,这些模式提供了强大的容错和恢复能力。 **2. ERTS - Erlang Run-...
OTP包括了诸如分布式数据库、监控工具、错误处理机制、行为模式(如GenServer、GenEvent和Supervisor)等一系列模块,这些模块帮助开发者实现健壮的系统架构。 RabbitMQ是一个流行的开源消息代理,它基于AMQP...
Erlang OTP(Open Telephony Platform)是Erlang编程语言的一个核心部分,它提供了一套强大的工具和库,用于构建可靠、可扩展和容错的分布式系统。OTP设计原则着重于实现高度并发、容错性和高效能。下面将详细讨论...
Erlang OTP 设计原理涉及到的核心概念包括监督树、行为模式以及应用的设计和管理。Erlang/OTP 提供了一种组织代码的高级原则,它基于进程、模块和目录的层次结构来构建可靠的、可容错的分布式系统。本文档将详细介绍...
书中可能讲解了OTP的设计原则和组件,如GenServer、GenEvent和Supervisor等。 3. **错误处理与容错**:Erlang推崇“let it crash”哲学,鼓励程序在遇到错误时快速失败并重启,而不是尝试修复。书里可能会讨论如何...
此“Erlang-OTP-API 离线查询英文全手册”是Erlang OTP的官方文档,包含了所有API的详细信息,是学习和开发Erlang OTP应用的重要资源。手册内容广泛,包括了以下几个核心部分: 1. **模块和函数**:手册详细列出了...
- **OTP(开放电信平台)**:Erlang OTP是一套库和设计原则,提供了构建可靠系统的框架,包括Mnesia数据库、Event Manager、Supervisor和GenServer等行为模块。 学习Erlang时,你需要掌握以下核心概念: - **BEAM...
OTP(Open Telecommunications Platform)是Erlang编程语言的核心组件之一,主要为构建高可用性、分布式...通过深入学习和熟练运用Erlang OTP,开发者可以创建出具备高可用性和弹性的系统,满足现代互联网服务的需求。
Erlang OTP设计原理是一份深入探讨Erlang/OTP(Open Telecom Platform)框架中设计模式和组织代码原则的文档。Erlang OTP作为Erlang语言的中间件平台,提供了构建可扩展和容错系统的标准方法。 文档开篇就介绍了...
3. 应用和发布(Applications and Releases):在Erlang/OTP中,应用(Application)是一组协同工作的进程和模块的集合,它具有明确的接口和依赖关系。每个应用都有一个回调模块,定义了启动、停止和其他生命周期...
9. 高可用性和容错性:OTP提供了一套名为Supervisor的行为,用于创建和管理进程树,当子进程失败时,Supervisor可以自动重启它们,确保系统的持续运行。 总结起来,"otp_src_21.3.tar.gz"是一个包含Erlang OTP框架...
开发者可以通过阅读源码学习如何在Erlang OTP环境中构建高效、可靠的服务器应用。通过深入理解Timekeeper的架构和实现,我们可以更好地理解Erlang OTP的强大之处,以及如何将其应用于其他需要高精度时间同步的场景。...