web-dev-qa-db-ja.com

単一のDockerコンテナー内の2つのプロセス、または同じデータベースに接続する2つのサービス?

私は最近、Dockerコンテナーを使用してモノリシックアプリケーションをマイクロサービスアーキテクチャに移行し始めました。アプリの一般的なアイデアは次のとおりです。

データのスクレイピング->データのフォーマット->データをMySQLに保存-> REST API。

各ステップを個別のサービスに分割したい。私には2つの選択肢があると思います。ここでのマイクロサービスアーキテクチャのベストプラクティスは何ですか?

オプション1
スクレイパーサービス-削り取り、カフカに公開
Formatterサービス-Kafkaからのメッセージを消費し、フォーマットします
APIサービス-Kafkaメッセージを消費し、MySQLを更新し、REST APIを公開します
欠点:私が間違っていない場合、Dockerコンテナーはコンテナーごとに1つのプロセスのみを実行する必要があります

オプション2
スクレイパーサービス-削り取り、カフカに公開
Formatterサービス-Kafkaからのメッセージを消費し、フォーマットします
DBサービスに保存-フォーマットされた情報を受け取り、MySQLを更新するだけです(pythonプロセスとして実行)
APIサービス-REST pythonフラスコでリクエストを処理するAPIを公開します。
欠点:同じDBに接続する2つのサービス。分離されないため、おそらく推奨されません

ここでのベストプラクティスは何ですか?オプション1を使用してflask serverとkafka listenerを同じコンテナで実行する必要がありますか?

ありがとう!

3
rogamba

私は次のように提案します。

  • スクレーパー:データをスクレイピングしてKafkaに公開します
  • フォーマッタ/永続性:Kafkaから読み取り、ストレージレイヤーにデータを送信します
  • ストレージ:書き込みを実行する1つの「実際の」データベース。このdbを必要な数の読み取り専用コピーに複製します。
  • API:データを提供するために読み取り専用レプリカにのみアクセスします。

結果整合性の概念がここに登場します。レプリカやAPIコンテナは、必要に応じていくつでもスピンアップできますが、その代わりに、異なる(古い)データが返される場合があります。ある時点で、レプリカデータベースが更新され、APIが最新のデータの提供を開始します。この方法では、新しいデータを書き込んでも、読み取りの応答時間がボトルネックになることはありません。

2
RubberDuck

間違いなくそれはオプション2であり、1つのデプロイメントパッケージにグループ化された2つの実際に異なる責任(DBに保存+ APIに公開)を持つ1つのサービス(「APIサービス」)があるため、オプション1でも同じことを引き起こします。

これら2つのサービス(DBに保存してAPIに公開)は、両方のサービスで複製された共通のDAOレイヤーを共有できます。 OR「APIサービスへの公開」は読み取り専用であるため、同じdbと対話しても、完全に独立したサービスになります。

更新:2つのマイクロサービス間でデータベースを共有することがアンチパターンではないことを確認する必要がある場合のみ: http://microservices.io/patterns/data/shared-database.html

1
Tristan