はじめに: インテリジェントな導入とスケーリング
モジュラーモノリスの主な利点の 1 つは、 導入の簡単さ: 単一のアーティファクト、単一の CI/CD パイプライン、単一のプロセスを監視します。しかし、シンプルさ それは制限を意味するものではありません。適切な戦略を使用すれば、モジュラーモノリスを次のように展開できます。 ダウンタイムゼロ、インテリジェントに拡張され、同じ洗練度で管理されます。 わずかな運用コストでマイクロサービス アーキテクチャを実現します。
この記事では、モジュラー モノリスの高度な展開戦略について説明します。 Blue-Green デプロイメント、デプロイメントとリリースを分離するための機能フラグ、に基づく自動スケーリング メトリクス、およびモジュールをスタンドアロン マイクロサービスとして抽出するタイミングを決定するための基準。
この記事で学べること
- ダウンタイムゼロでアップデートを実現する Blue-Green デプロイメント
- 機能フラグ: デプロイメントを機能リリースから切り離す
- Kubernetes HPA とカスタム メトリクスによる自動スケーリング
- コンテキストに応じたスケーリング: モジュールごとのリソースを最適化します。
- データベースのスケーリング: リードレプリカ、接続プーリング、シャーディング
- モジュールをマイクロサービスとして抽出する場合
- モジュラーモノリスの Kubernetes 構成の例
モノリシック導入: 一度構築すればどこにでも導入可能
モジュール式モノリスの展開は次の原則に従います。 「一度構築すれば、どこにでも展開できる」: 単一のアーティファクト (JAR、Docker イメージ) を一度ビルドすると、すべての環境にデプロイされます。 (ステージング、プロダクション、DR)。これにより、環境間の不一致のリスクが排除され、作業が簡素化されます。 CI/CD パイプラインを劇的に改善します。
# Pipeline CI/CD per modular monolith
# Un singolo artefatto per tutti gli ambienti
# .github/workflows/deploy.yml
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build application
run: ./gradlew build
- name: Build Docker image
run: |
docker build -t ecommerce-app:$GITHUB_SHA .
- name: Push to registry
run: |
docker push registry.example.com/ecommerce-app:$GITHUB_SHA
deploy-staging:
needs: build
runs-on: ubuntu-latest
steps:
- name: Deploy to staging
run: |
kubectl set image deployment/ecommerce \
app=registry.example.com/ecommerce-app:$GITHUB_SHA \
--namespace staging
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production # richiede approvazione manuale
steps:
- name: Deploy to production
run: |
kubectl set image deployment/ecommerce \
app=registry.example.com/ecommerce-app:$GITHUB_SHA \
--namespace production
Blue-Green 導入: ゼロダウンタイム
Il ブルーグリーン展開 は 2 つの同一の環境を維持します。 blue (アクティブ、トラフィックを処理) e green (非アクティブ、次のリリースの準備ができています)。 導入はアイドル環境で行われ、トラフィックの切り替えは全環境で瞬時に行われます。 ロードバランサーまたはKubernetesサービスの変更。
利点
- ダウンタイムゼロ: 切り替えは瞬時に行われ、ユーザーは中断されません。
- 即時ロールバック: 何か問題が発生した場合は、前の環境に戻るだけです
- 切り替え前の検証: 切り替える前に、グリーン環境で新しい展開をテストできます。
# Kubernetes: Blue-Green deployment con Service switch
# Blue deployment (attualmente attivo)
apiVersion: apps/v1
kind: Deployment
metadata:
name: ecommerce-blue
labels:
app: ecommerce
version: blue
spec:
replicas: 4
selector:
matchLabels:
app: ecommerce
version: blue
template:
metadata:
labels:
app: ecommerce
version: blue
spec:
containers:
- name: app
image: registry.example.com/ecommerce-app:v1.2.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
---
# Service che punta al deployment attivo
apiVersion: v1
kind: Service
metadata:
name: ecommerce-service
spec:
selector:
app: ecommerce
version: blue # Cambia in "green" per lo switch
ports:
- port: 80
targetPort: 8080
機能フラグ: デプロイメントとリリースの分離
I 機能フラグ コードをアクティブ化せずに実稼働環境にデプロイできるようになります。 すぐに。機能は、特定の目的に合わせて段階的にアクティブ化できます (カナリア リリース)。 ユーザー (ベータ テスト)、または特定の地域向け。これにより、瞬間が完全に切り離されます の 展開する (本番環境のコード) 当時のもの リリース (ユーザーに表示される機能)。
// Feature Flags con Spring Boot e Unleash
@Service
class OrderServiceImpl implements OrderModuleApi {
private final FeatureFlagService featureFlags;
@Override
public OrderDto createOrder(CreateOrderCommand cmd) {
Order order = Order.create(cmd);
// Feature flag: nuovo sistema di pricing
if (featureFlags.isEnabled("new-pricing-engine")) {
order.applyNewPricing(pricingEngine.calculate(cmd));
} else {
order.applyLegacyPricing(cmd.getItems());
}
// Feature flag: notifica push (graduale)
if (featureFlags.isEnabled("push-notifications",
cmd.getUserId())) {
notificationModule.sendPush(order);
}
orderRepository.save(order);
return order.toDto();
}
}
// Configurazione Feature Flags con Unleash
@Configuration
class FeatureFlagConfig {
@Bean
public Unleash unleash() {
return new DefaultUnleash(
UnleashConfig.builder()
.appName("ecommerce-app")
.instanceId("instance-1")
.unleashAPI("http://unleash:4242/api")
.build()
);
}
}
Kubernetes HPA による自動スケーリング
Il 水平ポッドオートスケーラー (HPA) Kubernetes は数値を自動的にスケールします CPU、メモリ、またはカスタム メトリックに基づいてポッドの数を決定します。モジュラーモノリスの場合、HPA アプリケーション全体を均一にスケーリングします。に基づいてカスタム メトリクスを構成できます。 1 分あたりの注文数などのビジネス固有の指標。
# HPA per il modular monolith
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ecommerce-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: ecommerce-app
minReplicas: 3
maxReplicas: 12
metrics:
# Scala basato su CPU
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
# Scala basato su metriche custom
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 120
データベースのスケーリング
モジュラーモノリスでは、多くの場合、データベースがコンピューティングよりも先にボトルネックになります。ここにいます データベースのスケーリング戦略:
返信を読む
設定する 返信を読む データベースと読み取りクエリをルーティングします。 と答える。書き込み操作はプライマリに行われます。これは特に効果的です CQRS パターン。読み取りモデルは専用レプリカ上に存在できます。
接続プーリング
次のような接続プーラーを使用します Pgバウンサー 接続を効率的に管理するため データベースに。モノリスのインスタンスが多数あると、データベース接続の数が増加する可能性があります すぐに。 PgBouncer は、有効なデータベース接続の数を減らします。
モジュールごとのシャーディング
特定のモジュールのデータ量が他のモジュールよりはるかに大きい場合は、そのテーブルを移動できます。 専用のデータベース上で。これは、マイクロサービスとして抽出するための中間ステップです。
モジュールをマイクロサービスとして抽出する場合
モジュール式モノリスは、必ずしも永遠にモノリスであり続ける必要はありません。データが それを正当化すると、モジュールは独立したマイクロサービスとして抽出できます。ここにあります 決定的な基準:
定量的基準
- 10倍スケーリング: このモジュールは他のモジュールより 10 倍のリソースを必要とします
- 導入頻度: モジュールには 5 倍の頻度のリリースが必要です
- SLA 遅延: モジュールには異なるレイテンシ SLA があります (例: クリティカル API の場合は 10ms 未満)
- チームの規模: 5 人以上の開発者がモジュールに専念して取り組んでいます
品質基準
- 技術スタック: モジュールは別の言語またはランタイムから恩恵を受けるでしょう
- 障害の分離: モジュールのバグによりシステム全体がクラッシュする可能性があります
- コンプライアンス: モジュールは、特定のセキュリティまたはコンプライアンスの要件に従ってデータを管理します
- キャッシング: モジュールには他のモジュールとは大きく異なるキャッシュ パターンがあります
抽出の経験則
完了するまで、モジュールをマイクロサービスとして抽出しないでください。 少なくとも 3 つの定量的基準 満足。時期尚早な抽出は分散型の複雑性をもたらしますが、メリットはありません 比例します。覚えておいてください: モジュラーモノリスは抽出を容易にするように設計されています 必要なときに、それを強制しないでください。
Kubernetes のセットアップを完了する
これは、モジュラーモノリスをデプロイするための参照 Kubernetes 構成です。 運用環境では、ヘルスチェック、リソース制限、およびアフィニティルールが使用されます。
# Deployment completo per modular monolith
apiVersion: apps/v1
kind: Deployment
metadata:
name: ecommerce-app
labels:
app: ecommerce
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: ecommerce
template:
metadata:
labels:
app: ecommerce
spec:
containers:
- name: app
image: registry.example.com/ecommerce-app:latest
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "production"
- name: JAVA_OPTS
value: "-Xms512m -Xmx2g -XX:+UseG1GC"
resources:
requests:
memory: "1Gi"
cpu: "500m"
limits:
memory: "2Gi"
cpu: "1000m"
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: ecommerce
監視と可観測性
モジュール式モノリスの大きな利点は、監視が簡単であることです。シングルで プロセス、メトリクスは一元管理され、ログは統合され、トレースはローカルに行われます。
- メトリクス: Spring Boot Actuator + Micrometer でメトリクスを Prometheus にエクスポート
- ログ: モジュール間のフローを追跡するための相関 ID を使用した構造化ログ
- 健康診断: 個々の健全性ステータスをチェックするための各モジュールのエンドポイント
- ダッシュボード: Grafana で集計されたモジュールごとのメトリクスを表示
次の記事
次の記事では、 段階的な移行 モノリスから レガシーからモジュール式モノリスへ: ストラングラー フィグ パターン、境界の特定、 物理モジュールの抽出、イベントの移行、現実的なタイムライン ケーススタディと指標を含めて。







