web-dev-qa-db-ja.com

Elixir / erlangはマイクロサービスアプローチのどこに当てはまりますか?

最近、複数の共同マイクロサービスをデプロイするために、Docker Composeを使用したいくつかの実験を行っています。マイクロサービスが提供する多くの利点を見ることができ、それらを管理するための優れたツールセットが存在するようになったので、マイクロサービスワゴンに飛び込むのはそれほど難しくないと思います。

しかし、私はElixirも実験しており、それ自体がもたらす利点を非常に気に入っています。コードを複数の分離されたアプリケーションにパックすることを奨励し、ホットコードアップグレードをサポートする場合、Dockerとelixir(またはアーラン)をどのように混在させますか?

たとえば、dev-prodパリティを提供するためにdockerを使用する場合、elixirはどのように適合しますか? Dockerコンテナは不変であるため、ホットコードアップグレードを行うことができません。ブルー/グリーン展開やカナリアリリースはどうですか?

つまり、Elixirでマイクロサービスを作成して、他の言語で書かれているかのように使用することができます。とにかく、多言語はマイクロサービスの利点の1つですが、OTPプラットフォームを使用することで十分な利点が得られません。純粋なコラボレーティブアーランアプリケーションは、中間キューを使用して異なる(またはそうでない)言語で記述されたマイクロサービス間で通信するよりもはるかに最適だと思います。

103
Papipo

これは非常に開かれた質問ですが、Elixir/Erlangが分散システムの開発に最適なプラットフォームである理由を説明します(マイクロサービスを使用しているかどうかに関係なく)。

まず、いくつかの背景から始めましょう。 Erlang VMおよびその標準ライブラリは、分散システムを構築するために事前に設計されたものであり、実際に表示されます。私の知る限り、それは唯一のランタイムであり、VM =このユースケース用に事前に設計された運用環境で広く使用されています。

用途

たとえば、あなたはすでに「アプリケーション」をほのめかしています。 Erlang/Elixirでは、コードは以下のアプリケーション内にパッケージ化されます。

  1. ユニットとして開始および停止されます。システムの起動と停止は、その中のすべてのアプリケーションを起動することの問題です
  2. 統一されたディレクトリ構造と構成API(XMLではありません!)を提供します。すでにOTPアプリケーションを使用して構成している場合は、他のアプリケーションを使用する方法を知っています。
  3. すべてのプロセス(プロセスとは、計算の軽量スレッドである「VMプロセス」を意味します)とその状態を含むアプリケーション監視ツリーを含みます

この設計の影響は非常に大きいです。つまり、Elixir開発者は、アプリケーションを作成するときに、次のことに対してより明確なアプローチをとることができます。

  1. コードの開始方法と停止方法
  2. アプリケーションの一部を構成するプロセスは何か、したがってアプリケーションの状態は何か
  3. クラッシュの場合、または何かがうまくいかない場合に、それらのプロセスがどのように反応し、影響を受けるか

それだけでなく、この抽象化のツールは素晴らしいです。 Elixirがインストールされている場合は、「iex」を開いて:observer.start()と入力します。ライブシステムに関する情報やグラフを表示する以外に、ランダムプロセスを強制終了したり、メモリ使用量や状態などを確認したりできます。これをPhoenixアプリケーションで実行する例を示します。

Observer running with a Phoenix application

ここでの違いは、アプリケーションとプロセスが、実稼働中のコードについて推論するために抽象化を提供することです。多くの言語は、主にランタイムシステムに反映されないコード編成用のパッケージ、オブジェクト、およびモジュールを提供します。クラス属性またはシングルトンオブジェクトがある場合:それを操作できるエンティティをどのように推論できますか?メモリリークまたはボトルネックがある場合、それを担当するエンティティをどのように見つけることができますか?

分散システムを実行している人に尋ねると、それは彼らが望む洞察の一種であり、Erlang/Elixirではそれを構築ブロックとして持っています。

コミュニケーション

これらはすべてほんの始まりに過ぎません。分散システムを構築するときは、通信プロトコルとデータシリアライザーを選択する必要があります。多くの人がHTTPとJSONを選択します。これについて考えると、実際のRPC呼び出しを実行するための非常に冗長で高価な組み合わせです。

Erlang/Elixirを使用すると、すぐに使用できる通信プロトコルとシリアル化メカニズムが既に用意されています。 2台のマシンが相互に通信するようにしたい場合は、それらに名前を付けるだけで、同じ秘密を持っていることを確認すれば完了です。

Jamieは、Erlang Factory 2015でこれについて話し、ゲームプラットフォームを構築するためにこれをどのように活用できるかについて話しました: https://www.youtube.com/watch?v=_i6n-eWiVn4

HTTPとJSONを使用する場合も問題ありません。PlugのようなライブラリとPhoenixのようなフレームワークは、ここでも生産性を保証します。

マイクロサービス

これまでのところ、マイクロサービスについては説明していません。それは、これまでのところ、彼らは本当に重要ではないからです。すでに分離されている非常に小さなプロセスを中心にシステムとノードを設計しています。必要に応じて、ナノサービスと呼んでください!

それだけでなく、アプリケーションにパッケージ化され、ユニットとして開始および停止できるエンティティとしてグループ化されます。アプリケーションA、B、およびCがあり、それらを[A、B] + [C]または[A] + [B] + [C]としてデプロイする場合は、そうすることにほとんど問題はありません。固有のデザインに。または、さらに良いことに、マイクロサービス展開の複雑さをシステムに前もって追加することを避けたい場合は、同じノードに完全に展開できます。

そして、1日の終わりに、これらすべてをErlang分散プロトコルを使用して実行している場合、異なるノードで実行でき、{:node@network, :name}で参照している限り、他のノードに到達できます。 :nameの代わりに。

さらに先に進むこともできますが、この時点であなたを納得させたと思います。 :)

130
José Valim