TT Lab
はじめる
学ぶ 学習パス コース

マイクロサービスアーキテクチャ

モノリスを二つのサービスに分ける

TT Labで続きを見る

目標

注文と在庫が1つのプロセスに入っているモノリスを、契約を先に固定してから2つの独立したサービスに分離し、分離の前後でレスポンスが同じかどうかを自動で検証します。

なぜ重要なのか

サービス分離で実際に難しいのは、コードを移すことではありません。移した後でも同じ答えが出ることを確認すること、そしてデータの所有権まで一緒に移したかを確認することです。現場で最もよくある失敗は、「サービスは分けたのにテーブルは共有」です。こうなると、デプロイは独立しましたが、スキーマの変更には今でも2つのチームの合意が必要です。結合はコードではなくデータにあったからです。そのため、このラボではコードを移す前に契約(contract)をファイルとして先に固定し、最後にソースを検査して、データアクセスが本当に切れたかを確認します。ストラングラーフィグ方式では、ファサードの裏にある2つの実装が同じ答えを返すという確信がなければ、トラフィックを移せません。

ステップ

  1. /opt/fixtures/msa/monolith.pyを127.0.0.1:8101で起動し、GET /healthが200を返すようにしてください。
  2. モノリスのルートを調べて、/root/msa/seams.txtに1行に1つずつ경로 도메인の形式で書いてください(プレースホルダーはパスとドメインです)。ordersとinventoryの2つのドメインがどちらも登場し、最低4行なければなりません。
  3. /root/msa/contract.jsonを作成してください。最上位のキーはordersとinventoryの2つで、それぞれport(整数)とpaths(文字列の配列)を持ちます。ordersは8103、inventoryは8102です。
  4. /root/msa/inventory_svc.pyを作成して、127.0.0.1:8102で起動してください。GET /stock/SKU-1が{"sku":"SKU-1","qty":<정수>}を返します(プレースホルダーは整数です)。
  5. /root/msa/orders_svc.pyを作成して、127.0.0.1:8103で起動してください。POST /ordersは{"sku":"SKU-1","qty":2}を受け取って在庫サービスに問い合わせ、十分なら201とorder_idを、足りなければ409を返します。
  6. orders_svc.pyのソースに、/opt/fixtures/msa/inventory.jsonのような在庫データのパスがなく、代わりに8102への呼び出しがなければなりません。
  7. /root/msa/parity.shを作成してください。同じリクエストをモノリス(8101)と新しい注文サービス(8103)に送り、ステータスコードと判定が同じならPARITY OKを出力します。実行結果を/root/msa/parity.outに残してください。
  8. /root/msa/decision.mdに、## 쪼갠 이유と## 쪼개지 말았어야 할 이유の2つの見出しを入れて(韓国語の見出しで、それぞれ「分割した理由」「分割すべきでなかった理由」を意味します)、それぞれ30文字以上書いてください。

参考

モノリスを起動して基準線を取る

/opt/fixtures/msa/monolith.pyを127.0.0.1:8101で起動し、GET /healthが200を返すようにしてください。

/opt/fixtures/msa/monolith.pyをpython3で実行すると、8101番ポートで起動します。バックグラウンド実行(&)とログのリダイレクトを忘れないでください。

継ぎ目(seam)の一覧を作る

モノリスのルートを調べて、/root/msa/seams.txtに1行に1つずつ경로 도메인の形式で書いてください(プレースホルダーはパスとドメインです)。ordersとinventoryの2つのドメインがどちらも登場し、最低4行なければなりません。

分割する前に、境界の候補を先に書きます。モノリスのルート定義をgrepして、パスと担当するドメインを1行ずつ書いてください。

2つのサービスの契約を固定する

/root/msa/contract.jsonを作成してください。最上位のキーはordersとinventoryの2つで、それぞれport(整数)とpaths(文字列の配列)を持ちます。ordersは8103、inventoryは8102です。

コードより契約が先です。JSONで、サービス名、ポート、公開するパスを書きます。在庫サービスが何を約束するのかが要点です。

在庫サービスを分離する

/root/msa/inventory_svc.pyを作成して、127.0.0.1:8102で起動してください。GET /stock/SKU-1が{"sku":"SKU-1","qty":<정수>}を返します(プレースホルダーは整数です)。

在庫に関するロジックだけを新しいファイルに移して、8102で起動します。レスポンスは、skuとqtyを含むJSONでなければなりません。

注文サービスを分離する

/root/msa/orders_svc.pyを作成して、127.0.0.1:8103で起動してください。POST /ordersは{"sku":"SKU-1","qty":2}を受け取って在庫サービスに問い合わせ、十分なら201とorder_idを、足りなければ409を返します。

注文サービスは、在庫を直接読まずに、HTTPで問い合わせます。在庫が足りなければ409を返すのが契約です。

データの所有権が分離されたことを証明する

orders_svc.pyのソースに、/opt/fixtures/msa/inventory.jsonのような在庫データのパスがなく、代わりに8102への呼び出しがなければなりません。

注文サービスのソースに在庫データのファイルパスが残っていれば、まだ結合しています。ソースを検査してみてください。

モノリスとレスポンスの同等性を比較する

/root/msa/parity.shを作成してください。同じリクエストをモノリス(8101)と新しい注文サービス(8103)に送り、ステータスコードと判定が同じならPARITY OKを出力します。実行結果を/root/msa/parity.outに残してください。

同じ入力を2つの経路に入れて、結果を比較するスクリプトを書きます。2つのレスポンスが同じなら、PARITY OKを出力するようにしてください。

分離の判断の記録を残す

/root/msa/decision.mdに、## 쪼갠 이유と## 쪼개지 말았어야 할 이유の2つの見出しを入れて(韓国語の見出しで、それぞれ「分割した理由」「分割すべきでなかった理由」を意味します)、それぞれ30文字以上書いてください。

分割した根拠と、分割すべきでなかった根拠を、それぞれ書きます。指定された2つのマークダウンの見出しを正確に書かなければ、採点されません。