Erlang 发布版本升级-3 升级发布版本工具讲解

Posted 养码青年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Erlang 发布版本升级-3 升级发布版本工具讲解相关的知识,希望对你有一定的参考价值。

为了不加班,所以程序员一般都会开发一些便捷的工具来提高开发效率,下面就让我来给大家讲讲升级发布版本工具:rebar3_appup_plugin


发布

看前缀就知道,这是一个rebar3的插件,如果对rebar3不熟悉的请先移步去官网看看文档.

那我们先来创建一个rebar3的项目:

rebar3 new release rus_rel && cd rus_rel

接下来,当然是添加这个插件到rebar.confg里面:

{erl_opts, [debug_info]}.

{plugins, [

rebar3_appup_plugin

]}.

{deps, []}.

{relx, [

{release, { rus_rel, "0.1.0" }, [rus_rel,sasl]},

{sys_config, "./config/sys.config"},

{vm_args, "./config/vm.args"},

{dev_mode, false},

{include_erts, false},

{extended_start_script, true}

]}.

记得relx的配置dev_mode要修改为false(此处是演示,正式设置的时候当然是设置profiles里面的设置)

我们需要增加一个gen_server模块

rus_gen_server.erl :

-module(rus_gen_server).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,

terminate/2, code_change/3]).

-export([

start_link/0

]).

-record(state, {}).

start_link() ->

gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->

{ok, #state{}}.

handle_cast(_Info, State) ->

{noreply, State}.

handle_call(_Info, _From, State) ->

{reply, ok, State}.

handle_info(_Info, State) ->

{noreply, State}.

terminate(_Reason, State) ->

{ok, State}.

code_change(OldVsn, State, Extra) ->

io:format("~p ~p ~p~n", [OldVsn, State, Extra]),

{ok, State}.

然后我们在sup里面增加这个模块作为子进程,之后我们会在第二版修改这个进程的内部状态

rus_rel_sup.erl :

-module(rus_rel_sup).

-behaviour(supervisor).

%% API

-export([start_link/0]).

%% Supervisor callbacks

-export([init/1]).

-define(SERVER, ?MODULE).

%%====================================================================

%% API functions

%%====================================================================

start_link() ->

supervisor:start_link({local, ?SERVER}, ?MODULE, []).

%%====================================================================

%% Supervisor callbacks

%%====================================================================

%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}

init([]) ->

Children = [

{rus_gen_server, {rus_gen_server, start_link, []}, permanent, 5000, worker, [rus_gen_server]}

],

{ok, { {one_for_all, 0, 1}, Children} }.

然后我们来发布一个版本:

rebar3 release tar

就这么简单,我们0.1.0的版本就发布好了,接下来运行起来:

$ tar zxf rus_rel-0.1.0.tar.gz // 解压

$ ./bin/rus start // 运行

$ ./bin/rus_rel versions

Installed versions:

* 0.1.0 permanent

ok, 准备工作完成


发布版本升级

接下来我们修改gen_server模块state的数据结构,增加一个字段id

-module(rus_gen_server).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,

terminate/2, code_change/3]).

-export([

start_link/0

]).

-record(state, {id}).

start_link() ->

gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->

{ok, #state{}}.

handle_cast(_Info, State) ->

{noreply, State}.

handle_call(_Info, _From, State) ->

{reply, ok, State}.

handle_info(_Info, State) ->

{noreply, State}.

terminate(_Reason, State) ->

{ok, State}.

code_change(OldVsn, {state}, Extra) ->

io:format("~p ~p ~p~n", [OldVsn, State, Extra]),

{ok, #state{id = 1}}.

然后别忘记了修改版本号

rus_rel.app.src修改vsn为0.2.0

rebar.config的{ rus_rel, “0.1.0” }修改为{ rus_rel, “0.2.0” }

然后先发布一下:

rebar3 release

之后再运行插件:

rebar3 appup generate

这个插件需要之前的版本也在本地目录下面,因为它的运行机制是通过对比两个rel文件夹的beam, 然后根据各自不同自动生成.appup 文件:

%% appup generated for rus_rel by rebar3_appup_plugin (2017/09/18 14:46:53)

{ "0.2.0",

[{ "0.1.0",

[{update,rus_gen_server,{advanced,[]},brutal_purge,brutal_purge,[]}] }],

[{ "0.1.0",

[{update,rus_gen_server,{advanced,[]},brutal_purge,brutal_purge,[]}] }]

}.

然后我们再执行relup 和 打包:

rebar3 relup tar

这样我们就获得了一个带有更新指令的发布,然后将这个发布包发到运行根目录下的releases文件夹下面, 并执行更新命令:

$ ./bin/rus_rel upgrade 0.2.0

Release 0.2.0 not found, attempting to unpack releases/rus_rel-0.2.0.tar.gz

Unpacked successfully: "0.2.0"

Installed Release: 0.2.0

Made release permanent: "0.2.0"

$ ./bin/rus_rel versions

Installed versions:

* 0.2.0 permanent

* 0.1.0 old

ok,整个更新就完成了,你可以attach进去看一下进程的内部状态,发现已经更新了.


appup插件说明

支持功能:

  • 原理:通过对比两个rel文件夹的beam, 然后根据各自不同自动生成.appup 文件.

  • 支持.appup.src 生成.appup 文件.

  • 当gen_server 存在了-state_record(state),插件会自动注入state变更代码到beam里, More info.

  • 支持根据两个版本sup模块init的返回的规格定义不同,生成相应的升级指令

  • 自动生成模块之间的依赖关系.

使用注意事项:

  • 两个版本必须编译参数里必须都有debug_info ,因为插件需要debug_info 的信息, 担心源码安全的话, 可以通过在项目下增加.erlang.crypt 文件来保护源码.

  • 如果需要手动修改.appup 文件, 则需要编写.appup.src , 但是.appup.src 生成.appup 文件后,插件不会再生成.appup文件,因此建议先用rebar3 appup generate 出 .appup文件,然后再以这个文件的基础去修改,然后作为.appup.src.


(原作者二维码)


以上是关于Erlang 发布版本升级-3 升级发布版本工具讲解的主要内容,如果未能解决你的问题,请参考以下文章

Erlang 发布版本升级-4 升级指令讲解

Erlang 发布版本升级-6 升级模块与进程

Erlang 发布版本升级-1 代码热更

Erlang/OTP 升级丢失现有的 RabbitMQ 消息

mac下升级ruby环境版本

K8s自动扩缩容工具KEDA发布2.0版本,全面升级应用扩展能力