アプリケーション開発Kubernetesあけましておめでとうございます。@mosuke5です。Shopは有名ですよね。Shopの紹介やインストール記事がでています。Shopをいじっていけばいいかの情報が足りないと感じました。Shopから少しでも多くの学びが得られるようにこの記事を書きます。Shopはdocker-composeを始め、Kubernetesなど多様な環境で動かせるようになっています。この記事では、Kubernetesを例に書きますが、どの環境で動かしていただいても構いません。本ブログでは起動方法については割愛します。お好みの環境で動かしてみてください。Shopを動かしたい場合はこちらのレポジトリも参考にしてください。Goなどとマイクロサービスの特徴であるポリグロットを体現しています。ポリグロットな構成に「できる」、というだけで戦略なしに「やっていい」というわけではないので、この点は誤解ないように理解していきましょう。データ構造を見るまずは、データ構造を見ていきます。マイクロサービスでは、どこのサービスでどのようにデータを持つかは非常に重要です。Shopではデータベースを持つサービスが4つあります。下では、サンプルの出力結果を表示しておきますが、ぜひ自分の目で確かめていくといいです。(mongodb)catalogue靴下の商品情報や、靴下のタグの情報を管理するcatalogueサービスのデータベース構造を示します。MySQLを利用しており、非常にわかりやすいデータ構造となっています。sockテーブルでは靴下の情報をtagテーブルでは靴下のタグ情報を管理しており、それらは1対nの関係性なので、sock_tagテーブルで中間テーブルとして機能させています。|+--------+--------+user続いて、ユーザを管理するサービスです。mongodbのcollectionは3つ存在します。}}cart次は、ショッピングカートです。15}...order最後は、注文履歴を管理するorderサービスです。orderサービスの中では、注文した商品のIDのみ保有し、そのデータは持っていないことは少し頭の片隅に覚えておいてください。後ほど、サービスをまたいだデータの取得に関して考えていきます。88.29000091552734}データ分割による弊害このアプリケーションではマイクロサービス特有のデータの分割による問題がしっかり発生しています。靴下を注文したあと、注文履歴を見るページでは、注文の情報と注文した商品の情報の両方を表示しています。catalogueとorderの2つでサービスを分離しているため、これらの情報をまとめて取得することができません。どのように取得しているか見ていきます。下記のように、orderサービスに問い合わせたあと、注文した商品を別でcatalogueサービスに問い合わせにいっています。target=”_blank">該当のコード)。これは、マイクロサービスではよく発生します。解決へのアプローチはいくつかあります。どれがいいということはなく、データの特性などによるのですが、以下のようなポイントを考えていくといいと思います。そもそもデータの特性はどうか?リアルタイムに更新が必要な情報か。DBを非正規化して対応するか?オーダー処理をイベントとして保存しておくか?複数のitemを取得できるAPIをつくるか?共有データベースにしてしまうか?BFFで結合、キャッシュするか?item情報を同期するか?CQRSパターンを採用するか?APIを実行する商品オーダーのAPIなどは当然ながら認証しないとと実行できません。残念ながら、認証の方法などについてドキュメントに書いていなかったので補足していきます。認証はクッキーを使います。試しに、ログインセッションを持たないまま、オーダーAPIを実行してみるとログインしてくれとエラーが返ってきます。in.","error":{}}ログインには"username:password"をbase64でエンコードしたものが必要です(該当コード)。コマンドラインで生成するか、こちらのようなBase64エンコードをしてくれるWebサービスで生成しましょう。risk.xxxxxxxログインができているか確認します。オーダー情報が返ってきていれば成功です。}]ログインさえできてしまえば、同じ要領で他のAPIも実行することが可能です。マイクロサービスのメリットの中には、サービスが独立することによる、デプロイやスケールのしやすさや回復性があります。実際に特定のサービスの停止・スケール・デプロイをやってみます。cartsサービスの停止マイクロサービスの回復性について考えてみます。cartsサービスを落としてみて、どんな影響があるか確認してみます。deployment/cartsオーダーはできるか?他のコンポーネントへの影響は?ユーザ体験はどう変わったか?デグレードの実装cartsサービスを落としたあと、UI上からカートボタンが消えました。これは、よくあるデグレードの考え方を実装しているからです。マイクロサービスでは、利用するマイクロサービスがどういう状態か把握し、防御的な実装をいれることがあります。その1つの例になりますでしょうか。該当のコードサーキットブレーカについてcartsサービスを落とした状態で、ブラウザのデバッグツールを開いて、cartsサービスへの通信状況を見てみましょう。アクセスの度にcartsサービスのタイムアウトを待っているのがわかるのがわかります。このサンプルではサーキットブレーカの実装は入っていません。いった通信状況をみているとなぜサーキットブレーカが必要なのか、など感じてくるかと思います。front-endのスケールとデプロイマイクロサービスのスケーリングについて考えてみます。マイクロサービスでは特定のサービスのみをスケールすることが容易であることが特徴の1つです。以下、実行することは非常に簡単なわけですが、重要なのはそのサービスの独立性です。1サービスで1チームと仮に想定した場合、チームの動きやすさを想像することができると思います。ためしにフロントエンドサービスをスケールさせてみてみましょう。フロントエンドのコンテナイメージを変更してデプロイしてみます。サンプルで、背景色を変更したフロントエンドのイメージを用意しました。weaveworksdemos/front-end:0.3.12非同期通信マイクロサービスアーキテクチャでは、サービス間の通信をどのように行うかは重要な選択の1つです。Shopでも、アーキテクチャデザインの図を見ると、shippingサービスはRabbitMQに対してデータを送り、queue-masterが処理していることがわかります。shippingサービスとqueue-masterサービスのPodのログを見ながら、画面上からオーダー処理を行ってみましょう。ログからキューへの書き込みおよび、キューからの受信を確認することができます。非同期通信のメリットは、通信先の相手の状態に関係なく通信できることです。あなたがAWSなどのパブリッククラウドで仮想サーバを作成すると仮定します。作成する仮想サーバの設定をしたあと、作成ボタンを押してから実際にできあがるまで約5分程度かかります。同期的処理では、仮想サーバが出来上がるまでの間、ずっと待っていなければいけません。その間、ブラウザのタブを閉じたりしてはいけません。非同期処理では、「仮想サーバの作成を受け付けました」とレスポンスを先に返すことが可能であり、実際の作成は裏側で行うことができます。これにより、仮想サーバが出来上がるまでの間、自由に他のことをすることができます。一般的に、時間のかかる処理や、同期的な処理では間に合わない場合などに利用されることが多いです。Shopでは、トレーシングも体験することができます。jaegerなどのコンポーネントをデプロイします。デプロイについてはドキュメントには書かれておらず、Githubにあるマニフェストファイルを使って起動することが必要です。こちらを参考にしてください。下記のような画面にアクセスできれば成功です。Shopで購入などの様々なアクションを実行しましょう。Shop内でのアクションがjaeger内部に保存されていきます。http:/ordersを探してみましょう。靴下の注文処理の裏側では、userやpaymentなど複数のサービスにまたいで処理が行われていることがわかってきます。paymentサービスに障害が起きたと仮定し、paymentサービスを落としたあとに、もう一度購入操作をしてみましょう。この複雑な処理のなかでもどこでエラーが起きたか一目瞭然に確認することができます。Shopを使ったマイクロサービスの体験を紹介してきました。〇〇なことも体験できるよ、とかシナリオとして入れたほうがいい、というものがあればリクエストください。みなさんでマイクロサービスを理解するいいきっかけを作れればと思っています。Shopを使ったマイクロサービス体験のハンズオン「捉」2019年振り返りDevOpsの本質を科学的に理解する。LeanとDevOpsの科学を読んで。