Erlang之父Joe Armstrong在描述Erlang的设计要求时,就提到了软件维护应该能在不停止系统的情况下进行。在实践中,我们也因为这种不停止服务的热更新获益良多。那么Erlang是如何做到热更新的呢?这就是本文要讨论的问题。
如何使用Erlang进行热更新?
Erlang有以下几组API提供选择:
%% 第一种热更新方式:
{Module, Binary, Filename} = code:get_object_code(Module),
code:load_binary(Module, Filename, Binary).
%% 第二种热更新方式:
code:purge(Module), code:load_file(Module).
%% 第三种热更新方式:
code:soft_purge(Module) andalso code:load_file(Module).
前面两种从erlang内部实现上来说是一样的,区别是对外接口不同。第三种和前面两种的区别是,如果当前仍有进程占用模块时是否杀掉进程强制更新,第三种则选择不更新。
erlang如何做到热更新的?
erlang VM为每个模块保存了2份代码,当前版本 'current' 和旧版本'old'。当模块第一次被加载时,代码就是'current'版本。如果有新的代码被加载,'current'版本代码就变成了'old'版本,新的代码就成了'current'版本。erlang用两个版本共存的方法来保证任何时候总有一个版本可用,对外服务就不会停止。
如何在热更新的时候不影响进程运行?erlang VM使用code index为代码建立多个索引版本,加载新的代码过程中直到加载完之前,这个新的代码是不可用的。
关于实现机制可以看这篇文章《分析erlang热更新实现机制》,我准备了满满的材料,希望喜欢。
为什么会有purge 代码?
关于热更新,就要看下Code Server模块的源代码\code_server.erl,可能版本不同有略微差别。
1、第一种方式:
code:get_object_code调用了code:mod_to_bin,code:load_binary依次调用了code:do_purge和code:try_load_module。
过程是:code:mod_to_bin ->code:do_purge ->code:try_load_module
2、第二种方式:
code:purge调用了code:do_purge,code:load_file依次调用了code:mod_to_bin和code:try_load_module。
过程是:code:do_purge -> code:mod_to_bin -> code:try_load_module
3、第三种方式:
code:soft_purge调用了code:do_soft_purge,code:load_file依次调用了code:mod_to_bin和code:try_load_module。
过程是:code:do_soft_purge -> code:mod_to_bin -> code:try_load_module
实际上都是这三个过程:
do_purge |
清除旧的模块代码 |
mod_to_bin |
获取模块二进制数据 |
try_load_module |
加载模块 |
那么,热更新时,erlang要清除掉旧的模块数据,再把新的模块数据加载进运行时系统,所以需要purge
再来看下do_purge 和 do_soft_purge 的区别:
使用erlang:check_process_code() 先判断有没有进程在使用模块时,do_purge直接杀了使用模块的进程,而do_soft_purge则返回false
这里应该有同学好奇,为什么要杀了进程,不是说热更新不影响进程运行吗?
前面也提到了erlang VM为模块保存了2份代码,但就是因为只有2份,必须挪出空位装新的代码,就要删掉 'old' 版本的代码,然后把 'current'的代码改成 'old'版本。而删掉了'old' 版本的代码,肯定会导致运行'old' 版本代码的进程执行出现异常。所以,这里就要杀掉运行 'old' 版本代码的进程。
而 erlang对用户暴露了 purge 的方法,实际上是把选择权交给用户,去选择是否杀进程,还是不杀,等到进程运行结束再更新。
最后,如何让进程从 'old'版本切换到最新的版本,可以看这篇文章 《再说说erlang的模块热更新》,我也准备了满满的材料。
参考:http://blog.csdn.net/mycwq/article/details/13290757
分享到:
相关推荐
#### 三、Erlang热部署的实现原理 Erlang 的热部署是基于其模块化的设计思想实现的。每个Erlang程序由一个或多个模块组成,这些模块定义了函数和数据类型。当需要更新代码时,Erlang允许我们重新编译并加载新的模块...
二、Erlang热代码替换 热代码替换是Erlang的一项核心特性,允许在不中断运行服务的情况下更新应用程序代码。它分为三个阶段:停止旧进程、加载新代码和启动新进程。 1. **加载新代码**:使用`code:load_file/1`或`...
本文将深入探讨Erlang中的代码热替换(Code Replacement)技术及其在应用部署中的重要性。 代码热替换是Erlang的一大特色,它允许在不中断运行服务的情况下更新和替换正在运行的代码。这一特性使得Elang系统可以在...
热部署(hot code replacement)是Erlang的一大特色,使得在不停机的情况下更新系统成为可能。这对于维护和升级大规模运行的应用系统尤其重要。 #### 12. IO和并发 Erlang的IO系统与其它语言相比设计得非常适合并发...
2. **热代码替换**:Erlang支持在运行时更新代码,无需停止或重启系统。这使得开发者可以在不影响服务的情况下修复错误或升级功能。 3. **分布式计算**:Erlang节点可以轻松地在多台机器上分布,形成一个集群,节点...
而Erlang的热代码替换功能(hot code swap)允许在不中断服务的情况下更新运行中的代码,这对于持续部署和维护生产系统极其重要。 总之,OTP_win64_22.1是一款适用于Windows 64位系统的OTP版本,包含了构建和运行...
`handle_call/3` 处理同步请求,`handle_cast/2` 处理异步请求,`handle_info/2` 处理来自系统的非预期消息,`terminate/2` 在服务器停止时清理资源,而`code_change/3` 用于处理代码热更新。 在名称服务中,`init/...
4. **热升级(Hot Code Swapping)**:E语言5.0版本继续保持热升级特性,即在不中断服务的情况下更新代码。这对于持续部署和维护生产环境的应用程序极其重要,能最大程度减少系统停机时间。 5. **错误处理与容错**...
Elixir利用Erlang的强项,如分布式计算、热代码升级和容错能力,使得它在构建高可用性服务和大型分布式系统时非常受欢迎。Elixir的语法简洁易读,社区活跃,拥有强大的库和工具支持,如Phoenix框架用于构建Web应用。...