JSUG勉強会 2017年その7 俺たちのマイクロサービスへ行ってきた
週末風邪で倒れてたので初投稿です。
教科書の話ではなく、実プロジェクトの経験ベースの貴重な発表がきけました。
無理をしないマイクロサービス
資料は非公開。
実際にマイクロサービスを導入したときの話。
無理をしない
自分たちの体制や得意な技術に合うやり方で、これまでやりたくてもできなかったことをする。
実際にやったこと
最初はBigMonolith。リリーススピードをあげたい
- コンフリクトが発生すると解消に時間かかる
バックエンドをチーム毎に分割して、フロントエンドにUIサービスを置いてAPIで呼ぶ
- フロントエンドのUIが全チームで共有するため、フロントエンドでコンフリクトが発生
コンポーネント指向のSPAやBFFは、サーバーサイドスキル中心のチームで採用するのは厳しい(無理をする)
各サービスがUIまで持つ完結したアプリケーションの構成
- 注文、カート、オーダーといったアプリケーションが画面遷移で繋がってる構成
ユーザー情報の連携はもともとあったSSOの仕組みを利用
リンクのURLはSpringCloudConfigで一括管理
- 開発中とプロダクションで値の切替もできる
他のサービスと連携する部分はAPI
API呼び出しで障害が発生すると、障害の連鎖で最悪LBがダウンする
- 障害の連鎖を防ぐためのサーキットブレーカー(Hystrix)の導入
- Fallbackが注目されがちだが、障害の発生したAPIにアクセスさせないことが重要な目的
各APIにHystrixのアノテーションを書きたくないため、APIゲートウェイを導入しそこでサーキットブレーカーを設定
- 各チームの作業コストは0
Zuul2の開発は停滞中。yamlで定義がかけるSpringCloudGatewayが開発進行中
サービスディスカバリーは使わず、Cloud FoundryのRouterを利用
サービスディスカバリーの種類
CloudFoundryもサービスディスカバリーをプラットフォームで提供する予定
- アプリケーション側ではなく、プラットフォーム側でやるべき
最近はEnvoyがホット
- サービスメッシュを形成する
- メッシュを管理するIstioもホット
APIでクラスを共有すると、サービス側の変更でクライアントも影響を受けるので、サービス側がクライアントを提供する
- 破壊的変更がない限りは影響なし
k8sやCloudFoundryのようなXaaSを利用する
- k8sはコンテナから先を実装するCaaS
- CloudFoundryはコンテナやランタイム/ミドルウェアまでをプラットフォームが提供
Spring Bootはコンテナにする利点があまりないのでCloud Foundry
- コンテナにしてもjava -jarをするだけ
CI/CDのパイプラインはconcourse
- Concourse: CI that scales with your project
- Yamlで定義でき、1チームが作成した後コピペで増やせる
重要なこと
- やりたいこと(これまでできなかったこと)が解決できているか
- 技術を目的にしない
俺のマイクロサービス
- マイクロサービスは目指すものではなく結果論
- マイクロサービスには守破離の守がなく、こうやれば始められるというものがない
ECサイトの例
- もともとはオフショアで作られたシステムで品質がひどい
-
- 既存システムに比べて安定したが問題も
APIが画面項目とひも付き、再利用できない
- RDBの負荷が高い
- Tomcatを再起動するとセッションが初期化されるため、誰もアクセスして来ないであろう深夜にしかリリースできない
- 非同期処理がやっつけ
15のやったこと
1.SpringBootの導入
2.サービスディスカバリーとロードバランス
- Eurekaを導入。サービスメッシュは検討中
3.キューイング
- ファイルでやってたところを、オープンな仕様のAMQP(RabbitMQ)を導入
- 今ならSpringCloudStreamとkafka使うかも
4.セッションレプリケーション
- SpringSession+Hazelcastを利用。今の所は問題ないが、ヘビーに使い込んでないので、後ほど再評価したい
5.Versioned Platform
- Sprong+Javaで統一し、親Pomを各サービスで共有
6.shared interface
- 共通のインターフェースを提供し、コンパイルエラーで気付けるようにする
- 便利だったけどMSAっぽくないと言われる
7.client library
- 6はコンシューマーでインターフェースを実装しなければならず、同じコードがたくさんできて効率悪い
- 実装したクライアントをサービス側で配布。コンシューマー側の実装が楽に。
8.service unit test
- 各マイクロサービスは、Controllerに対してJunitテストを書く(必須)
- 別サービスの呼び出しはモックにする。Mokitoとかつかわず、オーバーライド。
- 複雑な計算等不安な部分は局所的に書く(任意)
- Http通信の部分はSpringbootを利用
- 正常系、異常系のJSONやバリデーションをテスト
9.Service integration test
- サービス結合で期待したデータと違う等のインターフェース齟齬が発生し試験が進まなかった。
- 複数のマイクロサービスを手動で立ち上げてテストする
- 実行をjunitにしておけば残しておける
- 数ケースだけでもかなり問題が検出できる(それくらいインターフェース齟齬が多かった)
10.CI/CD
- AnsibleとJenkinsを利用して環境構築を自動化
- APIのバージョニングをしていなかったので困っている。バージョニングはすごく重要
11.monitoring
- 障害がユーザーからの問い合わせで発覚することが多く監視が必要
- elasticsearchをつかって全サーバーのCPU、メモリ使用率、ディスク使用率やログを採取
- ログは5分間でてないと異常と判断
- 既存メッセージを取り除いて、未知のメッセージが出ているか調べる
- 気づかれなければいいで片付けない。
12.Frontend service & backend service
- 再利用できるバックエンド、再利用しない前提のフロント
13.serverless
14.separated data store
15.イベントソーシング
買い物かごのAPIを、データベース視点のCRUDや追加・削除のようなビジネスロジック的なAPIではなくイベントを登録するAPIだけ提供
- 商品を入れる、出すを全てイベントとして記録する。
データ不整合が発生しても、イベントなら何が原因かがトレースできる
- 処理の追い越しや不正な遷移が発生したときの対応は検討が必要
これからやりたこと
- サーキットブレーカー、リアクティブAPI、コンテナやプラットフォーム
感想とか
手段を目的にしないことが大事
自然と教科書の構成に近づいていく
- 教科書的な構成に合わせなくてもいい
- 自然と似てくる
サービスメッシュとか知らない言葉が増えてたので、常にトレースしていくのが重要
JSUGからのお知らせ
11/24にSpringFest2017
- 会場は両国KFCホール
- 前回と同じく400〜500人の規模を想定
来月の勉強会は10/27。会場は恵比寿のRedhat