| Author: | litaocheng@gmail.com |
|---|---|
| Data: | 2009-3-1 |
| Version: | 0.2 |
tiny OTP Application
为了简单,我们创建一个超级简单的application, 其只有一个module, 其不使用supervisor, 只创建一个简单的process, 我们为这个应用名叫:tinyapp (tinyapp-1.0).
其代码如下(tiny.erl):
-module(tiny).
-behaviour(application).
-export([start/2, stop/1]).
start(_Type, _Args) ->
start_process().
stop(_State) ->
ok.
start_process() ->
FLoop =
fun() ->
Fun =
fun(F) ->
receive Msg ->
io:format("receive msg:~p~n", [Msg]),
F(F)
after 1000 ->
{ok, App} = application:get_application(self()),
io:format(user, "~p 1.0 running...~n", [App]),
F(F)
end
end,
Fun(Fun)
end,
{ok, proc_lib:spawn_link(FLoop)}.
这个tiny.erl就是我们所有的application代码了.功能很简单就是定期打印 tiny_app running ... 信息.
请注意,这个程序并不是一个标准的Erlang OTP 应用. 因为其没有使用 supervisor , gen_server , gen_fsm , gen_event 等behavior. 在后面的部分,我们会对这个tiny app进行改造,升级.
然后我们定义application resource 文件(.app), tiny_app.app 文件内容如下:
{application, tiny_app,
[{description, "tiny app"},
{vsn, "1.0"},
{modules, [tiny]},
{registered, []},
{applications, [kernel, stdlib, sasl]},
{mod, {tiny, []}}
]
}.
好了,这两个文件就构成了我们的一个tiny application, 当然其内部实现可能不是很符合OTP, 但是无所谓了,我们今天的 目标是为OTP application创建installer.
我们的目录结构如下:
tiny-1.0/
|-- ebin/
|-- src/
编译tiny.erl, 将tiny.beam输出到ebin目录中, 当然有时间你可以写个Makefile, 我这里就不描述了,我们这个小应用还是很 容易编译的: $ erlc -o ../ebin tiny.erl
到这里,有必要看看我们的application是否可以正常运行, 进入erl shell:
[da66@litaocheng ~/install/tiny-1.0]$ erl -pa ./ebin
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.6.5 (abort with ^G)
1> application:start(tiny_app).
ok
2> tiny_app version 1.0 live group leader:<0.33.0>
tiny_app version 1.0 live group leader:<0.33.0>
3> application:which_applications().
[{tiny_app,"tiny app","1.0"},
{stdlib,"ERTS CXC 138 10","1.15.5"},
{kernel,"ERTS CXC 138 10","2.12.5"}]
4> application:stop(tiny_app).
=INFO REPORT==== 2-Mar-2009::03:44:43 ===
application: tiny_app
exited: stopped
type: temporary
ok
好的,一切正常, 我的application已经可以start, stop. 接下来要生成release了.
生成Release
参照 OTP Design Principles Releases 部分, 使用你喜欢的Editor定义release resource file(.rel) tiny-1.0.rel 其内容如下:
{release, {"tiny app release", "1.0"}, {erts, "5.6.5"},
[{kernel, "2.12.5"},
{stdlib, "1.15.5"},
{sasl, "2.1.5.4"},
{tiny_app, "1.0"}
]}.
rel文件中,指明Erlang Emulator的版本信息: erts 5.6.5(R12B-5). 我们将tiny-1.0.rel文件放在tiny-1.0目录下:
tiny-1.0/
|-- ebin/
|-- src/
|-- tiny-1.0.rel
现在让我们使用sasl lib中的systools模块,根据rel文件,生成boot script和tar 运行如下:
[da66@litaocheng ~/install/tiny-1.0]$ erl -pa ./ebin/
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.6.5 (abort with ^G)
1> systools:make_script("tiny-1.0").
ok
2> systools:make_tar("tiny-1.0", [{erts, "/opt/local/lib/erlang/"}]).
ok
查看我们的tiny-1.0目录下看多了什么东西:
[da6600a1@litaocheng ~/install/tiny-1.0]$ ls -p ebin/ tiny-1.0.boot tiny-1.0.script src/ tiny-1.0.rel tiny-1.0.tar.gz
恩,我们通过make_script生成了 tiny_app.boot和 tiny_app.script, 通过make_tar生成了tiny-1.0.tar.gz.
在生成tar时,通过指定erts选项,可以将当前的erts运行时,也会被包含到打包的文件中.这样即使被部署的机器 没有安装Erlang, 我们这个Relase包依旧可以运行.
此时,我们的tiny-1.0.tar.gz包含下面几个目录:
tiny-1.0.tar.gz --
|-- erts-5.6.5/
|-- lib/
| |-- kernel-2.12.5/
| |-- stdlib-1.15.5/
| |-- tiny_app-1.0/
|-- releases/
其中make_script及make_script有很多选项,我们可以根据需要进行设定.
有了这个Relase, 我们怎么使用它呢? 这里就要用到sasl lib了, 我们首先把这个tiny-1.0.tar.gz copy到 $ERL_ROOT/releases 目录中, 其中$ERL_ROOT是你的erlang安装 目录,我这里是/opt/local/lib/erlang.
随后我们运行命令:
erl
1> application:start(sasl) % first start sasl
ok
2> release_handler:unpack_release("tiny-1.0").
{ok,"1.0"}
release_handler:unpack_release/1 的参数 Name , 对应releases目录下的 Name .tar.gz, 这里就是 tiny-1.0
通过上面的调用, tiny-1.0.tar.gz被解压,然后放置到$ERL_ROOT对应目录中:
$ERL_ROOT/lib 新增 tiny_app-1.0/ $ERL_ROOT/release 1.0/ 目录 $ERL_ROOT/release/RELEASES 文件被修改,添加tiny_app相关记录
恩, 这个过程其实归根结底,就是吧tiny_app-1.0放到了ERL_ROOT/lib目录,然后对ERL_ROOT/releases目录做了一些修改.
现在让我们重新启动erl, 随后, 你可以在任何目录运行tiny_app了.
- in erl shell > application:start(tiny_app).
- in linux shell $ erl -boot $ERL_ROOT/releases/1.0/start
说明:$ERL_ROOT/lib下的所有application路径都会加载到code中,所以通过第一种方式也可以方便的启动tiny_app 两种方式皆可.
上面解决了生成的release在本机运行的问题, 其实更多的时候,我们想将系统部署到一台"新"的机器中. 所以我们需要创建一个target system.
Target System
Target System的制作方法,请参考 Createing a First Target System . 这个target_system.erl中,根据rel文件,创建了script, boot以及tar, 也就是说,我们上一个章节的很多工作, 在这个module中都进行了处理. 我们对这个erl文件稍微进行一些改进, 加入一些传递给make_script和make_tar的参数. 改造后的文件可以从此下载: target_system.erl
在tiny-1.0.rel所在目录,运行target_system:create/1来创建target system:
[da6600a1@litaocheng ~/install/tiny-1.0]$ erl -pa ./ebin/ ../
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.6.5 (abort with ^G)
1> target_system:create("tiny-1.0").
Reading file: "tiny-1.0.rel" ...
...省略...
Removing directory "tmp" ...
ok
ok 表明生成成功; 如果发生错误, 请检查你的路径信息是否正确, 以及是否拥有创建文件相关权限.
好了一切正常,现在tiny-1.0目录下包含下面文件:
[da6600a1@litaocheng ~/install/tiny-1.0]$ ls -p ebin/ plain.script tiny-1.0.rel plain.boot src/ tiny-1.0.script plain.rel tiny-1.0.boot tiny-1.0.tar.gz
plain.* 系列文件启动时只加载kernel, stdlib两个lib, 没有包含我们的tiny_app,所以叫plain. 而tiny_app系列, 除却plain的项目,还包含了我们的tiny_app相关加载. 我们可以通过查看plain.script或tiny_app.script获取相关信息.
现在我们要安装target system了, 我们假设想安装在: /opt/local/tiny-1.0 目录.
这里有一个问题:如果目标机器没有安装erlang, 那么就不能使用target_system进行安装, 需要使用一段shell脚本进行安装, 主要就是解压文件, 随后替换路径从而完成安装. 这个小脚本随后会提供下载
执行下面命令:
[da6600a1@litaocheng ~/install/tiny-1.0]$ sudo erl -pa ../
Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.6.5 (abort with ^G)
1> target_system:install("tiny-1.0", "/opt/local/tiny").
Extracting tiny-1.0.tar.gz ...
Substituting in erl.src, start.src and start_erl.src to
form erl, start and start_erl ...
Creating the RELEASES file ...
ok
恩,好的,现在在/opt/local/tiny目录下已经安装成功.
接下来让我们运行这个新部署的应用:
[da6600a1@litaocheng ~]$ /opt/local/tiny/bin/erl -boot /opt/local/tiny/releases/1.0/start Erlang (BEAM) emulator version 5.6.5 [source] [async-threads:0] [hipe] [kernel-poll:false] Eshell V5.6.5 (abort with ^G) 1> tiny_app 1.0 running...
不错,我们的tiny_app部署成功, 下面的部分我们要讲述更加激动人心的部分, 关于应用的热升级及回退.
本文介绍如何使用Erlang OTP规范创建简单的应用程序,并详细解释了如何构建、打包及部署该应用。从源码组织到生成release包,再到安装与运行,提供了完整的流程指导。
204

被折叠的 条评论
为什么被折叠?



