Sam Newman の Principles Of Microservices
というセッション動画がかなり勉強になると同時に、耳の痛い所が色々とあって、もっと前に見たかったな〜としみじみと思った。ただ、後悔していても始まらないので、とりあえず、忘れないように内容のメモ。 ()の中は私の感想やら補足です。
動画
https://www.youtube.com/watch?v=PFQnNFe27kU
スライド (動画のとは違うイベントのだけど、中身はほぼ同じ)
https://www.slideshare.net/spnewman/principles-of-microservices-velocity
Sam Newmanはこの本の作者の方で、こっちの本もいいんですが、かなりのボリュームで、ボクはこの動画を知る前にこの本にチャレンジしたものの、読んでる内に何度も現在地を見失なってしまったので、、英語がある程度聞ける人はこっちの動画でエッセンスをつかんで、この本に突入するのも一つかなと。
http://www.amazon.co.jp/exec/obidos/ASIN/B00T3N7XB4/
http://www.amazon.co.jp/exec/obidos/ASIN/4873117607/
Why you need a principle
なぜprincipleの話をするかというと、Microservicesをやるにあたっては多くの選択/決定をしなければならないので、軸となるルールを持っておくことが大事だから。herokuのthe twelve factors的な感じ。
(これは本当そうだよな〜と。とりあえず、Microservicesだ〜と色々と分けて作ることは出来るけど、変な分け方をした所はボディブローのように苦しくなってくるし、かといって、作る前から全てを完全に見通すのはとても難しい。とりあえず、従うべきルールがあれば、そこをチェックすることで大きな設計ミスが防げるし、議論自体も、抽象的なものから、もう一歩踏み込んだ所でできそうかなと思った。)
Principle for microservice
Modelled Around Business Domain
- Domain Driven Design is a good place to start
- (エリック・エヴァンスの本を読み直した方が良さそう。)
Culture or Automation
- Infrastructure Automation, Automated Testing, Continuous Delivery
- 初期コストはかかるが、最初の仕組みが整えば、加速的にサービスを増やすことが可能になる。
Hide implementation details
- Hide your database. 例えば、複数のアプリケーションを同じテーブルにアクセスさせると、カラムの変更が複数アプリケーションにまたがってしまうのでNG。代わりに1つのアプリケーションにだけサクセスさせ、他のアプリケーションからはAPIでデータを取得できるように。
- 隠してる情報/フィールドをexposeするのは簡単だが、その逆は大変なので、最初はできるだけ隠す。
Decenterize All The Things
- self-service. 中央集権でなく、各チームで判断を下す。
- ここに書いてあることがいい感じ。 http://tech.gilt.com/2014/11/14/making-architecture-work-in-microservice
- とりまとめ役になるMessaging middleware はsimpleに。
Deploy Independently
- Most important!!! あなたのシステムがこれができている状態なら、結構、いい感じだよ。
- そして、これが守られていないなら、新しいサービスを足す前に、その状況を直す必要がある。
- 複雑性を避けるため、大体の人がone hostにmultiple application ではなく、one host, one applicationに帰結していく。 ただ、one host, one applicationは効率的なリソースの使い方とはいえないので、one host, multiple applicationを容易にする点が、dockerが人気を集めている一つの要因。
- consumer driven contract. consumerからのserviceの使い方を両者間の契約とみなし、service側の変更では、その契約に違反していない事をルールづける。(consumer driveの話はこの記事が参考になりそう。 http://techlife.cookpad.com/entry/2016/01/04/094705)
- consumerをservice側の変更と同時にデプロイすることを強要することはNG。service側は破壊的な変更はせずに新しいAPI end-pointを用意し、consumerのupgradeを待って、古いエンドポイントを削除。 ただし、bug fixとかのservice側のメンテナンスはちょっと大変。
Consumer First
- swagger
- 人間にも優しくね。 http://martinfowler.com/bliki/HumaneRegistry.html
Isolate Failure
- much easier to make less resilient, more machines, more network boundaries which can timeout. microservicesにすると、システムが堅牢になると思いがちだが、むしろ脆くなりやすい。マシンは増えるし、ネットワーク越しのやり取りも増えるから。
- あるモノリシックな1つの巨大システムを12個に分割したけど、そのどれか1つでも止まると、全部が上手く動かなくなるという分割をした会社があった。私なら、1個の巨大サービスに戻す事をオススメする!
- ↑のことを distributed single point of failure って名づけた人がいた。 (この言葉は言い得て妙で、気に入ってしまったw。)
- strangler app (level 7の振り分けのproxy layer?) を入れるパターンはあるあるだけど、そこがSPOFになりがち。一個のapplicationがthread poolを食いつぶしてしまうことで、全部のシステムがアクセス不可能になってしまう
- まずは妥当なtimeoutを設定しよう。
- thread poolをapplication単位で準備するとなお良し。一つのアプリケーションがハングしても、他のアプリケーションには問題なくアクセスできるように。bulk head pattern
- circuit breakers。エラーが繰り返される場合、timeoutを待たせるのではなく、素早くerrorを返してしまう。それにより二次災害を防ぐ。databaseアクセスにも使える。
Higly Observable
- log aggreation
- passing through correlation ids. 処理が始まった所でユニークなIDを発行し、全てのサービスのログで記録する。逆引きして、サービス間の依存関係をvisualizeするというお洒落なことをやってる人もいた。
- ただし、correlationが欲しくなった時にはこれを導入するコストも高いよ。デバッグが大変なくらいシステムが育ってるから必要になる訳で、ある意味必然。
- https://github.com/openzipkin/zipkin
Conclusion
(ちゃんとやればmicroservices怖くない。)