アーラン/ OTPはじめに分散 "のErlang / OTP並行プログラミングの戦闘" の章VIII

  1. Erlangで共有しない、唯一のメッセージング、そうスタンドアロンまたは分散性に違いはありません。
  2. Erlangのは、クラスタ全体Unicom社のネットワークです。
  3. ノードが開始されます:
    1. ERL -name xxの
      ネットワーク環境に通常のDNSへの適用、ノードの完全修飾ドメイン名を与える必要
    2. ERL -sname xxの
      完全修飾ドメイン名の場合には適用は使用できません
  4. 通信モードが異なるされているノードの短い及び長いノード名ノード名と、クラスタがその間に形成することができません。
  5. 目に見えないノード:
    いくつかの特別なノードと、私たちはより大きな、非フルUnicom社のクラスタに複数のクラスタを組み合わせることができます。
    特別な構成を介して、そのようなノードは、他のノードに発信情報に対して行われることはありません、彼らも、クラスタ非侵入型モニタリングの他のノードには見えないことができます。
  6. 接続を確立するには:
    net_adm:ping('[email protected]').

     

  7. EPMD(アーランポートマッパデーモン):
    1. ローカルマシン上でEPMD EPMDチェックを実行しているかどうか、各ノードを起動し、そうでない場合、EPMDのノードが自動的に起動します。
    2. EPMDは、各ノードのローカルマシン上で実行し、それらに割り当てられたポート番号の記録を追跡し、
    3. マシン上のアーラン・ノードがリモートノードと通信しようとすると、該当する名前を持っていないリモートマシン上のノードに問い合わせ、(TCP / IPをデフォルトのポート番号4369を使用して)リモートマシン上のローカルEPMD EPMD接触します。もしそうであれば、遠隔EPMDポート番号が返され、このポートは、直接リモートノードと通信することができます。
    4. EPMDは、積極的にノードが積極的に他のノードを検索したときにのみ確立することができ、他のEPMDを検索しません。
  8. 通信セキュリティ:
    クラスタ内のすべてのノードが信頼ネットワーク内で実行されていることを前提にErlangのデフォルト分散モデル。
    この仮定が成立しない、またはこれらのマシンの一部は、外の世界と通信する必要がある場合、その後、直接TCP(またはUDP、SCTP、等)の上のアプリケーション層プロトコルによって適切であると通信ネットワークとの非通信上で実現。加えて、利用することもSSL、SSHは、IPsecはトンネル確立された技術を暗号化し、あるいは直接アーランにSSLを介してトランスポートプロトコルを設定する通信層を分散することができます。
  9.  
    auth:get_cookie().            % 获取当前节点的 cookie
    set_cookie(Node, Cookie).     % 设置 cookie

     

  10. Erlangで、シェルは、フォールトトレラントのプロセスを使用することです。シェルプロセスがクラッシュした後に、メールボックスの内容は失われますが、それでも変数間の結合関係を保持します。
  11. リモートシェルを使用します。
    1. ノード間の事前確立接続する必要はありません
    2. コマンドはCtrl-Gの下で:R '[email protected]'
    3. ノード名は、単一引用符に、ピリオドが含まれている場合
    4. コマンドは直ちに有効になりません
    5. リモートシェルを終了するとことに注意してください:! Q()を使用しないでください。Q()は、リモート・ノードでコマンドノードを、実行するためにオフになっています。
      セキュア出口には、Ctrl-GまたはCtrl-Cを使用し
  12. 資源探査の適用:
    1. 資源探査:リソース・プロバイダーとリソース・コンシューマとの関係
    2. コードの実装:
      -module(resource_discovery).
      
      -behavior(gen_server).
      %% API
      -export([start_link/0, add_target_resource_type/1, add_local_resource/2, fetch_resources/1, trade_resources/0]).
      
      -export([
        init/1,
        handle_call/3,
        handle_cast/2,
        handle_info/2,
        terminate/2,
        code_change/3
      ]).
      
      -define(SERVER, ?MODULE).
      
      -record(state, {target_resource_types, local_resource_tuples, found_resource_tuples}).
      
      start_link() ->
        gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
      
      init([]) ->
        {ok, #state{target_resource_types = [], local_resource_tuples = dict:new(),
          found_resource_tuples = dict:new()}}.
      
      add_target_resource_type(Type) ->
        gen_server:cast(?SERVER, {add_target_resource_type, Type}).
      
      add_local_resource(Type, Instance) ->
        gen_server:cast(?SERVER, {add_local_resource, {Type, Instance}}).
      
      fetch_resources(Type) ->
        gen_server:call(?SERVER, {fetch_resources, Type}).
      
      trade_resources() ->
        gen_server:cast(?SERVER, trade_resources).
      
      
      handle_cast({add_target_resource_type, Type}, State) ->
        TargetTypes = State#state.target_resource_types,
        NewTargetTypes = [Type | lists:delete(Type, TargetTypes)],
        {noreply, State#state{target_resource_types = NewTargetTypes}};
      
      handle_cast({add_local_resource, {Type, Instance}}, State) ->
        ResourceTuples = State#state.local_resource_tuples,
        NewResourceTuples = add_resource(Type, Instance, ResourceTuples),
        {noreply, State#state{local_resource_tuples = NewResourceTuples}};
      
      handle_cast(trade_resources, State) ->
        ResourceTuples = State#state.local_resource_tuples,
        AllNodes = [node() | nodes()],
        lists:foreach(
          fun(Node) ->
            gen_server:cast({?SERVER, Node}, {trade_resources, {node(), ResourceTuples}})
          end, AllNodes),
        {noreply, State};
      
      handle_cast({trade_resources, {ReplyTo, Remotes}}, State) ->
        #state{local_resource_tuples = Locals, target_resource_types = TargetTypes, found_resource_tuples = OldFound} = State,
        FilteredRemotes = resource_for_types(TargetTypes, Remotes),
        NewFound = add_resources(FilteredRemotes, OldFound),
        case ReplyTo of
          noreply ->
            ok;
          _ ->
            gen_server:cast({?SERVER, ReplyTo}, {trade_resources, {noreply, Locals}})
        end,
        {noreply, State#state{found_resource_tuples = NewFound}}.
      
      handle_call({fetch_resources, Type}, _From, State) ->
        {reply, dict:find(Type, State#state.local_resource_tuples), State}.
      
      handle_info(_, State) ->
        {stop, normal, State}.
      
      terminate(_Reason, _State) ->
        sc_store:delete(self()),
        ok.
      
      code_change(_OldVsn, State, _Extra) ->
        {ok, State}.
      
      
      add_resources([{Type, Resource} | T ], ResourceTuples) ->
        add_resources(T, add_resource(Type, Resource, ResourceTuples));
      add_resources([], ResourceTuples) ->
        ResourceTuples.
      
      resource_for_types(Types, ResourceTuples) ->
        Fun =
          fun(Type, Acc) ->
            case dict:find(Type, ResourceTuples) of
            {ok, List} ->
              [{Type, Instance} || Instance <- List] ++ Acc;
            error ->
              Acc
            end
          end,
        lists:foldl(Fun, [], Types).
      
      add_resource(Type, Resource, ResourceTuples) ->
        case dict:find(Type, ResourceTuples) of
          {ok, ResourceList} ->
            NewList = [Resource | lists:delete(Resource, ResourceList)],
            dict:store(Type, NewList, ResourceTuples);
          error ->
            dict:store(Type, [Resource], ResourceTuples)
        end.

       

公開された42元の記事 ウォンの賞賛2 ビュー10000 +

おすすめ

転載: blog.csdn.net/sanmao123456_/article/details/103481125