Erlang应用部署与热代码替换--理解1

 

 

 

最近几天看了一下erlang的代码热替换,原本计划三天。现在花了快5天了,才刚刚有点对头。

开始我搜了一下,没有找到前人的例子,Erlang程序设计上面的热代码替换例子只不过是个替换思想,实际的应用替换要复杂的多。

我只好从API gen_server中Module:code_change/3开始看。找到OTP Design Principles (http://www.erlang.org/doc/design_principles/release_handling.html#instr)

。本以为就可以解决此问题了,后来发现只不过是个小小的救命草,接下来看了Release Handling,Releases,Appup Cookbook,systools,reltool等。

整个过程遇到了unpacke_release,install_release两个最耽误时间错误。

出现unpacke_release,install_release操作错误的原因是我没有发布第一个版本,(创建第一个版本:http://www.erlang.org/doc/system_principles/create_target.html)。

应用部署与热替换大体步骤:

一、发布第一个版本 (详细参考:http://www.erlang.org/doc/system_principles/create_target.html)

 1>创建 发布.rel文件

 

 {release,
 {"sellaprimeA", "1"},
 {erts, "5.7.5"},
 [{kernel, "2.13.5"},
  {stdlib, "1.16.5"},
  {sasl, "2.1.9"},
  {sellaprimeA,"1.0"}]}.
 

 

 2>创建第一个发布版本程序

   target_system:create("sellaprimeA").

 3>安装

   target_system:install("sellaprimeA", "/usr/local/target_sellaprime").

 4>启动程序

   /usr/local/target_sellaprime/bin/erl -boot /usr/local/target_sellaprime/releases/1/start

  留心:需要注意的是 target_system.erl 并没有在erlang lib中 ,需要自安添加编译。

二、代码热替换 (详细参考:http://www.erlang.org/doc/design_principles/release_handling.html#id2273657)

 1>创建 发布.rel文件

 2>创建 启动脚本 systools:make_script/1

 3>创建 relup文件 systools:make_relup/3

 4>创建 tar包 systools:make_tar/1

 5>复制到发布目录下

 6>解包 release_handler:unpack_release/1

 7>安装 release_handler:install_release/1

 8>持久化 release_handler:make_permanent/1

 9>删除老的版本 release_handler:remove_release/1

 

三、未解决的问题:

 1> 执行 unpacke_release、install_release函数操作时,必须在特定的shell下,就是启动一个发布程序的shell下。

    如果我是在noshell下启动的话,我就无法执行热代码替换了。有没有其他方法?请老师赐教,谢谢!

    如我必须在/usr/local/target_sellaprime/bin/erl -boot /usr/local/target_sellaprime/releases/1/start启动的shell。

 2> 更新 new_area_server.erl模块时,state状态丢失,即ets:new(?MODULE,[])内存表被清空。

    根据API中的设计原则上配置的sellaprime.appup(我没有看出哪里有错).

 

Erlang 写道
sellaprime.appup
{"6",
[{"5",[{update, new_area_server,{advanced,Extra}}]}],
[{"5",[{update, new_area_server,supervisor}]}]
}.
 

 

-module(new_area_server).
-behaviour(gen_server).

-export([area/1, start_link/0]).

%% gen_server callbacks

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

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

%% @type Thing()=autom()
%% @doc langxianzeu
area(Thing) ->
    gen_server:call(?MODULE, {area, Thing}).

init([]) ->
    %% Note we must set trap_exit = true if we 
    %% want terminate/2 to be called when the application
    %% is stopped
    process_flag(trap_exit, true),
    io:format("~p starting add ets table~n",[?MODULE]),
    {ok, ets:new(?MODULE,[])}.

handle_call({area, Thing}, _From, State) ->
        Reply = compute_area(Thing),
        ets:insert(State,{Thing,Reply}),
        io:format("~n==[handle_call]=======tab=~p=====~n",[ets:tab2list(State)]),
        {reply, Reply, State}.

handle_cast(_Msg, N)  -> {noreply, N}.

handle_info(_Info, N)  -> {noreply, N}.

terminate(_Reason, _N) ->
    io:format("~p stopping~n",[?MODULE]),
    ok.

code_change(_OldVsn, N, _Extra) -> {ok, N}.

compute_area({square, X})       -> io:format("~n===[new_area_server:compute_area-code_chanage-06~p~n====",[X*X]),X*X;
compute_area({rectongle, X, Y}) -> X*Y.
 

 

 3> 当 new_area_server中的(改变进程状态的存储方式)

    init([]) ->

    process_flag(trap_exit, true),

    io:format("~p starting add ets table~n",[?MODULE]),

    {ok, 0}.

    替换为

    init([]) ->

    process_flag(trap_exit, true),

    io:format("~p starting add ets table~n",[?MODULE]),

    {ok,

    ets:new(?MODULE,[])

    时如何保存以前的状态

 

4> 其他模块的热替换还没有实践,继续实践!

 

 

 

5>

release_handler:unpack_release("ch_rel-2").

{error,{enoent,"/opt/target/releases/ch_rel-2.rel"}}

出现上面error的其中一个原因就是权限不足,需要用root权限

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值