Erlang Supervisor #
一、Supervisor概述 #
supervisor是Erlang/OTP中用于监控和重启子进程的行为,是构建容错系统的核心。
1.1 特点 #
- 监控子进程
- 自动重启
- 监督树结构
- 容错机制
二、基本结构 #
2.1 完整示例 #
erlang
-module(my_supervisor).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
Children = [
#{id => my_server,
start => {my_server, start_link, []},
restart => permanent,
shutdown => 5000,
type => worker,
modules => [my_server]}
],
{ok, {#{strategy => one_for_one, intensity => 1, period => 5}, Children}}.
三、监督策略 #
3.1 one_for_one #
erlang
init([]) ->
{ok, {#{strategy => one_for_one, intensity => 1, period => 5}, []}}.
只重启崩溃的子进程。
3.2 one_for_all #
erlang
init([]) ->
{ok, {#{strategy => one_for_all, intensity => 1, period => 5}, []}}.
重启所有子进程。
3.3 rest_for_one #
erlang
init([]) ->
{ok, {#{strategy => rest_for_one, intensity => 1, period => 5}, []}}.
重启崩溃进程及其后的所有进程。
3.4 simple_one_for_one #
erlang
-module(dynamic_supervisor).
-behaviour(supervisor).
-export([start_link/0, start_child/1, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
start_child(Args) ->
supervisor:start_child(?MODULE, [Args]).
init([]) ->
ChildSpec = #{id => worker,
start => {my_worker, start_link, []},
restart => temporary,
shutdown => 5000,
type => worker,
modules => [my_worker]},
{ok, {#{strategy => simple_one_for_one, intensity => 10, period => 60}, [ChildSpec]}}.
四、子进程规格 #
4.1 规格字段 #
erlang
#{id => ChildId,
start => {Module, Function, Args},
restart => Restart,
shutdown => Shutdown,
type => Type,
modules => Modules}
4.2 restart选项 #
| 选项 | 说明 |
|---|---|
permanent |
总是重启 |
transient |
异常退出时重启 |
temporary |
从不重启 |
4.3 shutdown选项 #
| 选项 | 说明 |
|---|---|
brutal_kill |
强制杀死 |
infinity |
无限等待 |
| 整数 | 等待毫秒数 |
4.4 type选项 #
| 选项 | 说明 |
|---|---|
worker |
工作进程 |
supervisor |
监督者 |
五、强度限制 #
5.1 intensity和period #
erlang
{ok, {#{strategy => one_for_one, intensity => 5, period => 60}, Children}}
在period秒内最多重启intensity次。
5.2 超过限制 #
超过限制时,监督者自身退出。
六、监督树 #
6.1 多层监督 #
erlang
-module(top_supervisor).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
Children = [
#{id => server_sup,
start => {server_supervisor, start_link, []},
type => supervisor},
#{id => worker_sup,
start => {worker_supervisor, start_link, []},
type => supervisor}
],
{ok, {#{strategy => one_for_one, intensity => 1, period => 5}, Children}}.
6.2 主监督者 #
erlang
-module(main_supervisor).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
Children = [
#{id => cache_server,
start => {cache_server, start_link, []},
restart => permanent},
#{id => db_connection_pool,
start => {pool_supervisor, start_link, []},
type => supervisor}
],
{ok, {#{strategy => rest_for_one, intensity => 5, period => 60}, Children}}.
七、动态子进程 #
7.1 添加子进程 #
erlang
start_child(Supervisor, ChildSpec) ->
supervisor:start_child(Supervisor, ChildSpec).
7.2 终止子进程 #
erlang
terminate_child(Supervisor, ChildId) ->
supervisor:terminate_child(Supervisor, ChildId).
7.3 删除子进程 #
erlang
delete_child(Supervisor, ChildId) ->
supervisor:delete_child(Supervisor, ChildId).
八、实际应用 #
8.1 应用监督者 #
erlang
-module(app_supervisor).
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
Children = [
#{id => config_server,
start => {config_server, start_link, []},
restart => permanent,
shutdown => 5000},
#{id => db_pool,
start => {db_pool_supervisor, start_link, []},
type => supervisor},
#{id => api_server,
start => {api_server, start_link, []},
restart => permanent,
shutdown => 10000},
#{id => background_worker_sup,
start => {worker_supervisor, start_link, []},
type => supervisor}
],
{ok, {#{strategy => rest_for_one, intensity => 5, period => 60}, Children}}.
8.2 连接池监督者 #
erlang
-module(pool_supervisor).
-behaviour(supervisor).
-export([start_link/1, init/1]).
start_link(Size) ->
supervisor:start_link({local, ?MODULE}, ?MODULE, [Size]).
init([Size]) ->
Children = [
#{id => {connection, I},
start => {connection_worker, start_link, []},
restart => permanent,
shutdown => 5000}
|| I <- lists:seq(1, Size)],
{ok, {#{strategy => one_for_one, intensity => Size, period => 60}, Children}}.
九、总结 #
本章学习了:
- Supervisor概述
- 基本结构
- 监督策略
- 子进程规格
- 强度限制
- 监督树
- 动态子进程
- 实际应用
准备好学习Application了吗?让我们进入下一章。
最后更新:2026-03-27