erlang节点名称注册(erl_epmd)与cookie管理(auth)

net_supkernel中继 dist_ac(distribution applicationcontroller)后启动的监控者(supervisor),除了前文提到的net_kernel(提供节点互联)之外,还有erl_epmd(提供epmd名字注册)auth(提供cookie管理)

拓扑图如下:

            | - erl_epmd
net_sup --- | - auth
            | - net_kernel

本文主要说的是 erl_epmdauth

1. epmd(名字注册)

epmd相关的配置参数和环境变量:

名字 数据类型 备注
start_epmd true / false 在开启节点时候是否开启epmd,默认true
epmd_module atom epmd模块,默认是erl_epmd
epmd_port int 向指定端口注册Node
ERL_EPMD_ADDRESS string epmd 监听地址
ERL_EPMD_PORT int epmd端口号,注意:同一个集群使用同一个端口号,默认4369
1.1 如何设置epmd端口
$ epmd
$ export ERL_EPMD_PORT=Port

$ erlang node
$ erl -epmd_port Port -name ......

% erl_epmd.erl
get_epmd_port() ->
  case init:get_argument(epmd_port) of
    {ok, [[PortStr | _] | _]} when is_list(PortStr) ->
      list_to_integer(PortStr);
    error ->
      ?erlang_daemon_port
  end.

环境变量ERL_EPMD_PORTvm参数 epmd_port配合起来使用,可以在同一个机器上部署多个集群

# 演示了同一台机器部署2个集群
$ 集群一,epmd端口号4000
$ export ERL_EPMD_PORT 4000
$ erl -epmd_port 4000  -name abc@127.0.0.1
(abc@127.0.0.1)1> erl_epmd:names().
{ok,[{"abc",9591}]}

$ 集群二,epmd端口号5000
$ export ERL_EPMD_PORT 5000
$ erl -epmd_port 5000  -name abc@127.0.0.1
(abc@127.0.0.1)1> erl_epmd:names().
{ok,[{"abc",21309}]}
1.2 注册名称过程
% erl_epmd.erl
% 由 net_kernel 发起
handle_call({register, Name, PortNo, Family}, _From, State) ->
  case State#state.socket of
    P when P < 0 ->
      % 只有当没有注册的时候,才允许注册,换句话说,一个Node只会调用一次
      case do_register_node(Name, PortNo, Family) of
        {alive, Socket, Creation} ->
          S = State#state{socket = Socket,port_no = PortNo,name = Name},
          {reply, {ok, Creation}, S};
        Error ->
          {reply, Error, State}
      end;
    _ ->
      {reply, {error, already_registered}, State}
  end;

do_register_node(NodeName, TcpPort, Family) ->
  Localhost = open(TcpPort) % 连本地的epmd
  case Localhost of
    {ok, Socket} ->
      % Socket 正确连上epmd
      Name = to_string(NodeName),
      Packet = ...
      case gen_tcp:send(Socket, Packet) of
        ok ->
          % 发送注册包,等待回包
          wait_for_reg_reply(Socket, []);
        Error ->
          close(Socket),
          Error
      end;
    Error ->
      Error
  end.
  
wait_for_reg_reply(Socket, SoFar) ->
  receive
    {tcp, Socket, Data0} ->
      ...
    {tcp_closed, Socket} ->
      {error, epmd_close}
  after 10000 ->
    % 默认10秒超时,并且不能修改。
    gen_tcp:close(Socket),
    {error, no_reg_reply_from_epmd}
  end.

注意点:

  • 每个节点只能注册一次
  • 注册结束之后保存注册连接(Socket)作为后续与epmd的交互媒介

2. auth(管理cookie)

auth 功能比较单一,就是保存本地的cookie, 相关的vm参数如下:

名字 数据类型 备注
nocookie - 主动不设置cookie
setcookie string 设置节点cookie

设置cookie流程

init_cookie() ->
  case init:get_argument(nocookie) of
    error ->
      case init:get_argument(setcookie) of
        {ok, [[C0]]} ->
          C = list_to_atom(C0),
          #state{our_cookie = C, ...};
        _ ->
          % 从$HOME/.erlang.cookie读取cookie
          case read_cookie() of
            {error, Error} ->
              error_logger:error_msg(Error, []),
              %% Is this really this serious?
              erlang:error(Error);
            {ok, Co} ->
              #state{our_cookie = list_to_atom(Co),
                other_cookies = ets:new(
                  cookies,
                  [?COOKIE_ETS_PROTECTION])}
          end
      end;
    _Other ->
      #state{our_cookie = nocookie,other_cookies = ...}
  end.

  1. 如果vm设置nocookie 参数,直接忽略cookie,否则第二步
  2. 如果vm设置setcookie参数,则保存该 cookie, 否则第三步
  3. $HOME/.erlang.cookie 读取cookie

如上如果要设置一个集群的cookie,有2种方式:

  1. 显示使用setcookie参数(erl -setcookie Cookie),缺点是cookie容易被同一机器上别的用户发现
  2. 使用$HOME/.erlang.cookie文件,保密性强。

3.总结

erl_epmd,auth是节点互联的基础。通过对机制的深入理解,让我们对集群的配置有更多控制权。

4. 参考文献

  1. https://github.com/erlang/otp/blob/master/lib/kernel/src/kernel.erl
  2. https://github.com/erlang/otp/blob/master/lib/kernel/src/erl_distribution.erl
  3. https://github.com/erlang/otp/blob/master/lib/kernel/src/auth.erl
  4. https://github.com/erlang/otp/blob/master/lib/kernel/src/erl_epmd.erl
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容