マイクロサービスアーキテクチャへの移行を進める上で生まれた課題にどう取り組んだのか。オイシックス・ラ・大地の川上徹氏がOisixのマイクロサービス移行後のテスト、CI/CD、運用監視を紹介します。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
これまでの連載では、ECサイトであるOisixをマイクロサービスアーキテクチャへ移行させていくアプローチについて解説してきたが、今回は移行させた後の開発・運用について解説する。
併せて前回まで触れてこなかった開発時に留意しておいた方がいい継続的なメンテナンスや運用に関する内容についても解説する。
本連載の第5回でも「パイプラインファースト」という言葉について説明したが、開発当初からCI/CD(継続的インテグレーション/継続的デプロイ)パイプラインを整備し、品質保証に十分な量のテストコードをコード変更の都度実行し、実績のある自動デプロイを行える環境が整っていることのメリットは非常に大きいと筆者は考えている。
マイクロサービスを導入するメリットである「変更に強い」システムを目指すのであれば、テストコードを充足させることは必須だろう。
テストコードといえばいわゆるクラスやモジュールをターゲットにした「単体テスト」「ユニットテスト」と呼ばれる領域のテストをカバーするものというイメージがあるかもしれないが、もう少し広範囲の領域をテストコードでカバーすることも可能だ。
Oisixではマイクロサービス開発のフレームワークとして「Spring Boot」を採用しているが、このフレームワークにはテストに関する機能も豊富にそろっている。
Spring Bootを用いて開発したアプリケーションはビルドしたアーカイブ(jar)を直接Webアプリケーションとして起動することが可能だが、それをテストコードの中で行い、HTTPリクエストを送信するテストも可能だ。
つまり、RESTful APIとして開発したマイクロサービス単体の振る舞いであれば、テストコードの中で品質を保証できるということであり、コードの変更をGitリポジトリにPushする都度テストを実行し、問題がないことを確認できる安心感は大きい。
もちろん重厚なテストを実装するとテストの実行時間は比例して長くなるため、CIパイプラインの並列化や、Webアプリケーションとして起動するテストはある程度集約してWebコンテナの起動回数を減らすなどの工夫も必要になる。
また、各マイクロサービスが利用するデータベースやインメモリデータストアなどのマネージドリソースをDockerコンテナとして用意し、テスト実行の都度環境を構築して使い捨てるといったアプローチも有効だ。
特にデータベースについてはアプリケーションのGitリポジトリ内にDDL(Data Definition Language)を保持し、それをテスト実行時に起動したDockerコンテナに対して適用する。テストコードからはそのDockerコンテナに対してアクセスさせるという方法だ。アプリケーションリポジトリ内で原本管理されているDDLを用いることで本番環境と確実に同等であることが保証されたテーブル構成の環境に対してテストが行えるので、品質の確認精度を向上することにつながる。
テスト実行時に指定したDockerコンテナを立ち上げる機能は多くのCIツールが提供しており、JVM言語を利用した開発を行っているのであれば、「Testcontainers」のようなテストコードからDockerコンテナを起動するテストフレームワークを利用することも可能だ。都度クリーンな環境を構築することで冪等(べきとう)なテストコードを実装しやすくなり、CIの安定性も向上するだろう。
変更に強く、スピーディーな開発を行っていくためには自動テストによる品質保証は重要なポイントであり、強く意識すべきだろう。
「変更に強い」システムを目指すのだから、1日に何度もリリースを行ったり、ユーザーのアクセスが頻繁に行われている中でのリリースを行ったりするなどの要件も出てくるはずだ。そのためには、安全なリリースへの配慮が必要になる。
意識すべきキーワードとしては、下記などになるだろう。
Oisixのマイクロサービス開発ではプラットフォームとして「Kubernetes」を採用しているため、Kubernetesを例に説明するが、マイクロサービスアーキテクチャを用いた開発であれば、考え方としては近しいものが必要となるはずだ。
まずGraceful Shutdownだ。これはアプリケーションが処理中のリクエストを完了してから停止するというものだ。あらかじめGraceful Shutdownの仕組みを導入しておくことで、稼働中のアプリケーションを入れ替える際にエラーとなってしまうリクエストの発生を防ぐことができる。
Kubernetesを使用している場合は、アプリケーションにリクエストの完了を確認するエンドポイントを用意しておき、PreStopイベント(コンテナの終了時にフックできるライフサイクルイベント)において、そのエンドポイントを実行するなどで実現可能だ。
続いてヘルスチェック。これはアプリケーションが正常に稼働しているかどうかをチェックするインジケーターである。リリース時に限らず、ロードバランサーがそのアプリケーションに対してリクエストを割り振っていいかどうかをチェックするための機構だ。
OisixではKubernetesの「LivenessProbe/ReadinessProbeの仕組み」を用いて「Spring Boot Actuator」のhealthエンドポイントを実行させている。これにより、アプリケーションがデータベースなどのマネージドリソースに対して接続できているかどうかを含めてヘルスチェックを行い、Kubernetesがコンテナに対してリクエストを割り振ってよいかどうか、あるいはコンテナを再起動すべきかどうかを自動的に判断できる。
Graceful Shutdownとヘルスチェックの考え方を踏まえて、ローリングアップデートの仕組みを実現する。大まかな流れは下記のようなものである。
Kubernetesを使用している場合、これらの振る舞いを「Manifest」と呼ばれるYAMLファイルに記述することで制御できる。ローリングアップデート時のコンテナ数(割合)なども柔軟に設定可能だ。
最後はカナリアリリースだ。これは新しいバージョンと古いバージョンのアプリケーションを一定期間混在して稼働させ、新しいバージョンのアプリケーションに問題がないことを本番の運用状態で確認するものだ。
プラットフォームとしてKubernetesを使用している場合は、「Istio」などを使用して構築可能である。これは、アプリケーションのシステム的な問題を確認しながらリリースすることの他に、一部のユーザーに対して先行して機能提供を行い、フィードバックを取り込んだ上で本格的なリリースを行うといったアプローチとしても有効な手法だ。
本連載の第6回でも解説した通り、OisixではIstioを用いて実現可能なリクエストを割合ベースで振り分けるカナリアリリースよりも細かい制御を必要としたため、「Feature Toggle」を活用したカナリアリリースを実現している。
Oisixではストラングラーパターンを用いてマイクロサービスアーキテクチャへの移行を進めているところだが、運用面で意識したポイントを紹介する。
まず特徴的なポイントとして、分散トレーシングの仕組みを導入したことだ。マイクロサービスアーキテクチャへ移行することにより、複数のアプリケーションが相互に連携するようになる。ユーザーのリクエストに対して複数のアプリケーションが動作することになるため、アプリケーションのログを通して確認できるようにする仕組みはもちろん、どのアプリケーションでの処理がボトルネックになっているのかを分析する仕組みが必要だ。
アプリケーションのログについては、Oisixでは「Spring Cloud Sleuth」を用いてユーザーからのリクエストを識別する「TraceId」、各アプリケーションでの動作を識別する「SpanId」を自動的に払い出し、出力したログにIDが付与される仕組みを構築している。
各アプリケーションが出力したログはマネージドのログ管理サービスに既存システムが出力するログも含めて一元的に集約し、システム全体のログとして検索、可視化を可能としている。障害時の調査などにおいては、アプリケーションをまたいだ振る舞いを確認できることが必要になるため、こうしたログ集約の仕組みは必須になると考えられる。
同様に、APM(Application Performance Management)サービスの導入を検討し、「マネージドサービスへのアクセスを含めて、ユーザーからのリクエストを処理する上で、どの部分がボトルネックになっているのか」を、アプリケーションをまたいで分析できる仕組みを構築しておくといいだろう。
本連載の第4回でも解説したが、マイクロサービスアーキテクチャでシステムを構成した場合、システム全体のうちどこかで障害が発生している可能性は相対的に高くなるため、「リトライパターン」や「サーキットブレーカーパターン」を用いて耐障害性の高いシステム構成としておくべきというのは解説した通りだ。
その上で、何を即時に対処すべき事象として監視するか(アラートを上げるか)という点については配慮が必要となる。基本的にはシステム全体としてのサービス継続に影響がある事象(外部からのURL外形監視が一定期間エラーを継続するなど)に限定し、アプリケーションでのリトライや、プラットフォームの仕組み(Kubernetesの自動回復の機構など)で自動的に解消可能な事象についてアラートを上げてしまうと運用メンバーの疲弊を招いてしまうだろう。
また、アラートについてはシステムを構成するマイクロサービスをまたいで一元的に集約し、システム全体としてインシデントが発生しているのかどうかを可視化可能な仕組みとしておくのが望ましいだろう。そういった監視集約を行えるサービスも存在するため、導入を検討するとよい。
連載を通して、マイクロサービスアーキテクチャへの移行を検討するに当たってのOisixにおける基本的な考え方について解説してきたが、いかがだっただろうか。何かの参考になれば幸いである。
金融系のSIerを経て2018年にオイシックス・ラ・大地入社。ECサイトOisixのマイクロサービス化に向けた開発プロセスの整備を実施。好きなプログラミング言語はKotlin。趣味は住宅ローンの繰り上げ返済。野菜よりはお肉が好き。
勉強会やイベントレポートを中心に更新中!
複雑化、老朽化、ブラックボックス化した既存システムの残存で、2025年以降に予想される経済損失は最大12兆円/年といわれている。これを経済産業省は「2025年の崖」と呼び、企業に警鐘を鳴らす「DXレポート」を公開した。レポートでは、システム開発に取り入れるべきアーキテクチャとして「マイクロサービス」を挙げている。本特集では、マイクロサービスとは何か、システムをマイクロサービスにさせるとどのような課題が生まれるのか、モノリシックなサービスをマイクロサービスに移行させた事例などを通じて、どの場面でマイクロサービスを活用すべきか、現実解を探る。
Copyright © ITmedia, Inc. All Rights Reserved.