時間の経過とともに、各プロジェクトは成長し、既存のモノリスに新しい機能を実装することは、ビジネスにとってより難しく、長く、より高価になります。
この問題の解決策の1つは、マイクロサービスアーキテクチャの使用です。 初心者またはこのアーキテクチャを初めて使用する人にとって、どこから始めて、何をする必要があり、何をする価値がないのかを把握するのは困難です。
この記事では、NodejsおよびRabbitMQで最も単純なマイクロサービスを作成し、モノリスをマイクロサービスに移行するプロセスを示します。
マイクロサービスアーキテクチャには何がありますか?
- ゲートウェイ 要求を受信し、それらを目的のマイクロサービスにリダイレクトするメインサーバー。 多くの場合、ゲートウェイにはビジネスロジックがありません。
- マイクロサービス。 マイクロサービス自体。明確に定義されたビジネスロジックでユーザーリクエストを処理します。
- 輸送 これは、ゲートウェイとマイクロサービスが通信する部分です。 トランスポートはHTTP、gRPC、RabbitMQなどです。
なぜRabbitMQなのか?
もちろん、RabbitMQを使用することはできません。マイクロサービス間の通信には他のオプションがあります。 最も単純なのはHTTPで、GoogleのgRPCがあります。
RabbitMQを使用しているのは、マイクロサービスの作成を開始するのに十分シンプルで、メッセージがキューに送信されたときに、メッセージがマイクロサービスに到達することを確認できるためです(現時点でオフにしてからオンにしても) ) これらの利点により、信頼性の高いマイクロサービスを作成し、シームレスな展開を使用できます。
開始する
最初に、特定のポートをリッスンしながらHTTPリクエストを受信する単純なゲートウェイを実装します。
RabbitMQを展開します(これを介して、マイクロサービスとゲートウェイが通信します)。
$ docker run -d -p 5672:5672 rabbitmq
プロジェクトを初期化し、 micromq NPMパッケージをインストールします。
$ npm init -y $ npm i micromq -S
ゲートウェイを書く
// Gateway micromq const Gateway = require('micromq/gateway'); // Gateway const app = new Gateway({ // , microservices: ['users'], // rabbitmq rabbit: { // rabbitmq (default: amqp://guest:guest@localhost:5672) url: process.env.RABBIT_URL, }, }); // /friends & /status GET app.get(['/friends', '/status'], async (req, res) => { // users await res.delegate('users'); }); // app.listen(process.env.PORT);
仕組み:
- サーバーが起動し、ポートのリッスンとリクエストの受信を開始します
- ユーザーはhttps://mysite.com/friendsにリクエストを送信します
- ゲートウェイは、説明したロジックに従って、要求を委任します。
3.1 RabbitMQキューにメッセージが送信されています(要求パラメーター、ヘッダー、接続情報など)
3.2。 マイクロサービスはこのキューをリッスンし、新しいリクエストを処理します。
3.3。 マイクロサービスはキューに応答を送信します
3.4。 ゲートウェイは応答キューをリッスンし、マイクロサービスから応答を受信します
3.5。 ゲートウェイはクライアントに応答を送信します - ユーザーは応答を受け取ります
マイクロサービスを書く
// MicroService micromq const MicroMQ = require('micromq'); // MicroService const app = new MicroMQ({ // ( , Gateway) name: 'users', // rabbitmq rabbit: { // rabbitmq (default: amqp://guest:guest@localhost:5672) url: process.env.RABBIT_URL, }, }); // /friends GET app.get('/friends', (req, res) => { // json res.json([ { id: 1, name: 'Mikhail Semin', }, { id: 2, name: 'Ivan Ivanov', }, ]); }); // /status GET app.get('/status', (req, res) => { // json res.json({ text: 'Thinking...', }); }); // app.start();
仕組み:
- マイクロサービスが開始し、ゲートウェイが書き込む要求キューのリッスンを開始します。
- マイクロサービスはリクエストを受信して処理し、利用可能なすべてのミドルウェアを実行します
- マイクロサービスは、ゲートウェイに応答を送信します
3.1。 メッセージがヘッダー(HTTPコードの応答本文)をRabbitMQキューに送信されています
3.2。 ゲートウェイはこのキューをリッスンし、メッセージを受信し、応答を送信する必要があるクライアントを見つけます
3.3ゲートウェイはクライアントに応答を送信します
マイクロサービスアーキテクチャへのMonolithの移行
既にエクスプレスアプリケーションがあり、マイクロサービスへの移植を開始するとします。
次のようになります。
const express = require('express'); const app = express(); app.get('/balance', (req, res) => { res.json({ amount: 500, }); }); app.get('/friends', (req, res) => { res.json([ { id: 1, name: 'Mikhail Semin', }, { id: 2, name: 'Ivan Ivanov', }, ]); }); app.get('/status', (req, res) => { res.json({ text: 'Thinking...', }); }); app.listen(process.env.PORT);
/フレンドと/ステータスの2つのエンドポイントを作成します。 これのために何をする必要がありますか?
- ビジネスロジックをマイクロサービスに取り込む
- これらの2つのエンドポイントに対するリクエストのマイクロサービスへの委任を実装します。
- マイクロサービスから応答を受信する
- 顧客に返信する
上記の例では、ユーザーマイクロサービスを作成するときに、2つのメソッド/ friendsおよび/ statusを実装しました。これらは、モノリスと同じことを行います。
ゲートウェイからマイクロサービスへのリクエストをプロキシするには、ミドルウェアをエクスプレスアプリケーションに接続して同じパッケージを使用します。
const express = require('express'); // Gateway micromq const Gateway = require('micromq/gateway'); const app = express(); // Gateway const gateway = new Gateway({ // ( , Gateway) microservices: ['users'], // rabbitmq rabbit: { // rabbitmq (default: amqp://guest:guest@localhost:5672) url: process.env.RABBIT_URL, }, }); // middleware , app.use(gateway.middleware()); // , app.get('/balance', (req, res) => { res.json({ amount: 500, }); }); // /friends & /status GET app.get(['/friends', '/status'], async (req, res) => { // users // res.delegate middleware, await res.delegate('users'); }); // app.listen(process.env.PORT);
これは、クリーンなゲートウェイを作成した上記の例と同じように機能します。 この例での唯一の違いは、ゲートウェイがリクエストを受け入れるのではなく、エクスプレスで書かれたモノリスであることです。
次は何ですか
- マイクロサービスからモノリス/ゲートウェイへのRPC(リモートアクションコール)(たとえば、承認のため)
- 各マイクロサービスには独自のデータベースがあるため、詳細については、RabbitMQキューを介してマイクロサービス間で通信します
これについては、 「RabbitMQを介したNode.js上のマイクロサービス間の通信の学習」という記事で既に述べています。