アーキテクチャ (IT)システムアーキテクト

マイクロサービス間の連携を正しく整理して、結合度を最小化(ロースカップリング)し、スケーラビリティを最大化するにはどうすればよいですか?

Hintsage AIアシスタントで面接を突破

回答。

マイクロサービス間の結合度を最小化(ロースカップリング)することは、現代のアーキテクチャの主要な原則の一つです。これは、非同期通信(メッセージキューやイベントバスを介して)を通じて、不要な直接的同期HTTP呼び出しを避け、明確なAPI契約を定義することで達成されます。

一般的な方法は、メッセージブローカー(RabbitMQ、Kafka、NATS)を使用し、マイクロサービスが自身の状態に関するイベントを公開し、購読者がそれに反応することです。

KafkaでのNode.jsによるイベントの公開および処理の例:

// producer.js const { Kafka } = require('kafkajs') const kafka = new Kafka({ clientId: 'order-service', brokers: ['kafka01:9092'] }) const producer = kafka.producer() await producer.connect() await producer.send({ topic: 'orders', messages: [ { value: JSON.stringify({orderId: 123}) } ] }) await producer.disconnect() // consumer.js const consumer = kafka.consumer({ groupId: 'payment-group' }) await consumer.connect() await consumer.subscribe({ topic: 'orders', fromBeginning: true }) await consumer.run({ eachMessage: async ({ topic, partition, message }) => { const order = JSON.parse(message.value.toString()) // 注文の処理 }})

主な特徴:

  • マイクロサービスは、形式化されたAPIまたは仲介者(キュー、バス)を介して通信します。
  • 各サービスは独自のデータベースを持っており(Database per Service)、ロックや競合を避けます。
  • 既存のものを変更せずに新しいサービスをその場で接続可能です。

ひっかけ質問。

質問: 複数のマイクロサービスに共通のデータベースを使用することはできますか?大規模なプロジェクトであっても?

いいえ、これは独立性の原則に違反し、タイトカップリングを引き起こし、スケーラビリティやメンテナンス性を悪化させます。別々のデータベースまたはスキーマを使用する必要があります。

質問: システムのスケーリングにおいて、サービス間の同期HTTP通信は許容される実践ですか?

同期HTTPリクエストはスケーラビリティが低く、ボトルネックになる可能性があります。非同期メカニズムを適用し、絶対に必要な場合にのみ同期呼び出しを行うことが推奨されます。

質問: アーキテクチャを変更せずに、マイクロサービスのインスタンス数を増やしてスケールアウトできますか?

いいえ、単にインスタンス数を増やすだけでは、結合度やアーキテクチャのボトルネックの問題は解決されません。ボトルネックの分析、キューの導入、キャッシング、サービスの責任分担が必要です。