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阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容