マイクロサービス:必要はありません



@alvaro_sanchezによるイラスト







しばらくの間、誰もがマイクロサービスに夢中になりました。 お気に入りのニュースアグリゲーターを開き、マイクロサービスの助けを借りてエンジニアリング部門を救うことについてこれまで知らなかった会社を見ないことは不可能でした。 おそらく、あなたは自分で働いていて、小さな、魔法のような小さなサービスの興奮に捕らわれ、大規模で実行中の完全なレガシーコードベースのすべての問題を解決するでしょう。







当然のことながら、実際にはまったく逆になりました。 何が起こったのかを振り返ると、将来の希望を持って見ているときよりも、ビジョンは100%に近くなります。







私は、マイクロサービスの癒しの性質のアイデアを確信している会社で働いていた人の観点から、マイクロサービスの運動のいくつかの重要な誤解と落とし穴について話したいです。 この記事の結論を「マイクロサービス==悪い」にしたくはありませんが、理想的には、マイクロサービスアーキテクチャが適切かどうかを判断する際に問題について考えていただきたいと思います。







一般的なマイクロサービスとは何ですか?



理想的な定義はありませんが、この分野を推進する人々は、「マイクロサービス」アーキテクチャに起因する可能性のある、システムの一連の要件を説明できました。







これはモノリスではないと言えます。 実際には、これは、可能な限り限られたタスク領域でのみマイクロサービスが機能することを意味します。 最小限の機能を実行して、スタックの特定の目標を達成します。 より具体的な例を次に示します。銀行に「ログインサービス」があり、もちろんこのサービスが顧客の金融取引にアクセスできないようにしたいとします。 この領域をある種の「トランザクションサービス」に移動します(覚えておいてください-名前を付けるのは非常に難しいです)。







さらに、多くの場合、マイクロサービスは他のサービスとリモートで通信する必要があることを暗示しています。 これらは独立したプロセスであり、他のプロセスから遠く離れて実行されることが多いため、通常、このようなプロセスはRESTまたは他のRPCプロトコルを使用してネットワーク上で相互に通信します。







これまでのところ、すべてが十分にシンプルに思えます。RESTAPIでシステムの小さな部分をラップし、全員がネットワークを介して互いに通信できるようにするだけです。 私の経験では、人々が信じている5つの「真実」がありますが、必ずしも真実ではありません。







  1. コードはきれいになります
  2. 1つの問題を解決するモジュールを書くのが簡単です
  3. モノリスよりも速く動作します
  4. 単一のコードベースで作業する必要がない場合、エンジニアにとって簡単です。
  5. これは自動スケーリングを有効にする最も簡単な方法であり、Dockerはどこかに関与しています。


誤解#1:よりクリーンなコード



「より良いコードの作成を正当化するためにネットワーク制限を追加する必要はありません。」







人生の真実は、マイクロサービスも、技術スタックをモデル化する他のアプローチも、よりクリーンで保守性の高いコードを書くための要件ではないということです。 もちろん、可動部品が少ないので、怠andで不適切なコードを書く能力は低下します。 しかし、これは、店の窓から商品を取り除くことで盗難を防ぐことができると言う方法です。 問題を解決できず、単に多くの機能を削除しました。







一般的なアプローチは、論理的な「サービス」がサブジェクト領域の一部を所有するような方法でアーキテクチャを構築することです。 これは、システムを制御する依存関係が明示的になるため、マイクロサービスの概念に似ています。 また、ビジネスロジックはさまざまな角度に適合しません。 さらに、このアプローチでは、ネットワークの過剰な使用や、これに関連する問題の可能性はありません。







このアプローチのもう1つの利点は、マイクロサービスに基づいて構築されたサービス指向アーキテクチャ(サービス指向アーキテクチャ)に似ていることです。部品を正しく分離するための領域。 真のSOAはコードから始まり、物理スタックトポロジのレベルで時間が経っても続きます。







誤解#2:より軽い



「分散トランザクションは決して簡単ではありません。」







外とは違うように見えるかもしれませんが、ほとんどのサブジェクトエリア(特にプロトタイプを作成し、ピボットを作成し、一般に何度もエリア自体を再定義する必要がある新しい会社)は、きれいで明確なボックスに分割できません。 多くの場合、正しく動作するために、システムの任意の部分が別の部分に関するデータを取得する必要があります。 ドメイン外の別の部分にデータを書き込む操作を委任すると、すべてがさらに複雑になります。 影響範囲を超えて、他の部分を使用してデータを保存または変更する必要がある場合は、 分散トランザクションの国にいます。







1つの要求に複数のリモートサービスが関係している場合、複雑さが大幅に増加します。 それらに並行してアクセスすることは可能ですか、それとも順番にアクセスする必要がありますか? 回路の任意の部分でいつでも発生する可能性のあるすべてのエラー(アプリケーションレベルおよびネットワークレベル)を事前に知っていますか?また、これらのエラーはリクエスト自体にどのような意味がありますか? 多くの場合、各分散トランザクションには、エラー処理に対する異なるアプローチが必要です。 そして、すべての間違いを理解し、それらを解決する方法を理解することは、非常に大きな仕事です。







誤解#3:より速い



「少し規律を加えると、モノリスのパフォーマンスを大幅に改善できます」







タスクの数やロードされる依存関係の数などを減らすと、実際には別のシステムを高速化できることが多いため、この誤解を論破するのは困難です。







しかし、全体として、これは体系的な証拠ではありません。 マイクロサービスに切り替えた場合、これらのサービスで分離されたコードが高速化されることは間違いありませんが、ネットワーク要求が原因で発生した遅延を忘れないでください。 ネットワークは内部通信ほど高速ではなく、「十分に高速」である場合があります。







さらに、パフォーマンスの改善に関する多くの話は、実際にはマイクロサービスアーキテクチャだけでなく、新しい言語またはテクノロジスタック全体の利点に関連しています。 古いRuby on Rails、Django、またはNodeJSアプリケーションをScalaやGo(マイクロサービスアーキテクチャの2つの一般的な選択肢)のような新しい言語で書き換えると、一般に新しいテクノロジのパフォーマンスが向上したためだけに、パフォーマンスが向上します。 しかし、これらの言語は、プロセスをマイクロと呼んでも問題になりません。 コンパイルなどの単純な要因により、より速く動作します。







また、ほとんどのスタートアップアプリケーションでは、純粋なプロセッサとメモリのパフォーマンスはほとんど問題になりません。 通常、問題はI / Oであり、追加のネットワークコールはI / Oを増加させるだけです。







誤解#4:エンジニアにとってより良い



多くのエンジニアが分離されたコードベースで作業しているとき、シンドロームは「これは私の問題ではありません」。







小さなチームがパズルの小さな断片に取り組むとき、物事はより簡単になるように思われるかもしれません。 しかし、最終的に、そのような構成は問題を引き起こす可能性があります。







最大の問題は、どんな小さな変更でも、増え続けるサービスを実行する必要があることです。 つまり、すべてのエンジニアがすべてをローカルで実行できるシステムを構築および維持するために、時間と労力を投資する必要があります。 Dockerのようなものはこの点を簡素化できますが、プロジェクトの存続期間中は誰かが構成を維持する必要があります。







さらに、これはテストの記述を複雑にします。 統合テストの通常のセットを作成するには、特定の操作に関連するすべてのサービスを理解し、考えられるすべてのエラーを考慮する必要があります。 システムの理解は、システムの開発よりも時間がかかります。 また、システムを理解することは時間の無駄であるとエンジニアに伝えることは決してありませんが、私はまだ時期尚早に複雑さを加えることに対して彼に警告したいと思います。







そして最後に、この構成は社会的な問題を引き起こします。 バグは複数のサービスに同時に存在する可能性があり、複数のチームのレベルでの変更が必要です。 彼らは努力を同期し、調整する必要があります。 さらに、人々は責任感を失い、できるだけ多くの問題を他のチームに押し出そうとするかもしれません。 エンジニアが同じコードベースで一緒に作業する場合、システムの理解はお互いの理解と同時に成長します。 彼らは小さな孤立した公国の王や女王であるよりも、問題を解決するために一緒に働く可能性が高いです。







誤解#5:スケールの改善



「マイクロサービスは、モノリスと同様に広範に拡張できます」







サービスを別々のユニットにまとめて、たとえばDockerでスケーリングすることは、間違いなく水平スケーリングに適したアプローチです。







ただし、これはマイクロサービスだけでなく実行できます。 このアプローチは、モノリシックアプリケーションでも機能します。 トラフィックの一部を処理する論理的なモノリシッククラスタを作成できます。 たとえば、着信APIリクエスト、コントロールパネルのフロントエンド、およびバックグラウンドタスクを同じコードベースに含めることができますが、各マシンで3種類のリクエストをすべて処理する必要はありません。







ここでの利点は、マイクロサービスの場合と同じです。個々のクラスターは、負荷に応じて構成でき、トラフィックの急増に対応して個別にスケーリングできます。 マイクロサービスアーキテクチャは最初からこのアプローチを推進していますが、モノリシックスタックのスケーリングに同じ方法を適用することを妨げるものはありません。







マイクロサービスを使用する場合



「エンジニアリング組織としての準備ができたら」







この記事を、マイクロサービスに切り替えるときが来たとき(または、既に開始している場合は、これが適切な瞬間であったかどうかを理解する方法)についての議論で締めくくりたいと思います。







優れた実用的なマイクロサービスアーキテクチャを実現するための最も重要なことは、対象分野を簡単に理解することです。 理解できない場合、またはまだ理解しようとしている場合、マイクロサービスはソリューションよりも多くの問題をもたらします。 ただし、すでに十分に理解している場合は、境界と依存関係に精通しているため、マイクロサービスアプローチが適切なステップになる可能性があります。







もう1つの重要なポイントは、作業環境、特に分散トランザクションのコンテキストでどのように見えるかです。 システム内のクエリの各カテゴリのパスに精通しており、これらのパスがどこで、どのように、なぜ壊れるかを理解している場合、クエリを処理するための分散モデルを構築できます。







環境の理解に加えて環境監視のトピックがあります。 これは、マイクロサービスとモノリスの議論を超えていますが、エンジニアリングの取り組みの中心には監視が必要です。 ほとんどの場合、システムのさまざまな部分に関する多くの情報が必要になりますが、その理由の1つが不適切に動作したり、エラーを生成したりする理由がわかります。 システムのコンポーネントを監視するための確立されたシステムがある場合、水平スケーリングでシステムの動作を理解できます。







そして最後に、エンジニアリング組織とビジネス全体の利点を実際に実証する場合、マイクロサービスへの移行は成長、拡大、および収益化に役立ちます。 もちろん、興味深いシステムを構築して新しいことを試すのはクールですが、最終的にはどの会社も最も重要な指標を持っています。 「モノリスが悪い」というブログへの投稿のために、会社にお金をもたらす新機能のリリースを延期する必要がある場合、この決定を正当化する必要があります。 時にはそれだけの価値がある。 時々ない。 いつ主張し、時間をかけるかを知ることは、長期的にあなたの評判を助けるでしょう。







結論



誰かがマイクロサービスのアプローチを提供する場合に解決する必要がある一連の条件と質問があることを願っています。 最初に言ったように、私の目標は「マイクロサービスが悪い」ことを証明することではありませんでした。 しかし、すべての詳細や質問を考えずにマイクロサービスにジャンプすることは、将来の問題を尋ねるためにすべて可能です。







アドバイスを求める場合、コード内の明確で明確に定義されたモジュールに基づいた「内部」サービスに目を向けます。 必要が生じた場合、将来これらのサービスにすでに導入することができます。 このアプローチは唯一の可能なアプローチではなく、間違いなく悪いコードの万能薬ではありません。 しかし、必要以上に早くマイクロサービスを掘り下げる場合よりも早く前進するのに役立ちます。








All Articles