cns*_*nst 3 erlang upgrade real-time erlang-otp on-the-fly
Erlang能够轻松地重新加载代码,而不会丢弃现有的连接,这是一个非常有吸引力的主张,作为该语言的一个特性而广泛使用.
然而,没有明确宣传的是,显然,在删除尚未有机会将执行代码路径从旧切换为新的现有连接之前,您只能进行一次无缝重新加载.
确实如此,或者Erlang/OTP是否具有额外的高级代码重新加载功能,以避免在执行第二次代码重新加载时从上一代中删除执行代码路径?(我的意思是,nginx,例如,可以进行任意次数的二进制升级.)
仅限2个版本.为了说明行为,我使用了小模块:
-module (tver).
-compile([export_all]).
start(Name) ->
Pid = spawn(?MODULE,loop,[]),
register(Name,Pid).
loop() ->
receive
% an internal call won't reload the code. The process keeps
% executing the current version
version -> io:format("version 1~n"), loop();
% an external call will reload the code. The process will use
% the new version if any available in the VM. Notes that it
% will not search in the path if a new version exists!
update -> io:format("update code~n"), ?MODULE:loop();
stop -> io:format("bye...~n")
end.
Run Code Online (Sandbox Code Playgroud)
我在更改版本时更改打印的字符串.现在版本管理在行动:
Erlang/OTP 18 [erts-7.0] [64-bit] [smp:4:4] [async-threads:10]
Eshell V7.0 (abort with ^G)
1> c(tver).
{ok,tver}
2> tver:start(v1).
true
3> v1 ! version.
version 1
version
4> whereis(v1).
<0.39.0>
Run Code Online (Sandbox Code Playgroud)
将版本修改为版本2.c/1命令编译代码并将其加载到VM中
5> c(tver).
{ok,tver}
Run Code Online (Sandbox Code Playgroud)
检查v1进程是否仍在执行版本1
6> v1 ! version.
version 1
version
7> whereis(v1).
<0.39.0>
Run Code Online (Sandbox Code Playgroud)
但是新生成的进程执行版本2.
8> tver:start(v2).
true
9> v1 ! version.
version 1
version
10> v2 ! version.
version 2
version
Run Code Online (Sandbox Code Playgroud)
外部调用强制使用新版本.在现实生活中,你应该做一些验证,比如旧版本,新版本是什么,升级是否可能,是否有一些数据需要适应......
11> v1 ! update.
update code
update
12> v1 ! version.
version 2
version
13> v2 ! version.
version 2
version
14> whereis(v1).
<0.39.0>
15> whereis(v2).
<0.50.0>
Run Code Online (Sandbox Code Playgroud)
制作版本3,编译并重新加载
16> % modif version.
16> c(tver).
{ok,tver}
17> whereis(v1).
<0.39.0>
18> whereis(v2).
<0.50.0>
19> v1 ! version.
version 2
version
20> v1 ! version.
version 2
version
21> v2 ! version.
version 2
version
22> tver:start(v3).
true
23> v2 ! version.
version
version 2
24> v3 ! version.
version 3
version
Run Code Online (Sandbox Code Playgroud)
精细版本的pocesses 1和2正在执行版本2,而过程3正在执行版本3.
现在修改为版本4而不升级进程v1和v2,编译并加载代码.
25> c(tver).
{ok,tver}
26> whereis(v1).
undefined
27> whereis(v2).
undefined
Run Code Online (Sandbox Code Playgroud)
n-2版本不再存在!进程V1和V2已经死亡,尽管他们只是在等待接收块.在真正的OTP系统中,他们的主管会根据他们的重启策略重新启动它们.
28> tver:start(v4).
true
29> whereis(v3).
<0.69.0>
30> whereis(v4).
<0.80.0>
Run Code Online (Sandbox Code Playgroud)
V3和V4进程分别执行版本3和4
31> v3 ! version.
version
version 3
32> v4 ! version.
version 4
version
33>
Run Code Online (Sandbox Code Playgroud)