在window中調試的時候我們可以通過啟動多個cmd窗口運行Erlang節點,在生產環境中我們需要Erlang服務在Centos服務器上后台運行;這就需要在啟動的時候添加啟動參數detached來脫離終端:
-detached Starts the Erlang runtime system detached from the system console. Useful for running daemons and backgrounds processes. Implies -noinput.
對於我們自己的服務,即使部署到了生產環境一定要做到"像魔術師的飛刀,出手但並沒有脫手",還是需要一些方式進入到Erlang后台進程來做一些工作比如:查看某一個Erlang節點的運行時信息(內存,進程數等),讓服務優雅的退出而不是kill進程,或者做一下熱更新(參見:[Erlang 0010] Erlang 熱更新 當然熱更新可以使用reloader.erl的方案來簡化);一開始的時候服務器比較少,我們采用的是JCL的方式去處理的;
Erlang Shell JCL
JCL是Erlang Shell的一種運行模式,即Job Control Mode (JCL, in which jobs can be started, killed, detached and connected).我們啟動兩個節點來完成這個操作;
2012-11-14新增備注:下面的實驗是在Linux下完成的,Windows下JCL需要啟動werl.exe
Node_1 添加了-detached選項,啟動之后直接在后台運行並沒有啟動Shell
erl -setcookie abc -name node_1@192.168.1.123 -detached
Node_2 使用了和Node_1相同的cookie,啟動之后進入Erlang Shell界面
erl -setcookie abc -name node_2@192.168.1.123
下面我們開始在node_2@192.168.1.123演練JCL:
Eshell V5.9 (abort with ^G)
(node_2@192.168.1.123)1> node(). %當前這是在node_2
'node_2@192.168.1.123'
(node_2@192.168.1.123)2> %Ctrl + G 進入JCL模式
User switch command
--> h
c [nn] - connect to job
i [nn] - interrupt job
k [nn] - kill job
j - list all jobs
s [shell] - start local shell
r [node [shell]] - start remote shell
q - quit erlang
? | h - this message
--> r'node_1@192.168.1.123' %嘗試連接到node_1@192.168.1.123
--> j
1 {shell,start,[init]} %列出所有的Job
2* {'node_1@192.168.1.123',shell,start,[]}
--> c 2 %這里2是job的編號,切換到job 2
Eshell V5.9 (abort with ^G)
(node_1@192.168.1.123)1> node(). %注意提示符,現在已經是在node_1
'node_1@192.168.1.123'
(node_1@192.168.1.123)2> erlang:now().
{1326,801888,347570}
(node_1@192.168.1.123)3> %再一次Ctrl + G
User switch command
--> j
1 {shell,start,[init]}
2* {'node_1@192.168.1.123',shell,start,[]}
--> c 1 %切換到job 1
(node_2@192.168.1.123)2> node(). %注意提示符,我們已經回到了node_2
'node_2@192.168.1.123'
(node_2@192.168.1.123)3>
這樣來來回回切換是不是有點盜夢空間的意思?是不是可以更簡單一點,比如直接進入node_1呢?借助-remsh參數就可以做到
看看-remsh的說明恰好是我們需要的:
If you want an Erlang node to have a remote job active from the start (rather than the default local job), you start Erlang with the -remsh flag. Example: erl -sname this_node -remsh other_node@other_host
動手試一下:
erl -setcookie abc -name node_3@192.168.1.123 -remsh node_1@192.168.1.123 %%這樣就直接進入了node_1節點
注意:直接進入到了node_1,執行完操作了想要退出怎么辦? 你要是在這里執行一下q(). node_1這個節點就直接死掉了;
正確的方法還是Ctrl+G進入JCL模式然后執行q命令退出;使用ps aux|grep node查看一下進程是不是還在
ejabberd網站上提到了這個方法
[1] Attach an Erlang Shell to an Already Running ejabberd Process http://www.ejabberd.im/tricks
[2] Interconnecting Erlang Nodes http://www.ejabberd.im/interconnect-erl-nodes
另一種實用的接入erlang控制台的方法
地址:http://mryufeng.iteye.com/blog/362394 Powered by mryufeng
按照mryufeng老大的方法操練了一番,成功,中間 /usr/local/lib/erlang/bin/start 啟動失敗,同樣是目錄和配置文件缺失的問題
mkdir /usr/local/lib/erlang/log
echo "[]." > /usr/local/lib/erlang/releases/R15B/sys.config
Stackoverflow的相關問題: How to create deamon program with erlang? http://stackoverflow.com/questions/5972811/how-to-create-deamon-program-with-erlang
題外話:在embedded模式下是沒有交互式shell可用的,能夠接入Erlang VM的方法就是to_erl
原理見下圖:
erl_call
Usage: /usr/local/lib/erlang/lib/erl_interface-3.7.6/bin/erl_call [-[demqrsv]] [-c Cookie] [-h HiddenName]
[-x ErlScript] [-a [Mod [Fun [Args]]]]
(-n Node | -sname Node | -name Node)
where: -a apply(Mod,Fun,Args) (e.g -a 'erlang length [[a,b,c]]'
-c cookie string; by default read from ~/.erlang.cookie
-d direct Erlang output to ~/.erl_call.out.<Nodename>
-e evaluate contents of standard input (e.g echo "X=1,Y=2,{X,Y}."|erl_call -e ...)
-h specify a name for the erl_call client node
-m read and compile Erlang module from stdin
-n name of Erlang node, same as -name
-name name of Erlang node, expanded to a fully qualified
-sname name of Erlang node, short form will be used
-q halt the Erlang node (overrides the -s switch)
-r use a random name for the erl_call client node
-s start a new Erlang node if necessary
-v verbose mode, i.e print some information on stderr
-x use specified erl start script, default is erl
B=2,
C=A+B.
%Ctrl + D
{ok, 3}
SSH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
$ mkdir /tmp/ssh
$ ssh-keygen -t rsa -f /tmp/ssh/ssh_host_rsa_key
$ ssh-keygen -t rsa1 -f /tmp/ssh/ssh_host_key
$ ssh-keygen -t dsa -f /tmp/ssh/ssh_host_dsa_key
$ erl
1> application:ensure_all_started(ssh).
{ok,[crypto,asn1,public_key,ssh]}
2> ssh:daemon(8989, [{system_dir,
"/tmp/ssh"
},
2> {user_dir,
"/home/ferd/.ssh"
}]).
{ok,<0.52.0>}
$ ssh -p 8989 ferd@127.0.0.1
Eshell Vx.x.x (abort with ^G)
1>
|