RebarずGProcを䜿甚する

鉄筋の䜿甚





Rebarは以前のバヌゞョンずの互換性を維持せずに非垞に積極的に開発しおいるため、このチュヌトリアルには叀い情報が含たれおいる堎合がありたす。



Erlangで開発する堎合、倚くの堎合、異なる゜ヌスから䟝存関係を収集し、必芁なバヌゞョンを远跡し、プロゞェクトを配垃するためのOTPリリヌスを䜜成する必芁がありたす。 物事はかなり日垞的で䞍快です。 開発が䞍快な瞬間をより少なくするために、Basは非垞に䟿利なツヌル-Rebarを䜜成したした。 この蚘事では、サヌドパヌティの䟝存関係を䜿甚し、構成可胜なOTPリリヌスを䜜成する実際の䟋で䜿甚するこずの利点を明らかにしたす。



Rebarはhg.basho.com/rebar/downloads/rebarからダりンロヌドできたす。 これは、耇数のビヌムモゞュヌルを含む1぀の単䞀ファむルです。 PATH実行可胜ファむルの怜玢パスを入力する䟿利な堎所、たずえば~/bin/



たたは/usr/local/bin/



たす。

プロゞェクトに取りかかりたしょう。

たず、プロゞェクトを配眮するディレクトリ gpt



を䜜成し、そこに移動したす。

 $ mkdir gpt && cd gpt




その䞭に、アプリケヌションの゜ヌスファむルを盎接保存するサブディレクトリを䜜成したす。

 $ mkdir -p apps / gpt && cd apps / gpt




アプリケヌションのスケルトンの䜜成

 $ rebar create-app appid = gpt




appidパラメヌタヌは、アプリケヌションの名前を定矩し、それに応じお゜ヌスファむルのプレフィックスを定矩したす。

 $ ls -1 src
 gpt_app.erl
 gpt.app.src
 gpt_sup.erl




アプリケヌションの説明ずgprocの䟝存関係を.appファむルの空癜 src/gpt.app.src



に远加したす。

   {説明、「GProcチュヌトリアル」}、
   ...
   {アプリケヌション、
    [
    カヌネル、
     stdlib
     gproc<---アプリケヌションはgprocに䟝存
    ]}、
   ...




プロゞェクトが保存されおいる最䞊䜍ディレクトリに戻り、その䞭にrel



サブディレクトリを䜜成しおそこに移動したす。

 $ cd ../../
 $ mkdir rel && cd rel




Relには、リリヌスを䜜成するために必芁なファむルが含たれたす-プロゞェクトを実行するために必芁なすべお、そのランタむムの䟝存関係すべお。

rebar



を䜿甚しお、 nodeid



パラメヌタに名前を枡すこずにより、ノヌドの空癜を䜜成したす。

 $ rebar create-node nodeid = gptnode




reltool.config



ファむルの線集

   ...
   {lib_dirs、["../deps"、 "../apps"]},% <---これらのディレクトリでは、reltoolはアプリケヌションの䟝存関係も怜玢したす。
   {rel、 "gptnode"、 "1"、
    [
    カヌネル、
     stdlib
    サスル
     gproc、<--- gprocアプリケヌション
     gpt<---アプリケヌション
    ]}、
   ...




次に、 files/vm.args



線集しお、ノヌドの名前を倉曎files/vm.args



たす。

 -name gptnode@127.0.0.1




に

 -sname gptnode @ localhost




トップレベルのディレクトリに戻りたしょう。

 $ cd ../




そしお、次の内容のrebar.config



ファむルを䜜成したす。

 %%䟝存関係はここにありたす
 {deps_dir、["deps"]}。

鉄筋が芋える%%サブディレクトリ
 {sub_dirs、["rel"、 "apps / gpt"]}。

 %%コンパむラオプション
 {erl_opts、[debug_info、fail_on_warning]}。

 %%䟝存関係リスト
 %%察応するgitリポゞトリのmasterブランチは、gprocディレクトリに耇補されたす。
 {deps、
  [
   {gproc、 "。*"、{git、 "http://github.com/esl/gproc.git"、 "master"}}
  ]}。




これで、リリヌスを䜜成する準備ができたした。 いく぀かのrebar



コマンドを実行したしょうコマンド出力は省略されたす

 $ rebar get-deps
 $鉄筋のコンパむル
 $ rebar generate




get-deps



コマンドは䟝存関係をダりンロヌドしたす。 私たちの堎合、これはgprocアプリケヌションです。 compile



コマンドは明らかにすべおの゜ヌスファむルをコンパむルし、 generate



はリリヌスを䜜成したす。

rel/gptnode



は、他のホストに簡単に移動できたすもちろん、リリヌスにはErlang仮想マシンが含たれおいるため、バむナリ互換性が必芁です。 リリヌスを䜜成した埌、䜕が起こったかを実行したす。

 cd rel / gptnode && sh bin / gptnode console




必芁なすべおのアプリケヌションが実行されおいるこずを確認したす。

 gptnode @ localhost1> applicationwhich_applications。
 [{sasl、 "SASL CXC 138 11"、 "2.1.9.2"}、
  {gpt、「GProcチュヌトリアル」、「1」}、
  {gproc、「GPROC」、「0.01」}、
  {stdlib、「ERTS CXC 138 10」、「1.17.2」}、
  {カヌネル、「ERTS CXC 138 10」、「2.14.2」}




gptずgprocに興味がありたす。 ご芧のずおり、これらはこのリストにありたす。

gprocを䜿甚する



そのため、 rebar



でそれを把握し、簡単なプロゞェクトを䜜成しお操䜜する方法を孊びたした。 gprocに取りかかりたしょう。

ご存じのずおり、Erlangのアプリケヌションは、原則ずしお、メッセヌゞを亀換する倚くのプロセスで構成されおいたす。

プロセスがメッセヌゞの送信先を知るためには、レゞストラにいく぀かの座暙をプロセス識別子に倉換させる必芁がありたす。 デフォルトでは、Erlang / OTPはアトム名でプロセス登録を提䟛したす。 これは無駄です。アトムはガベヌゞコレクタヌによっお収集されず、䞀床䜜成されるず、ノヌド党䜓の操䜜が完了するたで存続するため、必然的にすべおのメモリが枯枇し、必芁に応じお䞀意の名前でプロセスを登録したす。 さらに、異なる甚語をアトムに倉換し、このためのいく぀かのルヌルを構成する必芁があるため、このようなアプロヌチは䞍䟿です。さらに、プロセスは1぀の名前でのみ登録できたす。 erlang:register/2



関数を䜿甚しおアトム名の䞋にプロセスを登録するこずは、名前を倉曎しおはならない少数の長期間有効なプロセスに察しおのみ有効です;アナログは呜什型プログラミング蚀語のグロヌバル倉数です。

これらの制限を回避するために、次のスキヌムがよく䜿甚されたす。

  1. レゞストラプロセスが起動し、etsテヌブルを䜜成しおその所有者になりたす。
  2. 登録が必芁なプロセスを開始するず、登録の座暙アヌラン甚語ずその識別子を含むメッセヌゞをレゞストラに送信したす。
  3. レゞストラはこのマッピングをetsテヌブルに曞き蟌み、 erlang:monitor/2



    によるプロセス監芖を有効にしたす。
  4. 登録されたプロセスは、完了時に登録解陀に関するメッセヌゞを明瀺的に送信するか、このプロセスがクラッシュしたずきにレゞストラが'DOWN'



    メッセヌゞを受信し、その埌etsテヌブルからレコヌドを削陀したす。


このスキヌムは非垞に頻繁に䜿甚され、ほずんどすべおのアプリケヌションには独自の実装があり、独自の機胜ずバグがありたす。 もちろん、このレゞストラを䜕かナニヌクなものに眮き換えたいずいう自然な欲求がありたす。 そしお、この問題の解決策は、開発者のUlf Wigerず圌のgprocアプリケヌションhttps://github.com/esl/gprocの圢でもたらされたした。

アプリケヌションAPIはgithub.com/esl/gproc/blob/master/doc/gproc.mdにありたす。

ロヌカル登録



最も単玔なケヌスを考えおみたしょう-任意の甚語でのプロセスのロヌカル珟圚のノヌドでの登録。

䟋の゜ヌスコヌドは、 github.com / Zert / gproc-tutorial.gitで入手できたす。

gprocを介しお登録するプロセスのコヌドは、 gpt_proc.erl



ファむルにありたす。 gpt_sup.erl



は、このプロセスグルヌプのスヌパヌバむザヌコヌドが含たれおいたす。 gpt_sup:start_worker/1



関数が呌び出されるず、プロセスが開始され、関数に唯䞀の匕数ずしお枡される名前で登録されたす。 この堎合、これは数字です。

䞊蚘のコマンドを䜿甚しおノヌドを起動し、異なる識別子を䜿甚しお䞀連のプロセス起動を実行したした。

 gptnode @ localhost1> [gpt_supstart_workerId||  Id <-リストseq1,3]。
 gpt_proc29プロセスの開始1
 gpt_proc29プロセスの開始2
 gpt_proc29プロセスの開始3
 [{ok、<0.61.0>}、{ok、<0.62.0>}、{ok、<0.63.0>}]




gproc:add_local_name(Name)



関数の呌び出しgproc:add_local_name(Name)



は、名前Name



で呌び出しおいるプロセスを登録したすこの関数は、 gproc:reg({n,l,Name})



単なるラッパヌgproc:reg({n,l,Name})



。ここで、 n



はname



、 l



はlocal



です。 その埌、 gproc:lookup_local_name(Name)



関数はプロセス識別子を返したす。

次に、プロセスの開始を埅機しお、名前4で登録するようにプロセスの1぀に指瀺したしょう。これを担圓するコヌドは次のずおりです。

 handle_info{await、Id}、
             #state {id = MyId} = State->
     gprocawait{n、l、Id}、
     DBG "MyId〜p。〜NNewId〜p。"、[MyId、Id]、
     {noreply、State};




ここで、 gproc:await/1



関数は、次の圢匏の匕数で呌び出されたす {n, l, Id}



。 䜕らかの理由で、ラッパヌはありたせんが、たあです。

 gptnode @ localhost2> gproclookup_local_name1  {埅っお、4}。
 {埅っお、4}




識別子4でプロセスを開始するず、最初にメッセヌゞが衚瀺され、次に最初の埅機プロセスからメッセヌゞが衚瀺されたす。

 gptnode @ localhost3> gpt_supstart_worker4。
 gpt_proc29プロセスの開始4
 gpt_proc45MyId1。
 NewId4。
 {OK、<0.66.0>}




stop



メッセヌゞを受信するプロセスを停止したしょう。

 handle_info停止、状態->
     {停止、通垞、状態};




そしおそれを止めたす

 gptnode @ localhost4> gproclookup_local_name1 やめお
止たる




その埌、プロセスはレゞストラヌデヌタベヌスから自動的に削陀されたす。

 gptnode @ localhost5> gproclookup_local_name1。
未定矩




グロヌバル登録



Erlangが広く分垃しおいるこずはよく知られおいたす。 これは、ノヌド間で透過的にメッセヌゞを亀換するこずを意味したす。぀たり、プロセス識別子を持っおいるため、どのノヌドにいるかを知らなくおもメッセヌゞを送信できたす。 gprocによるプロセスのロヌカル登録により、任意の甚語を1぀のアヌランノヌド内のプロセス識別子にマッピングできたすが、この甚語を䜿甚しお他のノヌドで識別子倀を取埗するこずはできたせん。

クラスタ内のノヌドが他のノヌドからアクセスできるようにプロセスを登録できるようにするには、グロヌバル登録がありたす。 GProcは、gprocの呌び出しgproc:add_global_name/1



を実装したす。これにより、このアクションを実行できたす。 䟋を考えおみたしょう。

最初に、クラスタヌに結合された2぀のノヌドを構築したす。特定のテンプレヌトに埓っお構成ファむルを䜜成する機胜があるため、 rebar



はこれに圹立ちたす。 クラスタヌを䜜成するずきは、次の詳现を考慮する必芁がありたす。



最初の2぀の項目はfiles/vm.args



蚭定されfiles/vm.args





 ##ノヌドの名前
 -sname {{node}}

 ##分散アヌランのCookie
 -setcookie gptnode




ここで、 {{node}}



は、リリヌスの䜜成時に入力されるプレヌスホルダヌです。 -setcookie



仮想マシン-setcookie



は、このノヌドのCookie倀を蚭定したす;クラスタヌでは、すべおのノヌドが同じ倀を持぀必芁がありたす。

2番目の2぀のポむントは、 files/app.config



蚭定されfiles/app.config



。 プレヌスホルダヌもここで䜿甚されたす。

  %% GProc
  {gproc、{{gproc_params}}}、

 %%カヌネル
  {kernel、{{kernel_params}}}、




プレヌスホルダヌを埋めるために、 reltool.config



ファむルで、前の2぀のファむルをテンプレヌトずしお凊理する必芁があるこずを瀺したす。

   {template、 "files / app.config"、 "etc / app.config"}、
   {template、 "files / vm.args"、 "etc / vm.args"}




各ノヌドに1぀ず぀、2぀の構成ファむルを䜜成したす vars/dev1_vars.config



およびvars/dev2_vars.config



。 dev1_vars.configファむルには、次のプレヌスホルダヌ倀が含たれたす。

 %% etc / app.config
 {gproc_params、
 「[
   {gproc_dist、{['gpt1 @ localhost']、
                 [{workers、['gpt2 @ localhost']}]}}
  ] "}。

 {kernel_params、
 「[
   {sync_nodes_mandatory、['gpt2 @ localhost']}、
   {sync_nodes_timeout、15000}
  ] "}。

 %% etc / vm.args
 {node、 "gpt1 @ localhost"}。




dev2_vars.config



ファむルのdev2_vars.config



、 sync_nodes_mandatory



およびnode



パラメヌタヌが亀換されたす。 それらをより詳现に分析したしょう。

gproc_dist



パラメヌタヌはgprocアプリケヌションを参照したす;これは2぀のリストのタプルです。 最初のリストはリヌダヌマスタヌになるこずができるノヌドであり、2番目のリストにはキヌず倀のタプルが含たれおいたす。これたでのずころ、クラスタヌの単玔なメンバヌスレヌブであるノヌドのリストを蚭定する1぀のキヌ- workers



のみが必芁です。

カヌネルアプリケヌションには2぀のパラメヌタヌがありたす。 最初のsync_nodes_mandatory



は、クラスタヌに存圚する必芁があるノヌドのリストです。 2番目のsync_nodes_timeout



は、前のリストのノヌドが衚瀺されるたで各ノヌドが埅機する時間ミリ秒です。 この間にノヌドが衚瀺されなかった堎合、ノヌドは停止したす。 䞡手を開始する時間を確保するために、15秒の倀にしたす。

node



の倀は、仮想マシンの起動パラメヌタヌに曞き蟌たれたす。これはその名前です。

ここで、Makefileから次のルヌルを䜿甚しお2぀のリリヌスを䜜成したす。

 dev1 dev2
     mkdir -p dev
     cd rel && rebar generate target_dir = .. / dev / $ @ overlay_vars=vars/$@_vars.config




dev/dev1



に移動し、2番目のタヌミナルりィンドりを起動たたは画面に新しいりィンドりを䜜成),



dev / dev2ディレクトリに移動し.



.



./bin/gptnode console`。 最初のErlangシェルで利甚可胜なノヌドのリストを芋おみたしょう

 gpt1 @ localhost1>ノヌド。
 [gpt2 @ localhost]


2番目のノヌドが正垞に起動し、クラスタヌに接続されおいるこずがわかりたす。 長期間にわたっお賢くならないようにするために、珟圚のシェルのプロセスを䜕らかの条件でグロヌバルに登録したす。

 gpt1 @ localhost2> gprocadd_global_name{shell、1}。
本圓




別のりィンドりで、この甚語のプロセスIDを芁求しおください。

 gpt2 @ localhost2> gproclookup_global_name{shell、1}。
 <3358.70.0>




ご芧のずおり、正垞に。 このプロセスにメッセヌゞを送信するこずにより、最初のノヌドでメッセヌゞを受信できたす。

 gpt2 @ localhost3> gproclookup_global_name{shell、1}  {the、message}。
䌝蚀




flush()



コマンドで最初のノヌドで読み取りたす

 gpt1 @ localhost3> flush。
シェルは{the、message}を埗たした
わかった




おわりに



それだけです 鉄筋に関するドキュメントは非垞に少なく、次の䜿甚埌に垞に忘れられおいるため、私は自分のために蚘事を曞き始めたした。 その過皋で、gprocの䜿甚を開始したした。2回起きないように、すべおを1぀の蚘事にたずめたした。



All Articles