Hi, I am Stanislav Yablonskiy, Lead Server Developer at Pixonic (MY.GAMES). そして今日、マイクロサービスについて話そう。 マイクロサービスはソフトウェア開発(主にバックエンド開発)のアプローチで、機能性は可能な限り小さなコンポーネントに分割され、それぞれ独立して動作します。各コンポーネントには独自のAPIがあります。 マイクロサービスは現在非常に人気がありますが、その使用は、ネットワーク、メモリ、CPUの面で大幅な上限を導入します。 それぞれの呼び出しは、ネットワーク上のデータの連続化、送信、受信の必要性に変わります. さらに、古典的なデータベースのトランザクションを使用することはもはや可能で、分散されたトランザクションまたは最終的な一貫性をもたらします。 分散トランザクションは遅く、高価であるが、最終的な一貫性は、トランザクションの結果がすぐに表示されず、データが一時的に不一致である可能性があることを意味する。 マイクロサービスを使用すると、他のサービスから既に書かれた論理にアクセスするのが困難であるため、開発者が各サービスにより多くのコードを書くように強制されます。 マイクロサービス「Overheads」 デビュー Overhead デバッグはマイクロサービスでより困難になります。通常のデバッグは、すべてのサービスを一度にデバッグすることはできませんので、このような状況ではほとんど役に立たないです。 これは、デバッグされているサービスだけでなく、そのすべての依存性(他のサービス、データベース、列など)も実行している特別な環境が必要であることを意味します。 HTTP オーバーヘッド HTTP プロトコルには多くの組み込まれた機能があり、さまざまなルート、パラメーターパッキング方法、応答コードをサポートし、多くの使用可能なサービス (プロキシを含む) によってサポートされていますが、軽量ではありません - それはすべてのサービスがパス、ヘッダー、およびパスを作成するためにあまり効率的なコードを多く実装するように強制します。 プロトボフ Overhead メッセージの受信時にネットワークコミュニケーションのための連続化と deserializationが必要です。 メッセージ交換のために protobuf を使用する際には、以下が必要です。 物体を作り、 これらをアリスに変え、 使用後はすぐに捨てましょう。 これはゴミコレクターやダイナミックメモリマネージャのための多くの追加作業を作成します。 ネットワーク Overhead ネットワーク経由でデータを転送すると、同じホスト上でマイクロサービスが実行されている場合でも、メモリとCPUの消費量が増加します。 メモリー Overhead メッセージの送信と受信には、追加のデータ構造を維持し、別々のスレッドを使用し、それらを同期する必要があります。 CPU オーバーヘッド もちろん、このすべてのプロセス間とコンテナ間のコミュニケーションには、コンピューティングリソースが必要です。 データベース Overhead 通常のトランザクションは、複数のマイクロサービスをカバーする場合に不可能である。分散されたトランザクションは、より遅く、複雑でしばしば手動の連携を必要とする。 ネットワーク・ディスクOverhead マイクロサービスコンテナはしばしばネットワークマウントディスクで実行されます. This increases latency, reduces performance (IOPS), and makes it unpredictable. プロジェクトBorder Overhead マイクロサービスの設計と開発は、プロジェクトの進化と再構築に困難をもたらします。 サービスの責任地帯を変えるのは簡単ではありません。 単に名前を変更したり、何かを削除したりすることはできません. あなたは単にコードを一つのサービスから別のサービスに移動することはできません。 これには通常必要: たくさんの時間と努力で、 いくつかの API バージョン、 機能がサービス間で再配布される前に、複雑な移行が行われます。 また、ライブラリを更新または置き換えたい場合は、1 つのプロジェクトだけでなく、すべてのプロジェクトで行う必要があります。 インフラ Overhead あなたは単に「マイクロサービスを行う」ことはできません。インフラストラクチャが必要です。 コンテナ(それぞれ共有図書館のコピーを含む) キューブレット、 クラウドサービス、 カフカ(RabbitMQ、カフカ) 構成同期ツール(Zookeeper、Etcd、Consul)など。 これらすべては、機械と人間の両方から膨大な資源を必要とします。 独立デプロイ Overhead 独立したデプロイメントを支援するには、以下のことを意味します。 各サービスは別々に展開可能で、 それぞれ独自のCI/CDパイプラインを持つ必要があります。 そして、一番難しい部分は、APIバージョン化です。 各サービスは複数の API バージョンを同時にサポートする必要があります. そして、呼び出し者はこれらのバージョンを追跡し、時間内に呼び出しを更新する必要があります。 ボール・オブ・ムード Distributed Ball of Mud クリーンなマイクロサービスの代わりに、機能が悪く分散され、外部通話が内部通話の連鎖を引き起こし、すべてが恐ろしく遅い分散された泥のボールに終わります。 モノリスって本当にそんなに怖いの? モジュールモノリス モジュラルモノリットは、ほとんどのマイクロサービスのオーバーヘッドを回避することを可能にし、必要に応じて後で使用できる分離を提供します。 このアプローチでは、アプリケーション(主にバックエンド)を単一のサービスとして個々のモジュールに分割し、以下のように書きます。 明確な境界線、そして、 最低限の相互依存性 これにより、スケーリングが本当にそれを必要とする場合にサービスに分割することが可能になります。 待ってね、やれるの? マイクロサービスアーキテクチャに与えられる多くの利点は、一つのモノリットで達成することができる。 Modularity は、言語機能(クラス、ネームスペース、プロジェクト、アセンブリ)で実装できます。 複数のデータベース – 可能な場合、本当に必要である場合 複数の言語 - 例えば、C/C++/C#/JavaとJava、Python、Erlangなどのスクリプト言語を組み合わせることも可能です。 Interop — 多くのプラットフォームは、Java、C#、Python、JavaScript、またはErlangからC/C++を呼び出すことをサポートします。 メッセージ列 - 適切なデータ構造を使用するだけです。 そして、あなたがデバッグしたいとき - キーを1つ押すと、すべてのアプリケーションはあなたの指先にあります。 アーティスト Frameworks Actor Frameworks では、マイクロサービスを構築することができます - マイクロサービスなしです。 すべての論理は、メッセージバス(クエー)を通じてのみ通信するクラス(俳優)に分かれています。 これらの俳優は: 単一のプロセスの中に存在するか、または、 複数のプロセスに分布します。 この方法では、マイクロサービスプログラミングモデルを取得しますが、ほとんどのインフラストラクチャはフレームワーク自体によって処理されます。 Conclusion 結論 アーキテクチャは、以下に基づいて選ぶべきです。 プロジェクト要件、 利用可能な資源、 チームの専門知識 マイクロサービスは、巨大なプロジェクトやチームにとって有用ですが、モノリスは時代遅れであり、デフォルトでは技術的な借金ではありません。 最も重要なのは、柔軟性と複雑性、スケーラビリティとメンテナンスのバランスをとり、あなたが構築するシステムが効果的で持続可能なようにすることです。