Erlang 接入远程控制台的几种方法

目录

这篇博客源自于调试过程中发现的一个比较有意思的问题。

平时我们的项目生产环境一般都是在 linux 操作系统后台中运行,但我们在运行中势必有连接到线上环境的需求,这时候就需要有办法接入远程控制台, Erlang 提供了四种方法来远程接入控制台

测试环境

主机:Mac Erlang 17.5
虚拟机:CentOS 7 Erlang R16B02

JCL

JCL:作业控制模式「Job Control Mod」, 该模式启动方式是在「Erlang Shell」中按「^G」, 输入 h 就会显示该模式下的命令
Erlang 接入远程控制台的几种方法
接下来在虚拟机中启动一个 Application
Erlang 接入远程控制台的几种方法
可以看到虚拟机中已经运行起来了一个 Application
然后我们在主机 Shell 中用 JCL 的方式去连接,并执行测试函数
Erlang 接入远程控制台的几种方法
可以看到我们连接成功并且运行环境已经是对端节点了

如果我们要退出的话同样是按「^G」然后按 q 安全退出,如果我们这里没有安全退出而是在 shell 执行了「q().」会如何,我们试一下就知道了
Erlang 接入远程控制台的几种方法
我们会看到执行「q().」后返回 ok,但是再去调用函数会提示进程终止,那么是本地终止了还是远程节点终止了呢?我们看下我在执行这个命令前后打印的虚拟机 beam 的进程
Erlang 接入远程控制台的几种方法
可以看到是远程节点终止了,所以我们的连接断掉了,所以我们在生产环境中远程连接的时候一定要小心操作。

那如果我们按了「^C」会怎么样呢?我们再来试试
Erlang 接入远程控制台的几种方法
我们可以看到和 JCL 类似也是会有一个提示信息,你输入对应的命令会执行对应的操作,我试了一下输入「a」会直接退出,远程节点没影响;再按一次「^C」也就是连按两次,会直接退出,远程节点貌似也没影响,这个后面搞清楚再说
@todo

在这里我碰到了一个问题,由于服务器是在虚拟机,所以就存在防火墙阻断端口的问题,一开始我以为 JCL 是通过 EPMD 的端口即 4369 连接,可是我打开了该端口,并不能连接上,经过多番尝试以及查资料了解到 Erlang 启动时, JCL 服务会独立监听一个端口用于处理远程连接,知道这点就好办了,我看一下端口连接就知道了
Erlang 接入远程控制台的几种方法
对比连接前后可以看出 46792 就是 JCL 端口,于是我把 4369 从 iptables 去掉,加入 46792,结果还是不行,我擦嘞,我试了下把两个都添加进去,就可以了,这是为什么?

我猜想:有远程连接到来时,会先连接 epmd 服务,连接后 epmd 会告知 JCL 服务的端口,接下来该连接就直接通过 JCL 服务来交互,所以 epmd 这里起到一个告知端口的作用,这样其他远程节点只需要记住一个 epmd 的端口就行了。

接下来没问题了,然而当我重启了一次服务器之后又连接不上了,我去看了下端口,发现 JCL 的端口竟然变了,后来查到 Erlang 的 JCL 端口是随机的,不过我们可以通过 kernel 两个参数来设定该端口范围,「inet_dist_listen_min 和 inet_dist_listen_max」,现在就彻底没问题了,下面的 remsh 也是一样的

Remsh

Remsh 和 JCL 启动都可以使用长命名或短命名,其他的 Erlang 参数也都可以使用,底层机制也相同,唯一的区别在于:remsh 初始启动的 shell 是远程的,而 JCL 初始启动的节点是本地的

erl -setcookie test -name [email protected] -remsh [email protected]
Erlang 接入远程控制台的几种方法
该模式相对于 JCL 模式还有一个优点,remsh 的方式连接后调用函数是会有自动补全的,JCL 没有。

SSH

@todo

PIPE

@todo

参考:
没有开花的树:erlang 接入远程 shell 控制台
坚强 2002:接入 Erlang 控制台的几种方法

本文链接
代码链接