7

趣味で、マイクロサービス アーキテクチャを使用していくつかの Web アプリケーションを設計しています。構成管理を行うための最善の方法を決定しようとしていますが、構成に対する私のアプローチにはいくつかの大きな落とし穴があるのではないか、またはより良い方法が存在するのではないかと心配しています。

問題を組み立てるために、C++ で記述された認証サービス、Rust で記述された ID サービス、Haskell で記述された分析サービス、scala で記述されたいくつかの中間層、および JavaScript で記述されたフロントエンドがあるとします。対応する ID DB、認証 DB、分析 DB (おそらくセッションの redis キャッシュ) などもあります。これらのアプリはすべて docker swarm を使用してデプロイしています。

これらのアプリの 1 つが展開されるたびに、必ず他のすべてのアプリケーションを検出する必要があります。私は docker swarm を使用しているので、すべてのノードが必要なオーバーレイ ネットワークを共有している限り、検出は問題になりません。

ただし、各アプリケーションには依然としてアップストリーム サービスの host_addr、おそらくポート、一部の DB または封印されたサービスの資格情報などが必要です。

docker にはsecrets、アプリがコンテナーから構成を読み取れるようにする機能があることは知っていますが、各サービスの各言語で構成パーサーを作成する必要があります。これは厄介なようです。

私がむしろしたいのはconfiguration service、他のすべてのサービスを構成する方法に関する知識を維持する です。したがって、各アプリケーションは、実行時にアプリケーションの構成を取得するように設計された RPC 呼び出しで開始されます。何かのようなもの

int main() {
    AppConfig cfg = configClient.getConfiguration("APP_NAME");
    // do application things... and pass around cfg
    return 0;
}

AppConfig は IDL で定義されるため、クラスはすぐに使用可能になり、言語に依存しなくなります。

これは良い解決策のように思えますが、おそらく私はここでポイントを逃しています。大規模であっても、いくつかの構成サービスで数万のノードを簡単に処理できるため、スケーリングの問題は予想されません。繰り返しますが、これは単なる趣味のプロジェクトですが、「もしも」のシナリオについて考えるのが好きです :)

構成スキームはマイクロサービス アーキテクチャでどのように処理されますか? これは合理的なアプローチのように思えますか? Facebook、Google、LinkedIn、AWS などの主要なプレーヤーは何をしていますか?

4

2 に答える 2

0

良い解決策はありませんが、考慮すべき問題をいくつか指摘できます。

まず、アプリケーションには、構成サービスを見つけて接続できるようにするブートストラップ構成が必要になると思われます。たとえば、リモート プロシージャ コールをサポートするミドルウェア システム用に、IDL を使用して構成サービス API を定義すると述べました。CORBA IDL のようなものを意味していると思います。これは、ブートストラップ構成が接続先のエンドポイント (おそらく文字列化された IOR またはパス/in/naming/service として指定される) だけでなく、使用している CORBA 製品の構成ファイルでもあることを意味します。その CORBA 製品の構成ファイルを構成サービスからダウンロードすることはできません。鶏が先か卵が先かという状況になるからです。そのため、代わりに、アプリケーション インスタンスごとに CORBA 製品の構成ファイルの個別のコピーを手動で維持する必要があります。

次に、疑似コードの例では、単一の RPC 呼び出しを使用して、アプリケーションのすべての構成を一度に取得することを提案しています。この粗いレベルの粒度が良いです。代わりに、アプリケーションが個別の RPC 呼び出しを使用して各名前 = 値のペアを取得した場合、大きなスケーラビリティの問題が発生する可能性があります。説明のために、アプリケーションの構成に 100 個の名前=値のペアがあると仮定すると、構成データを取得するために 100 回の RPC 呼び出しを行う必要があります。次のスケーラビリティの問題を予測できます。

  • たとえば、アプリケーションと構成サーバーが同じローカル エリア ネットワーク上にある場合、各 RPC の往復時間は 1 ミリ秒かかる可能性があるため、アプリケーションの起動時間は 100 回の RPC 呼び出しごとに 1 ミリ秒 = 100 ミリ秒 = 0.1 秒となります。 . それは受け入れられるように思えるかもしれません。しかし、別の大陸に別のアプリケーション インスタンスを展開し、たとえば往復レイテンシが 50 ミリ秒の場合、その新しいアプリケーション インスタンスの起動時間は、1 回の呼び出しあたり 50 ミリ秒のレイテンシで 100 回の RPC コール = 5 秒になります。痛い!

  • 構成データを取得するために 100 回の RPC 呼び出しのみを行う必要があるのは、アプリケーションが各名前=値のペアを 1 回取得し、その情報をオブジェクトのインスタンス変数などにキャッシュしてから、後でname=valueのペアにアクセスすることを前提としています。そのローカルキャッシュ。ただし、遅かれ早かれ誰かが-loopx = cfg.lookup("variable-name")内から呼び出されforます。これは、アプリケーションがループのたびに RPC を作成することを意味します。明らかに、これはそのアプリケーション インスタンスの速度を低下させますが、数十または数百のアプリケーション インスタンスがそれを実行することになる場合、構成サービスは 1 秒あたり数百または数千の要求で圧倒され、集中化されたパフォーマンスのボトルネックになります。

  • 起動時に 100 回の RPC を実行して構成データを取得し、終了するまで数時間または数日間実行する、寿命の長いアプリケーションの作成から始める場合があります。これらのアプリケーションは、他のアプリケーションが RPC 経由で通信できる CORBA サーバーであると仮定しましょう。遅かれ早かれ、次のようなことを行うコマンドライン ユーティリティを作成することを決定するかもしれません。アプリケーション インスタンスを「クエリ」してステータスの詳細を取得します。アプリケーション インスタンスに正常な終了を要求します。等々。これらのコマンド ライン ユーティリティはそれぞれ短命です。起動時に、RPC を使用して構成データを取得し、サーバー プロセスに対して 1 つの RPC を作成して ping/クエリ/kill することで「実際の」作業を行い、その後終了します。今度は、数十または数百のアプリケーション インスタンスごとに、これらの ping コマンドとクエリ コマンドを 1 秒に 1 回呼び出す UNIX シェル スクリプトを誰かが作成します。この一見無害なシェル スクリプトは、1 秒間に数十または数百の短期間のプロセスを作成する役割を担い、それらの短期間のプロセスのうち、集中化された構成サーバーに対して多数の RPC 呼び出しを行って取得します。name=valueのペアは一度に 1 つずつです。この種のシェル スクリプトは、集中型の構成サーバーに大きな負荷をかける可能性があります。

集中構成サーバーの設計を思いとどまらせようとしているわけではありません。上記の点は、考慮する必要があるスケーラビリティの問題について警告しているだけです。アプリケーションがすべての構成データを 1 回の粗粒度 RPC 呼び出しで取得するように計画すると、前述のスケーラビリティの問題を回避するのに確実に役立ちます。

考える材料を提供するために、別のアプローチを検討することをお勧めします。各アプリケーションの構成ファイルを Web サーバーに保存できます。アプリケーションのシェル起動スクリプト「ラッパー」は、次のことを実行できます。

  • wgetまたはを使用curlして、Web サーバーから「テンプレート」構成ファイルをダウンロードし、そのファイルをローカル ファイル システムに保存します。「テンプレート」構成ファイルは通常の構成ファイルですが、値のプレースホルダーがいくつかあります。プレースホルダーは のようになり${host_name}ます。

  • また、wgetまたはを使用curlして、 などの検索と置換のペアを含むファイルをダウンロードします${host_name}=host42.pizza.com

  • ダウンロードしたすべてのテンプレート構成ファイルに対してこれらの検索および置換用語のグローバル検索および置換を実行して、すぐに使用できる構成ファイルを生成します。またはスクリプト言語などの UNIX シェル ツールを使用sedして、このグローバルな検索と置換を実行できます。または、 Apache Velocityなどのテンプレート エンジンを使用することもできます。

  • コマンドライン引数を使用して path/to/downloaded/config/files を指定して、実際のアプリケーションを実行します。

于 2017-09-23T10:48:21.553 に答える