モノリスのこぎり



この作品は、読者に既に知っていることを伝えずに、モノリスからマイクロサービスへの移行の原則を説明するという非常に困難な課題に直面しています。 マイクロサービスアーキテクチャは非常に人気があるので、著者は、2人に1人の読者がそのようなアーキテクチャを扱っているか、自分の魂のすべての繊維でそれを嫌っていると確信しています。 また、これらの行を読んでいる開発者のほとんどは、マイクロサービスになった後、マイクロサービスに基づいてプロジェクトに参加したと考えられています。 そして、モノリスからマイクロサービスに独自に道を進んだ人たちのごく一部は、シニア開発者、アーキテクト、またはプロジェクトマネージャーとして働くのに十分な経験があります。







アプリケーションが絶対君主制から断片化された封建制に移行する時が来たら、ほとんどの時間は長年にわたって蓄積された技術的負債の返済に費やされるでしょう。 そして、この借金は名誉に返済する必要があります-彼自身が負っているものと彼のすべての前任者が負っているものを返済する必要があります。 このプロセスには、「私のもの」と「私のものではない」という概念はありませんが、現在プロジェクトに参加するのに十分な幸運ではない開発者の勇敢な勇気の概念しかありません。 プログラマーは彼の大君主の真の家臣であり、多くのアーキテクチャエラー、テストの欠如、多数のアンチパターンとの戦いに突入する必要があります。







可能な場合、既存のコードが変更されていないマイクロサービスへの移行の失敗例は多数あります。 しかし、新しい機能は別のリポジトリで作成され、メインの既存のコードをブラックボックスとして使用していました。 その結果、膨大な量の機能の重複、データの重複が形成され、悪魔は何か他のものを知っています。 メインプロジェクトはサポートされなくなり、依存関係は絶望的に古くなっていました。 そのようなプロジェクトのタスクは、すべての機能を完全にカバーし、サービスのみを介して外部で作業するために、メインプロジェクトの周りに十分な数のマイクロサービスを記述することでした。 そして、この瞬間が達成されたと同時に、計画によると、ブラックボックスの機能を新しく作成されたマイクロサービスに置き換える必要がありました。 原則として、このようなアプリケーションは、メインのレガシーコードに依存することはありません。







もちろん、誰もが「リファクタリング」と言うことができます。これは、額を7スパンにする必要がないためです。 ファウラーとファウラーのファンと彼の嫌いな人によって書かれた100冊の本にリストされているリファクタリング方法について話すことはもう少し難しいですが、まだ一般的です。 それをしない方法の巨大で複雑な例と、実際には絶対に適用できない完全に選択された球面真空の例を示し始めるのは完全に無意味です。 また、問題を作成するプログラマーである人たちは、長く成長し、もはや成長していないことを考慮する価値があります。 または、逆に、彼らは頭を入力してそのような記事を読むことさえできません。







また、完璧なコードと完璧なプロジェクトを検討するのは退屈で面白くないことにも注意してください。 完璧に分析的に配置されたプログラマーの頭の中では、コードがどのように見えるべきかを常に知っています。 私たちは常に、極端な精度と皮肉で、悪いコードと恐ろしいコードを区別できます。 ただし、6か月前に自分のコードを見て、「馬鹿が何を書いたのか!」と叫ぶ論理的なtrapに陥ることもあります。 ちなみに、これはこれらの同じ半年間の開発者の高度な専門的開発を確認するだけです。







さらに、著者は論理的なtrapに陥るつもりはなく、読者がアプリオリをより良く知っている問題について読者と議論します。 したがって、注目を集める声明を進める前に、1つの重要な共通の特徴を持つ仮想プロジェクトをさらに検討することに同意します。 まあ、それはひどいです。 目を閉じて、想像できる真空中で最も恐ろしい球形のプロジェクトを想像する必要があります。 言うまでもなく、他の自尊心のあるエンタープライズプロジェクトと同様に、非常に安定して動作し、動作し、そして最も重要なことには、利益を上げます。 彼は、そのようなプロジェクトに必要なものすべてを持っています:顧客、満足した顧客、技術サポート、そして外部からの素晴らしい眺め。 それはひどい内部にあり、勇敢なナイトプログラマーのみがそれについて知っており、誰もリファクタリングしたことのないリファクタリングの準備ができています。 どこからか、著者は経験豊富な開発者がそれほど困難なくこれを提示するという自信を持っています。







しかし、それでも、コードのクリーンさに関するいくつかの戦略とルールについて言及する必要があります。 コードを改善し、マイクロサービスライフに備えるための最初の目標は、これらのルールから生じます。







マイクロサービス計画



すべての間違ったマネージャーと上級開発者にとって好きなことは、理由の有無にかかわらず計画することです。 しかし、著者は計画を完全に放棄することを強く勧めていません。プロジェクトに有能な計画がないため、開発はムースが燃える森を駆け抜けるようなものになります。 しかし、マイクロサービスへの移行という観点からの長期計画のプロセスは、非常にありがたい仕事です。 個々のクラスまたはライブラリをリファクタリングする方法を多かれ少なかれ正確に言うことができますが、初期段階でマイクロサービスアーキテクチャ全体を考えて推測することは非常に困難です。 このような早期計画の目標は、コードまたは現在のアーキテクチャにリンクすることなく、プロジェクトをいくつかの論理的な部分に分割することです。 実際、アプリケーションが実行していることと、これらの機能のどれが独立しているかを修正するために。 そして、毎週月曜日の朝にこのリストに戻って、ホットコーヒーを飲み、書かれた一連の機能を修正し、努力する必要があるものを確認します。







グローバル変数とシングルトーン



すべての少年が知っているグローバルスコープで変数を使用するのが悪いのはなぜですか。 母乳であっても、各開発者はそのようなデータの保存と変更が競争力とスケーリングの問題につながるという知識を吸収します。 もちろん、これは本当です。 しかし、リファクタリングの観点からすると、グローバル変数は、重複することなく個別に構成されたサーバーに機能を転送することが不可能になるという点で悪いです。 それとは別に、グローバルに設定されたオブジェクトを持つライブラリに言及する価値があります。 たとえば、デフォルトでdockerを操作するためrubyライブラリは 、グローバルに利用可能なシングルトンを介してdocker環境へのアクセスを構成します。







Docker.url = 'tcp://example.com:5422' Docker::Container.create({ 'Cmd' => ['ls'], 'Image' => 'base' })
      
      





グローバルにアクセス可能な変数を使用する







もちろん、このタイプの構成はこのライブラリの初期接続を保存しましたが、同時に複数のDockerホストを操作しているときに水平方向にスケーリングすることを不可能にしました。 このようなプロジェクトでは、dockerを使用した作業はすべての抽象化レベルに浸透しており、1回のリクエストでdockerホストの選択を規制することはできません。 幸いなことに、このライブラリの作成者は、複数のホストを操作する機能を提供しています。 各コマンドには、ホストを定義できる追加のオプションパラメータがあります。







 connections = [ Docker::Connection.new('tcp://example.com:2375', {}), Docker::Connection.new('tcp://example2.com:2375', {}), Docker::Connection.new('tcp://example3.com:2375', {}) ] Docker::Container.create({ 'Cmd' => ['ls'], 'Image' => 'base' }, connections.sample)
      
      





複数のサーバー間の誇張された最も単純なラウンドロビン実装







グローバルオブジェクトを破棄する最も簡単で明白な方法は、単純な正式な事実上のパラメーターに移ることです。 抽象化のいくつかのレイヤーで使用されるオブジェクトは、使用されるレイヤーの最上部でローカル変数として宣言され、正式な実際のパラメーターを介してグローバル変数が使用されていたすべての場所に渡される必要があります。







しかし、注意してください。 このアプローチのコインの裏側は、仮パラメーターの数がすでに膨大な場合です。 そのような場合、正しいリファクタリングの本は、このプロセスへの実用的なアプローチを推奨しています-機能の一部を別々のクラスに取り入れ、単一のデータ構造のように一連のパラメーターを操作し、メソッドを強調表示し、その他の正しいことを行います。







プロキシクラスとプロキシメソッド



モノリシックアプリケーションからサービスを分離する移行における次のマイルストーンは、 責任の分離の 原則と唯一の責任の原則です 。 この段階では、この長くて骨の折れる旅の結果としてどのサービスが得られるかは完全に理解できないことを常に念頭に置く必要があり、すぐに別々の独立したコードを作成しようとはしません。 マーティンとデマルコの本を長い間、専門家の趣味で語り直し、彼らが読んだものを自分の考えとして伝えることができますが、これらの本の著者はこれをより簡潔にします。 その結果、グローバル変数とシングルトーンが利用できなくなったとしても、責任分離の原則に準拠しないコードを別のサービスに組み込むことは非常に困難です。







図書館



優れたライブラリは、適切に設計されており、重大な問題がなく、あらゆる理由でソースコードを読み直す必要がないライブラリです。 そして、よく書かれたサードパーティのライブラリを使用することで、プログラマーに偽りのない喜びをもたらすことができました。 そして、絶え間ない介入、非自明なオブジェクト指向言語、および多数のバグを必要とするライブラリーは、ライブラリー全体を地獄に投げ込み、独自のソリューションを作成することを望みます。 ほとんどの場合、この独自のソリューションはほとんど不快で自明ではありません。 そして、原則として、検討中のアプリケーションのタイプは、標準的な問題に対する膨大な数の独自のソリューションで構成されています。







結果として、全体から断片化への移行における次のステップは、手動による解決策の拒否と、よく知られたよく書かれたオープンソースライブラリへの移行です。 もちろん、必要な機能が単にライブラリの形で利用できない場合もあります。 この場合、そのようなライブラリとオープンソースコードをコミュニティに提供することが決定されます。 将来、この種のモノリシックアプリケーションのリファクタリングにより、異なるマイクロサービスで共通の機能を使用できるようになります。







オープンソースライブラリを作成するのは簡単ではないという意見があり、このプロセスに多くの時間を費やす必要があります。 ドキュメント、完全なテスト範囲、注釈、サービスファイルのサポート、リリースノート、および多くの非プログラミング作業。 それは非常に困難で疲れる。 さらに、誰でも読むことができるコードにより、開発者は書かれた内容に対してより敏感になり、ほとんどの開発者は他の人にコードを見せたがらず、悪いコードやい決定を判断することを恐れます。 著者には一般的な解決策はありませんが、ナイトとオーバーロードのアナロジーのみを知っています。 騎士は、この仕事やその仕事をするのがどれだけ面白いか尋ねられません。 必要です必要です







しかし、コードを汎用ライブラリーに入れることには、いくつかの明らかな利点があります。 これらのライブラリをサードパーティのアプリケーションで使用すると、まだ見つかっていないバグを取り除き、ライブラリが異なる環境で動作することを確認し、サードパーティの開発者が開発できるようにします。







また、行き過ぎて絶対にすべてをライブラリーに持ち込まないでください。 アプリケーションロジックは、アプリケーション自体の中に残っている必要があります。 一部のコードを別のライブラリに転送するための適切な基準は、異なるテーマとビジネスロジックを持つアプリケーションでこのライブラリを使用できるかどうかという質問です。







シンプルなデータ



この段階で、個別のエントリポイントと、隣接するエリア間の通信インターフェイスを備えたアプリケーションエリアがすでに形成されているはずです。 このリファクタリング段階のタスクは、正式な事実上のパラメーターの複雑な構造を取り除くことです。 もちろん、ハッシュとデータ配列を支持する構造クラスの軽率な放棄は状況を救いませんが、悪化させるだけです。 16個の正式な単純なパラメーターを持つ関数は、シリアル化の点では単純ですが、相互作用の点では非常に複雑です。 複合型の仮パラメータは、個別のサービス、ライブラリ、または独立したサブルーチンとして簡単に作成できます。







正式な事実上のパラメータを簡素化する目的は、単一のサブアプリケーションを独立したシステムプロセスに取り込む可能性です。 そして、そのようなプロセスとの通信は、標準化された言語に依存しないプロトコルの形式で形式化される必要があります。







公開されている標準



プロトコルは、すべての味と色のための全体の多数を思い付きました。 ほぼすべての言語で通信する一般的な方法については、さらに、受け入れられる解決策がほとんどありません。 前述のすべての指示を完了すると、アプリケーションは最終的に、個々の部分を個別のサブプログラムまたはサービスに移動する準備が整います。 アプリケーション間の通信に別の標準を選択する主な基準は、それを簡単に置き換え、一般化、拡張、または改善できることです。







すべてのマイクロサービス間の通信に単一の一般的にアクセス可能な標準を選択することは、アプリケーション全体の統合を意味すると考えるのは間違いです。 それどころか、サービス間の通信の統合により、個々のマイクロサービスは、アプリケーションの利益のためではなく、より良いためにアーキテクチャを微調整することができます。 サービス間の通信規格は異なる場合があり、特定の要件と条件に依存します。 新しいマイクロサービス用に標準を選択するときは、標準をゆっくりと調整して選択し、この標準またはその標準の長所と短所に批判的なアプローチを取る必要があります。 もちろん、この標準またはその標準が別のマイクロサービスで既に使用されているという事実は、他のすべてのものが等しい他のマイクロサービスよりも有利ですが、この基準だけが考慮されるべきではありません。







結論の代わりに



マイクロサービスアーキテクチャへの移行は骨の折れるプロセスです。 そして、レインボーライフを約束して建築に移行した後、プロジェクトのすべてが本当にバラ色になると思い込まないでください。 奇跡はありません。 また、この記事を呼び出して、プロジェクトをマイクロサービスアーキテクチャ移行 する必要はありません 。 すべてのプロジェクトがこれに対応できるわけではありません。







そして、因果関係を混同しないでください。 この記事では、プロジェクトの将来をマイクロサービスと結びつけることに決めた場合に、どのステップを踏む必要があるかについて説明します。 そして、その逆はありません。 この記事は、プロジェクトでマイクロサービスを使用するための呼び出しではありません。














All Articles