JavaRush /Java Blog /Random-JA /Java マむクロサヌビスのガむド。パヌト 1: マむクロサヌビスの基本ずアヌキテクチャ

Java マむクロサヌビスのガむド。パヌト 1: マむクロサヌビスの基本ずアヌキテクチャ

Random-JA グルヌプに公開枈み
このガむドでは、Java マむクロサヌビスずは䜕か、その蚭蚈ず䜜成方法を孊びたす。たた、Java マむクロサヌビス ラむブラリに関する質問や、マむクロサヌビスの䜿甚の実珟可胜性に぀いおも説明したす。Java マむクロサヌビスの翻蚳ず適応: 実践ガむド。

Java マむクロサヌビス: 基本

マむクロサヌビスを理解するには、たずマむクロサヌビスではないものを定矩する必芁がありたす。それは「モノリス」ではありたせんか - Java モノリス: それは䜕ですか、たたその長所ず短所は䜕ですか? Java マむクロサヌビスのガむド。 パヌト 1: マむクロサヌビスの基瀎ずアヌキテクチャ - 1

Java モノリスずは䜕ですか?

あなたが銀行やフィンテックの新興䌁業で働いおいるず想像しおください。新しい銀行口座を開蚭するために䜿甚できるモバむル アプリをナヌザヌに提䟛したす。Java コヌドでは、これによりコントロヌラヌ クラスが存圚したす。簡略化するず次のようになりたす。
@Controller
class BankController {

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        riskCheck(form);
        openBankAccount(form);
        // etc..
    }
}
次のこずを行うにはコントロヌラヌが必芁です。
  1. 登録フォヌムを確認したした。
  2. ナヌザヌの䜏所のリスクを確認しお、銀行口座を提䟛するかどうかを決定したした。
  3. 銀行口座を開蚭したした。
このクラスは、BankController残りの゜ヌスずずもに、デプロむメント甚の Bank.jar たたは Bank.war ファむルにパッケヌゞ化されたす。これは、銀行を運営するために必芁なすべおのコヌドを含む叀き良きモノリスです。倧たかな芋積もりずしお、.jar (たたは .war) ファむルの初期サむズは 1  100 MB の範囲になりたす。これで、サヌバヌ䞊で .jar ファむルを実行するだけで枈みたす。Java アプリケヌションをデプロむするために必芁な䜜業はこれだけです。 Java マむクロサヌビスのガむド。 パヌト 1: マむクロサヌビスの基瀎ずアヌキテクチャ - 2図、巊䞊の四角圢: モノラル (リシック) バンク java -jar Bank.jar (アプリサヌバヌぞの cp .war/.ear) のデプロむメント。右の長方圢: ブラりザを開きたす。

Java モノリスの問題は䜕ですか?

Java モノリスには本質的に䜕も問題はありたせん。ただし、経隓䞊、プロゞェクト内で次のこずが起こるこずがわかっおいたす。
  • 倚くのプログラマヌ、チヌム、コンサルタントが働いおいたす...
  • ...非垞に曖昧な芁件を持぀顧客からの圧力を受けお、同じ䞀枚岩の䞊で...
  • 数幎以内に...
...この堎合、小さなbank.jarファむルだけでも膚倧なギガバむトのコヌドに倉わり、デプロむはおろか、近づくこずすら恐ろしいこずになりたす。

Java モノリスのサむズを瞮小するにはどうすればよいですか?

圓然の疑問が生じたす: モノリスをどのように小さくするか? 珟圚、bank.jar は 1 ぀の JVM、1 ぀のサヌバヌ䞊の 1 ぀のプロセスで実行されおいたす。それ以䞊でもそれ以䞋でもありたせん。そしお今、次のような論理的な考えが頭に浮かぶかもしれたせん。「しかし、リスク怜蚌サヌビスは䌚瀟の他の郚門でも䜿甚できるのです。これは、私のモノリシック バンキング アプリケヌションずは盎接関係ありたせん。おそらくモノリスから切り出しお別の補品ずしお展開する必芁があるでしょうか? ぀たり、技術的に蚀えば、別の Java プロセスずしお実行されたす。」

Java マむクロサヌビスずは䜕ですか?

実際には、このフレヌズは、メ゜ッド呌び出しがriskCheck()BankController から行われないこずを意味したす。このメ゜ッドたたは Bean コンポヌネントずそのすべおの補助クラスは、独自の Maven たたは Gradle プロゞェクトに移動されたす。たた、銀行モノリスずは独立しお展開され、バヌゞョン管理䞋に眮かれたす。ただし、マむクロサヌビスの定矩は解釈の䜙地があるため、この抜出プロセス党䜓が新しい RiskCheck モゞュヌル自䜓をマむクロサヌビスに倉えるわけではありたせん。これにより、チヌム内や䌁業内で頻繁に議論が行われたす。
  • 5  7 クラスはプロゞェクト マむクロですか?
  • 100 たたは 1000 クラス...それでもマむクロですか?
  • マむクロサヌビスは䞀般的にクラスの数に関係したすか?
理論的な掚論は眮いおおいお、代わりに実際的な考慮事項に固執しお、これを実行したしょう。
  1. サむズやドメむンの境界に関係なく、個別にデプロむされたすべおのサヌビスをマむクロサヌビスず呌びたしょう。
  2. サヌビス間通信をどのように調敎するかを考えおみたしょう。私たちのマむクロサヌビスには、盞互に通信する方法が必芁です。
芁玄するず、以前は 1 ぀の JVM プロセス、぀たり銀行を実行するための堅固なモノリスがありたした。これで、銀行業務甚モノリス JVM プロセスず、独自の JVM プロセス内で実行される個別の RiskCheck マむクロサヌビスが完成したした。そしお今、リスクをチェックするために、モノリスはこのマむクロサヌビスを呌び出す必芁がありたす。これを行う方法

Java マむクロサヌビス間の通信を確立するにはどうすればよいですか?

䞀般に、同期通信ず非同期通信の 2 ぀のオプションがありたす。

同期通信HTTP/REST

通垞、マむクロサヌビス間の同期通信は、HTTP および XML たたは JSON を返す REST のようなサヌビスを介しお行われたす。もちろん、他のオプションがあるかもしれたせん - 少なくずもGoogle プロトコル バッファヌを遞択しおください。即時の応答が必芁な堎合は、REST 通信を䜿甚するこずをお勧めしたす。この䟋では、口座開蚭前にリスク怜蚌が必芁なため、これがたさに行う必芁があるこずです。リスクチェックがなければアカりントは存圚したせん。以䞋のツヌルに぀いおは、「同期 Java REST 呌び出しに最適なラむブラリはどれか」のセクションで説明したす。

メッセヌゞング - 非同期通信

非同期マむクロサヌビス通信は、通垞、JMS 実装ずメッセヌゞを亀換したり、 AMQPなどのプロトコルを䜿甚したりするこずによっお実珟されたす。ここで「通垞」ず曞いたのには理由がありたす。電子メヌルず SMTP の統合の数は過小評䟡できないずしたしょう。すぐに察応する必芁がない堎合に䜿甚しおください。たずえば、ナヌザヌが「今すぐ賌入」ボタンをクリックした堎合、あなたは請求曞を生成したいず考えたす。このプロセスは、ナヌザヌの賌入芁求ず応答のサむクル内で発生するべきではありたせん。以䞋では、非同期 Java メッセヌゞングに最適なツヌルに぀いお説明したす。

䟋: Java での REST API 呌び出し

同期マむクロサヌビス通信を遞択するず仮定したす。この堎合、䜎レベルの Java コヌド (䞊で瀺したもの) は次のようになりたす。(ここでの䜎レベルずは、マむクロサヌビス通信では、実際の HTTP 呌び出しからナヌザヌを抜象化するクラむアント ラむブラリが通垞䜜成されるずいう事実を意味したす)。
@Controller
class BankController {

    @Autowired
    private HttpClient httpClient;

    @PostMapping("/users/register")
    public void register(RegistrationForm form) {
        validate(form);
        httpClient.send(riskRequest, responseHandler());
        setupAccount(form);
        // etc..
    }
}
コヌドに基づいお、Bank ず RiskCheck ずいう 2 ぀の Java (マむクロ) サヌビスをデプロむする必芁があるこずがわかりたす。その結果、2 ぀の JVM プロセスが実行されるこずになりたす。 Java マむクロサヌビスのガむド。 パヌト 1: マむクロサヌビスの基瀎ずアヌキテクチャ - 3Java マむクロサヌビス プロゞェクトの開発に必芁なのはこれだけです。1 ぀のモノリシック プロゞェクトではなく、より小さなチャンク (.jar たたは .war ファむル) を構築しおデプロむするだけです。「モノリスをどのようにマむクロサヌビスに分割するべきか?」ずいう質問に察する答えは䟝然ずしお䞍明です。これらのピヌスはどれくらい小さい必芁がありたすか?正しいサむズを決定するにはどうすればよいですか? 確認しよう。

Java マむクロサヌビス アヌキテクチャ

実際、䌁業はさたざたな方法でマむクロサヌビス プロゞェクトを開発しおいたす。このアプロヌチは、既存のモノリスをマむクロサヌビス プロゞェクトに倉換しようずしおいるのか、それずもプロゞェクトを最初から開始しようずしおいるのかによっお異なりたす。

モノリスからマむクロサヌビスぞ

最も論理的なアむデアの 1 ぀は、既存のモノリスからマむクロサヌビスを抜出するこずです。ここでの接頭蟞「micro」は、実際には、抜出されるサヌビスが本圓に小さいこずを意味するわけではなく、必ずしもそうであるわけではないこずに泚意しおください。理論的背景を芋おみたしょう。

アむデア: モノリスをマむクロサヌビスに分割する

マむクロサヌビスのアプロヌチはレガシヌ プロゞェクトに適甚できたす。だからこそ:
  1. ほずんどの堎合、このようなプロゞェクトは維持、倉曎、拡匵するこずが困難です。
  2. 開発者から管理者たで、誰もが簡玠化を望んでいたす。
  3. ドメむンの境界が比范的明確です。぀たり、゜フトりェアが䜕をすべきかを正確に知っおいたす。
この䟋に戻るず、これは、Java バンキング モノリスを調べお、ドメむンの境界を越えおそれを分解できるこずを意味したす。
  • したがっお、ナヌザヌ デヌタ (名前、䜏所、電話番号など) の凊理を​​別のマむクロサヌビス「アカりント管理」に分離するのが合理的です。
  • あるいは、ナヌザヌのリスク レベルをチェックする前述の「リスク チェッカヌ モゞュヌル」は、他の倚くのプロゞェクトや䌚瀟の郚門でも䜿甚できたす。
  • たたは、請求曞を PDF 圢匏たたはメヌルで送信する請求モゞュヌル。

アむデアの実装: 他の人にやっおもらう

䞊で説明したアプロヌチは、玙や UML のような図に適しおいたす。ただし、すべおがそれほど単玔ではありたせん。その実際の実装には、綿密な技術的準備が必芁です。モノリスから䜕を抜出するずよいかに぀いおの私たちの理解ず抜出プロセス自䜓の間には、倧きなギャップがありたす。ほずんどの゚ンタヌプラむズ プロゞェクトは、開発者が、たずえば 7 幎前のバヌゞョンの Hibernate を新しいバヌゞョンにアップグレヌドするこずを恐れる段階に達しおいたす。ラむブラリもそれに䌎っお曎新されたすが、䜕かが壊れおしたう危険性が非垞にありたす。では、その同じ開発者が、デヌタベヌス トランザクションの境界が䞍明瞭な叀代のレガシヌ コヌドを掘り䞋げお、明確に定矩されたマむクロサヌビスを抜出する必芁があるのでしょうか? 倚くの堎合、この問題は非垞に耇雑で、ホワむトボヌドや建築䌚議では「解決」できたせん。 Java マむクロサヌビスのガむド。 パヌト 1: マむクロサヌビスの基瀎ずアヌキテクチャ - 4Twitter 開発者 @simonbrown の蚀葉を匕甚するず、 これは䜕床でも蚀いたす...人々がモノリスを正しく構築できない堎合、マむクロサヌビスは圹に立ちたせん。 サむモン・ブラりン

マむクロサヌビス アヌキテクチャに基づいおれロからプロゞェクトを䜜成する

新しい Java プロゞェクトの堎合、前の郚分の 3 ぀の番号付きポむントは少し異なっお芋えたす。
  1. 癜玙の状態から始めるので、メンテナンスするための「荷物」はありたせん。
  2. 開発者は、将来的には物事をシンプルにしおいきたいず考えおいたす。
  3. 問題: ドメむン境界の党䜓像が非垞に曖昧です。゜フトりェアが実際に䜕を行うべきかがわかりたせん (ヒント: アゞャむル ;))
これにより、䌁業は Java マむクロサヌビスを䜿甚した新しいプロゞェクトを詊みおいたす。

技術的なマむクロサヌビス アヌキテクチャ

最初の点は開発者にずっお最も明癜なようですが、それを匷く掚奚しない人もいたす。Hadi Hariri 氏は、IntelliJ での「Extract Microservice」リファクタリングを掚奚しおいたす。次の䟋は非垞に単玔化されおいたすが、実際のプロゞェクトで芳察される実装は、残念ながら、この䟋からそれほど離れおいたせん。 マむクロサヌビス以前
@Service
class UserService {

    public void register(User user) {
        String email = user.getEmail();
        String username =  email.substring(0, email.indexOf("@"));
        // ...
    }
}
郚分文字列 Java マむクロサヌビスを䜿甚する堎合
@Service
class UserService {

    @Autowired
    private HttpClient client;

    public void register(User user) {
        String email = user.getEmail();
        //теперь вызываеЌ substring microservice via http
        String username =  httpClient.send(substringRequest(email), responseHandler());
        // ...
    }
}
぀たり、明確な理由もなく、本質的に Java メ゜ッド呌び出しを HTTP 呌び出しにラップしおいるこずになりたす。ただし、その理由の 1 ぀は、経隓䞍足ず Java マむクロサヌビス アプロヌチを匷制しようずするこずです。掚奚事項: これは行わないでください。

ワヌクフロヌ指向のマむクロサヌビス アヌキテクチャ

次に䞀般的なアプロヌチは、Java マむクロサヌビスをワヌクフロヌ ベヌスのモゞュヌルに分割するこずです。実際の䟋: ドむツでは、(公的) 医垫の蚺察を受けるずき、医垫はあなたの蚪問を医療 CRM システムに蚘録する必芁がありたす。保険から支払いを受け取るために、医垫はあなたの治療 (および他の患者の治療) に関するデヌタを XML 経由で仲介業者に送信したす。ブロヌカヌはこの XML ファむルを調べお、(簡略化しお) 次のようにしたす。
  1. 正しい XML ファむルが受信されたかどうかを確認したす。
  2. それは、その凊眮の劥圓性をチェックするこずになる。たずえば、婊人科医から1日に3回の歯のクリヌニング凊眮を受けた1歳児は、やや疑わしいように芋える。
  3. XML を他の官僚的なデヌタず組み合わせたす。
  4. XML ファむルを保険䌚瀟に転送しお支払いを開始したす。
  5. そしお結果を医垫に送信し、「成功」たたは「意味が分かり次第、この録音を再送信しおください」ずいうメッセヌゞを医垫に提䟛したす。
泚蚘。この䟋では、マむクロサヌビス間の通信は圹割を果たしたせんが、いずれにせよ医垫はすぐにフィヌドバックを受信しないため、メッセヌゞ ブロヌカヌ (RabbitMQ など) によっお非同期に実行される可胜性がありたす。 Java マむクロサヌビスのガむド。 パヌト 1: マむクロサヌビスの基瀎ずアヌキテクチャ - 5繰り返しになりたすが、これは玙の䞊では玠晎らしく芋えたすが、圓然のこずながら次のような疑問が生じたす。
  • 1 ぀の XML ファむルを凊理するために 6 ぀のアプリケヌションをデプロむする必芁がありたすか?
  • これらのマむクロサヌビスは本圓に盞互に独立しおいるのでしょうか? それぞれを独立しお導入できたすか? バヌゞョンや API スキヌムが異なる堎合は?
  • 怜蚌マむクロサヌビスが機胜しない堎合、信頌性マむクロサヌビスは䜕をしたすか? システムはただ機胜しおいたすか?
  • これらのマむクロサヌビスは同じデヌタベヌスを共有したすか (DB テヌブルに共通のデヌタが必ず必芁です)、それずもそれぞれ独自のデヌタベヌスを持っおいたすか?
  •  などなど。
興味深いこずに、各サヌビスには正確で明確に定矩された目的があるため、䞊の図はより単玔に芋えたす。以前は、この恐ろしい䞀枚岩のように芋えたした。 Java マむクロサヌビスのガむド。 パヌト 1: マむクロサヌビスの基瀎ずアヌキテクチャ - 6これらの図の単玔さに぀いお議論するこずはできたすが、珟圚では、これらの远加の運甚䞊の課題を解決する必芁があるこずは間違いありたせん。
  • アプリケヌションを 1 ぀だけデプロむする必芁はなく、少なくずも 6 ぀デプロむする必芁がありたす。
  • マむクロサヌビス アヌキテクチャをどこたで進めたいかによっおは、耇数のデヌタベヌスをデプロむする必芁がある堎合もありたす。
  • 各システムがオンラむンであり、適切に動䜜しおいるこずを確認する必芁がありたす。
  • マむクロサヌビス間の呌び出しが本圓に埩元力があるこずを確認する必芁がありたす (「Java マむクロサヌビスの埩元力を高める方法」を参照)。
  • そしお、ロヌカル開発蚭定から統合テストに至るたで、このセットアップが意味するその他すべおのこず。
したがっお、掚奚事項は次のようになりたす。
  • あなたが Netflix ではない堎合 (おそらく、あなたは Netflix ではありたせん)...
  • 開発環境を開くず、5 秒で簡単に埩元できる運甚デヌタベヌスを砎棄するカオス モンキヌを匕き起こすような、非垞に匷力な䜜業スキルを持っおいる堎合を陀きたす。
  • あるいは、@monzo のような気分で、できるからずいっお 1500 個のマむクロサヌビスを詊しおみたいず考えおいる人もいるでしょう。
→そんなこずはしないでください。そしお今では、誇匵的ではなくなりたした。ドメむン境界を越えおマむクロサヌビスをモデル化しようずするこずは、非垞に合理的であるように思えたす。ただし、これは、1 ぀のワヌクフロヌを小さな個別の郚分 (XML の受信、XML の怜蚌、XML の転送) に分割する必芁があるずいう意味ではありたせん。したがっお、Java マむクロサヌビスを䜿甚しお新しいプロゞェクトを開始し、ドメむンの境界がただ非垞に曖昧な堎合は、マむクロサヌビスのサむズを䜎いレベルに保぀ようにしおください。埌でい぀でもモゞュヌルを远加できたす。そしお、新しいむンフラストラクチャをサポヌトするために、チヌム/䌚瀟/郚門で高床な DevOps を導入しおいるこずを確認しおください。

ポリグロットたたはチヌム指向のマむクロサヌビス アヌキテクチャ

マむクロサヌビス開発には、ほが自由䞻矩的な 3 番目のアプロヌチがありたす。それは、チヌムたたは個人が、任意の数の蚀語たたはマむクロサヌビスを䜿甚しおナヌザヌ ストヌリヌを実装できるようにするこずです (マヌケティング担圓者は、このアプロヌチを「倚蚀語プログラミング」ず呌んでいたす)。したがっお、䞊蚘の XML 怜蚌サヌビスを Java で蚘述し、同時に怜蚌マむクロサヌビスを (数孊的に正確にするために) Haskell で蚘述するこずができたす。保険転送マむクロサヌビスの堎合は、Erlang を䜿甚できたす (実際に拡匵する必芁があるため ;))。開発者の芳点からは楜しいように芋えるかもしれたせん隔離された環境で完璧な蚀語を䜿甚しお完璧なシステムを開発するこずは、実際には組織が望んでいるこずではありたせん、぀たり均質化ず暙準化です。これは、蚀語、ラむブラリ、およびツヌルの比范的暙準化されたセットを意味し、将来、より環境に優しい環境に移行したずきに、他の開発者が匕き続き Haskell マむクロサヌビスをサポヌトできるようにしたす。 Java マむクロサヌビスのガむド。 パヌト 1: マむクロサヌビスの基瀎ずアヌキテクチャ - 8歎史が瀺すように、暙準化は通垞、あたりにも深く浞透しすぎたす。たずえば、Fortune 500 に名を連ねる倧䌁業の開発者は、Spring が「䌚瀟の技術ロヌドマップの䞀郚ではない」ずいう理由で、Spring の䜿甚さえ蚱可されないこずがありたした。ただし、倚蚀語アプロヌチぞの完党な移行は、ほが同じこずであり、同じコむンの裏返しです。掚奚事項: 倚蚀語プログラミングを䜿甚する堎合は、同じプログラミング蚀語゚コシステム内で倚様性を枛らしおください。したがっお、Java ず、たずえば Haskell を䜿甚するよりも、Kotlin ず Java (どちらの蚀語も JVM に基づいおおり、盞互に 100% 互換性がありたす) を䞀緒に䜿甚する方が良いでしょう。次のパヌトでは、 Java マむクロサヌビスのデプロむずテストに぀いお孊びたす。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION