KomadのプリンシパルエンジニアであるSean Kelly氏は,去年のBoston Golang meetupでのライトニングトークを踏まえて,記事を書いている。 このライトニングトークにて,彼はマイクロサービスに対する経験を語った。 彼は,彼の講演や記事から聴衆が何を期待するべきか,というところから話を始めている。
私は,マイクロサービスに関する主な誤解と,“成果”について話します。 この話のもとは,従来のモノリシックアプリケーションを分割することで時間を節約しようと考えていた企業で働いていた人からのものです。 私は,この記事の結論として“マイクロサービス == 悪”とはしたくありません。 本記事を読んだ人がマイクロサービスベースのアーキテクチャを検討する際に,いくつかの課題を取り除く助けになることを願っています。
もちろん,マイクロサービスとは何か,を考えずして話を進めることはできない。 しかし,Kelly氏の指摘通り,"完璧"はない。 あるいは,大筋合意されている定義として以下のものがある。
実践において意味するところでは,マイクロサービスは可能な限りドメインを限定して扱います。 ですので,貴方の関心事のうち,目的に応じるために必要な分だけの仕事をするもの,と言えます。
また,ほとんどのマイクロサービス実践者は,マイクロサービス間の通信に,REST (HTTP)やRPCプロトコルを使用する。 このため開発者は,こういったことを行うのは極めて簡単だと考えている。
ある種類のREST APIでドメインの小さな部分をラップするだけで,私たちは誰もがネットワーク上でお互いに通信できるようになります。
残念ながら,これはKelly氏の発言の核心につながる。 彼は,経験からマイクロサービスに対する5つの"真実"を導いた。 これは,常に"真"になるとは限らないものである。 “ より良いコードを書くために,言い訳としてネットワーク境界を導入する必要はない。 ”
この問題に対する単純な事実は,マイクロサービスにしろ他の技術によるモデリングアプローチにしろ,クリーンで保守性の高いコードを書くための要件であることに変わりはない,ということです。 関与するものが少なくなれば,残念なコードを書いてしまうことが少なくなるのは確かです。 ただしそれは,店先に売れ筋商品をださなければ万引きが防げる,と言っているのと同じです。 問題が解決するのではなく,選択肢が減るだけです。
Kelly氏は,少なくとも最初は粗い粒度の"論理"サービスを考えるアプローチを薦めている。 Kelly氏によれば,いきなりマイクロサービスを考えるよりもこのやり方をとる方が良い点として,ネットワーク通信の削減がある。 彼はこれがサービス指向アーキテクチャー(SOA)に非常に似ていることを示唆している。 ここには一つ,未解決の質問がある。 SOAとマイクロサービスの違いは何か? これまで,これに関する議論はほとんど無かった。
Kelly氏によるマイクロサービスに関する次の"真実"は,一つの目的しか持たないものは,書くのが簡単である,である。
一見すると単純に感じるかも知れませんが,ほとんどのドメイン(特に新しい会社で,プロトタイプやピボットを必要としたり,何回もドメインを再定義する場合)は,小さな箱に納まるようになっていません。 多くの場合,ドメイン内の部品が他の部品とつながり,データを取得することでひとつのジョブが機能します。 自分のドメインの外にデータ書き込みの責務を委譲する場合は,さらに複雑になるでしょう。 自分の管理外の領域で,他者とのやりとりをしつつ,データを保存したり更新することになれば,貴方は分散トランザクションの世界に足を入れることになります(冒険談のようになりますね)。
冒険談が分散トランザクションの様相をとるとしても,分散トランザクション構築の全てが大冒険になるかどうかは,この際無視しよう。 Kelly氏の論の核心は,複数のリモートサービスを特定の要求にラップすると,様々な複雑さを引き起こしうるということである。 例えば,サービスは並列に呼んでよいのか,直列でなければいけないのか? エラーはどのように扱うか? このような複雑さに関しては,一例として他の識者Alvaro Videlaからの意見もある。
Kelly氏の第3の"真実"は,"マイクロサービスはモノリスより速い"である。
これは論破するのが難しいものです。 結合されたシステムより高速に動作する,独立したシステム群を作れることもあるからです。 ただしこれは極めて個別的な主張です。 マイクロサービスに焦点を当てた人は,サービス内で閉じたコードが高速化するのと同時に,ネットワーク通信が増加していることにも気づくはずです。 ネットワーク通信は,単一コード内での呼び出しより速くなることはありませんが,十分高速に動作することはあるでしょう。
Kelly氏は,少なくとも,マイクロサービスの高速化につながったと言われている例のいくつかには,他の要因,特に新しいアーキテクチャや再実装で使用された新しい言語やテクノロジスタックがあると考えている。 これらが元のモノリスに対して使用された場合にも,ある程度の性能改善はあったのではないか?
第4の"真実"は,’技術者が,一つのコードベースで全ての仕事をするのをやめさせることは簡単だ"である。 これに従っていると “分断されたコードベースで作業している技術者には,‘俺の仕事じゃない’シンドロームが発生しやすい”点をKelly氏は指摘する。 マイクロサービスアーキテクチャでは,潜在的な利益が減少するという問題を引き起こす恐れがある。
最大の問題は,単純に何を行うことになるか,です。 小さな変更を行うにも,沢山のサービスを動かすことになるのです。 技術者がローカルで全ての作業を行うための単純な方法を構築し保守するために,時間をかけ苦労する必要があります。[...] さらに,テスト記述は困難になります。 適切な結合テストのセットを書くためには,実行の可能性がある全てのサービスを理解する必要があります。 また,エラーの可能性も洗い出さなくてはいけません。
最後,5番目の"真実"は,"これは,オートスケーリングのための最も簡単な方法である。Dockerはどこかにある。"
水平スケーリングのアプローチとして,サービスを個々のユニットにパッケージングしてDockerなどでスケールするというのは確かに良い方法です。 しかし,これがマイクロサービスでしか実現できないというのは間違いです。 モノリシックアプリケーションであっても,これはうまくいきます。 [...] マイクロサービスは,このアプローチに自然と向かっていきますが,同じ手法をモノリシックなプロセスに対して適用することはできるでしょう。
Kelly氏は,こうしてライトニングトークを終えた。 一方,彼の記事には,開発者がマイクロサービスの使用を検討すべき時期についての議論がある。 彼は,開発者やアーキテクトが理解しておくべきこととして,以下のように記している。
ドメインの理解は重要です。 これがわかっていない場合,マイクロサービスには苦労が付きまとうでしょう。 逆に,ドメインを深く理解できていれば,境界がどこにあるかを知ることが出来ます。 ですので,マイクロサービスは,本来あるべき姿になっていくでしょう。
彼は,ワークフローに対する理解の重要性に対しても触れている(分散トランザクションに関する別のリファレンスもある)。 ワークフローの理解と合わせ,ワークフローのモニタリングも重要である。 恐らくモノリシックな実装の場合よりも重要になるだろう。 なぜなら,どのマイクロサービスがボトルネックになっているか,欠陥の原因かを突き止めるのが難しくなるからである。 マイクロサービスに飛びつく前にアーキテクチャを理解しよう,というSean氏の意見は,ある意味,これまで他者が述べてきたことと同じである。 例えば,Simon Brown氏によるDistributed Balls of Mudがある。
モノリシックシステムを構築していて,大きな泥の球になってしまった場合は,ソフトウェアアーキテクチャを十分に考慮しているかどうかを考え直した方がよいでしょう。 ソフトウェアの中核となる構造抽象概念は何かを本当に把握できていますか? インタフェースや責務は明確ですか? そうでないとしたら,マイクロサービスへの移行にはどのような利点があるのでしょうか? もちろん,サービスを物理的に分離すると,ショートカットができないように強制することはできます。 ですが,モノリスであっても同様の分離はできるでしょう。
Kelly氏の言葉で締めくくろう。これら全てを踏まえた上で,マイクロサービスを検討している人への一言は何か?
一言いえるとすれば, “内部の”サービスの構築に注力しましょう。 コードによりモジュールを明確に定義し,個々のサービスに向けて洗練し,来たるべき時に備えるのです。 このアプローチは,唯一の方法というわけではありません。 また,劣悪なコードに対する万能薬でもありません。 ですが,準備せずに一塊のマイクロサービスに取り組む場合よりもずっと早く,先に進めるでしょう。
Rate this Article
- Editor Review
- Chief Editor Action