microservices-architecture

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Microservices Architecture

微服务架构

Overview

概述

Comprehensive guide to designing, implementing, and maintaining microservices architectures. Covers service decomposition, communication patterns, data management, deployment strategies, and observability for distributed systems.
一份关于微服务架构设计、实现与维护的全面指南,涵盖服务拆分、通信模式、数据管理、部署策略以及分布式系统的可观测性等内容。

When to Use

适用场景

  • Designing new microservices architectures
  • Decomposing monolithic applications
  • Implementing service-to-service communication
  • Setting up API gateways and service mesh
  • Implementing service discovery
  • Managing distributed transactions
  • Designing inter-service data consistency
  • Scaling independent services
  • 设计全新的微服务架构
  • 拆分单体应用
  • 实现服务间通信
  • 搭建API网关与服务网格
  • 实现服务发现
  • 管理分布式事务
  • 设计服务间数据一致性方案
  • 独立服务的扩容

Instructions

操作指南

1. Service Boundary Design

1. 服务边界设计

Domain-Driven Design (DDD) Approach

领域驱动设计(DDD)方法

Bounded Contexts:
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│  Order Service  │  │  User Service   │  │ Payment Service │
│                 │  │                 │  │                 │
│ - Create Order  │  │ - User Profile  │  │ - Process Pay   │
│ - Order Status  │  │ - Auth          │  │ - Refund        │
│ - Order History │  │ - Preferences   │  │ - Transactions  │
└─────────────────┘  └─────────────────┘  └─────────────────┘
Decomposition Strategies:
  1. By Business Capability
E-commerce System:
- Product Catalog Service
- Shopping Cart Service
- Order Management Service
- Payment Service
- Inventory Service
- Shipping Service
- User Account Service
  1. By Subdomain
Healthcare System:
- Patient Management (Core Domain)
- Appointment Scheduling (Core Domain)
- Billing (Supporting Domain)
- Notifications (Generic Domain)
- Reporting (Generic Domain)
Bounded Contexts:
┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│  Order Service  │  │  User Service   │  │ Payment Service │
│                 │  │                 │  │                 │
│ - Create Order  │  │ - User Profile  │  │ - Process Pay   │
│ - Order Status  │  │ - Auth          │  │ - Refund        │
│ - Order History │  │ - Preferences   │  │ - Transactions  │
└─────────────────┘  └─────────────────┘  └─────────────────┘
拆分策略:
  1. 按业务能力拆分
E-commerce System:
- Product Catalog Service
- Shopping Cart Service
- Order Management Service
- Payment Service
- Inventory Service
- Shipping Service
- User Account Service
  1. 按子域拆分
Healthcare System:
- Patient Management (Core Domain)
- Appointment Scheduling (Core Domain)
- Billing (Supporting Domain)
- Notifications (Generic Domain)
- Reporting (Generic Domain)

Service Design Example

服务设计示例

typescript
// order-service/src/domain/order.ts
export class OrderService {
  constructor(
    private orderRepository: OrderRepository,
    private eventBus: EventBus,
    private paymentClient: PaymentClient,
    private inventoryClient: InventoryClient
  ) {}

  async createOrder(request: CreateOrderRequest): Promise<Order> {
    // 1. Validate order
    const order = Order.create(request);

    // 2. Check inventory (synchronous call)
    const available = await this.inventoryClient.checkAvailability(
      order.items
    );
    if (!available) {
      throw new InsufficientInventoryError();
    }

    // 3. Save order
    await this.orderRepository.save(order);

    // 4. Publish event (asynchronous)
    await this.eventBus.publish(new OrderCreatedEvent(order));

    return order;
  }
}
typescript
// order-service/src/domain/order.ts
export class OrderService {
  constructor(
    private orderRepository: OrderRepository,
    private eventBus: EventBus,
    private paymentClient: PaymentClient,
    private inventoryClient: InventoryClient
  ) {}

  async createOrder(request: CreateOrderRequest): Promise<Order> {
    // 1. Validate order
    const order = Order.create(request);

    // 2. Check inventory (synchronous call)
    const available = await this.inventoryClient.checkAvailability(
      order.items
    );
    if (!available) {
      throw new InsufficientInventoryError();
    }

    // 3. Save order
    await this.orderRepository.save(order);

    // 4. Publish event (asynchronous)
    await this.eventBus.publish(new OrderCreatedEvent(order));

    return order;
  }
}

2. Communication Patterns

2. 通信模式

Synchronous Communication (REST/gRPC)

同步通信(REST/gRPC)

REST API Example:
typescript
// user-service/src/api/user.controller.ts
import express from 'express';

const router = express.Router();

// Get user profile
router.get('/users/:id', async (req, res) => {
  try {
    const user = await userService.findById(req.params.id);
    res.json(user);
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      res.status(404).json({ error: 'User not found' });
    } else {
      res.status(500).json({ error: 'Internal server error' });
    }
  }
});

// Service-to-service call with circuit breaker
import axios from 'axios';
import CircuitBreaker from 'opossum';

const options = {
  timeout: 3000,
  errorThresholdPercentage: 50,
  resetTimeout: 30000
};

const breaker = new CircuitBreaker(
  async (userId: string) => {
    const response = await axios.get(
      `http://user-service/users/${userId}`,
      { timeout: 2000 }
    );
    return response.data;
  },
  options
);

breaker.fallback(() => ({ id: userId, name: 'Unknown User' }));
gRPC Example:
protobuf
// proto/user.proto
syntax = "proto3";

package user;

service UserService {
  rpc GetUser (GetUserRequest) returns (UserResponse);
  rpc ListUsers (ListUsersRequest) returns (stream UserResponse);
}

message GetUserRequest {
  string user_id = 1;
}

message UserResponse {
  string user_id = 1;
  string email = 2;
  string name = 3;
}
typescript
// Implementation
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';

const packageDefinition = protoLoader.loadSync('proto/user.proto');
const userProto = grpc.loadPackageDefinition(packageDefinition).user;

// Server
function getUser(call, callback) {
  const userId = call.request.user_id;
  const user = await userService.findById(userId);
  callback(null, user);
}

const server = new grpc.Server();
server.addService(userProto.UserService.service, { getUser });
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
REST API示例:
typescript
// user-service/src/api/user.controller.ts
import express from 'express';

const router = express.Router();

// Get user profile
router.get('/users/:id', async (req, res) => {
  try {
    const user = await userService.findById(req.params.id);
    res.json(user);
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      res.status(404).json({ error: 'User not found' });
    } else {
      res.status(500).json({ error: 'Internal server error' });
    }
  }
});

// Service-to-service call with circuit breaker
import axios from 'axios';
import CircuitBreaker from 'opossum';

const options = {
  timeout: 3000,
  errorThresholdPercentage: 50,
  resetTimeout: 30000
};

const breaker = new CircuitBreaker(
  async (userId: string) => {
    const response = await axios.get(
      `http://user-service/users/${userId}`,
      { timeout: 2000 }
    );
    return response.data;
  },
  options
);

breaker.fallback(() => ({ id: userId, name: 'Unknown User' }));
gRPC示例:
protobuf
// proto/user.proto
syntax = "proto3";

package user;

service UserService {
  rpc GetUser (GetUserRequest) returns (UserResponse);
  rpc ListUsers (ListUsersRequest) returns (stream UserResponse);
}

message GetUserRequest {
  string user_id = 1;
}

message UserResponse {
  string user_id = 1;
  string email = 2;
  string name = 3;
}
typescript
// Implementation
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';

const packageDefinition = protoLoader.loadSync('proto/user.proto');
const userProto = grpc.loadPackageDefinition(packageDefinition).user;

// Server
function getUser(call, callback) {
  const userId = call.request.user_id;
  const user = await userService.findById(userId);
  callback(null, user);
}

const server = new grpc.Server();
server.addService(userProto.UserService.service, { getUser });
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());

Asynchronous Communication (Message Queue)

异步通信(消息队列)

Event-Driven with RabbitMQ:
typescript
// order-service/src/events/publisher.ts
import amqp from 'amqplib';

export class EventPublisher {
  private connection: amqp.Connection;
  private channel: amqp.Channel;

  async connect() {
    this.connection = await amqp.connect('amqp://localhost');
    this.channel = await this.connection.createChannel();
    await this.channel.assertExchange('orders', 'topic', { durable: true });
  }

  async publishOrderCreated(order: Order) {
    const event = {
      eventType: 'OrderCreated',
      timestamp: new Date(),
      data: order
    };

    this.channel.publish(
      'orders',
      'order.created',
      Buffer.from(JSON.stringify(event)),
      { persistent: true }
    );
  }
}

// inventory-service/src/events/consumer.ts
export class OrderEventConsumer {
  async subscribe() {
    const connection = await amqp.connect('amqp://localhost');
    const channel = await connection.createChannel();

    await channel.assertExchange('orders', 'topic', { durable: true });
    const q = await channel.assertQueue('inventory-order-events', {
      durable: true
    });

    await channel.bindQueue(q.queue, 'orders', 'order.created');

    channel.consume(q.queue, async (msg) => {
      if (msg) {
        const event = JSON.parse(msg.content.toString());
        await this.handleOrderCreated(event.data);
        channel.ack(msg);
      }
    });
  }

  private async handleOrderCreated(order: Order) {
    // Reserve inventory
    await inventoryService.reserveItems(order.items);
  }
}
Kafka Event Streaming:
typescript
// event-streaming/kafka-producer.ts
import { Kafka } from 'kafkajs';

const kafka = new Kafka({
  clientId: 'order-service',
  brokers: ['kafka:9092']
});

const producer = kafka.producer();

export async function publishEvent(topic: string, event: any) {
  await producer.connect();
  await producer.send({
    topic,
    messages: [
      {
        key: event.aggregateId,
        value: JSON.stringify(event),
        headers: {
          'event-type': event.type,
          'correlation-id': event.correlationId
        }
      }
    ]
  });
}

// Consumer
const consumer = kafka.consumer({ groupId: 'inventory-service' });

await consumer.subscribe({ topic: 'order-events', fromBeginning: false });

await consumer.run({
  eachMessage: async ({ topic, partition, message }) => {
    const event = JSON.parse(message.value.toString());
    await eventHandler.handle(event);
  }
});
基于RabbitMQ的事件驱动架构:
typescript
// order-service/src/events/publisher.ts
import amqp from 'amqplib';

export class EventPublisher {
  private connection: amqp.Connection;
  private channel: amqp.Channel;

  async connect() {
    this.connection = await amqp.connect('amqp://localhost');
    this.channel = await this.connection.createChannel();
    await this.channel.assertExchange('orders', 'topic', { durable: true });
  }

  async publishOrderCreated(order: Order) {
    const event = {
      eventType: 'OrderCreated',
      timestamp: new Date(),
      data: order
    };

    this.channel.publish(
      'orders',
      'order.created',
      Buffer.from(JSON.stringify(event)),
      { persistent: true }
    );
  }
}

// inventory-service/src/events/consumer.ts
export class OrderEventConsumer {
  async subscribe() {
    const connection = await amqp.connect('amqp://localhost');
    const channel = await connection.createChannel();

    await channel.assertExchange('orders', 'topic', { durable: true });
    const q = await channel.assertQueue('inventory-order-events', {
      durable: true
    });

    await channel.bindQueue(q.queue, 'orders', 'order.created');

    channel.consume(q.queue, async (msg) => {
      if (msg) {
        const event = JSON.parse(msg.content.toString());
        await this.handleOrderCreated(event.data);
        channel.ack(msg);
      }
    });
  }

  private async handleOrderCreated(order: Order) {
    // Reserve inventory
    await inventoryService.reserveItems(order.items);
  }
}
Kafka事件流:
typescript
// event-streaming/kafka-producer.ts
import { Kafka } from 'kafkajs';

const kafka = new Kafka({
  clientId: 'order-service',
  brokers: ['kafka:9092']
});

const producer = kafka.producer();

export async function publishEvent(topic: string, event: any) {
  await producer.connect();
  await producer.send({
    topic,
    messages: [
      {
        key: event.aggregateId,
        value: JSON.stringify(event),
        headers: {
          'event-type': event.type,
          'correlation-id': event.correlationId
        }
      }
    ]
  });
}

// Consumer
const consumer = kafka.consumer({ groupId: 'inventory-service' });

await consumer.subscribe({ topic: 'order-events', fromBeginning: false });

await consumer.run({
  eachMessage: async ({ topic, partition, message }) => {
    const event = JSON.parse(message.value.toString());
    await eventHandler.handle(event);
  }
});

3. API Gateway Pattern

3. API网关模式

typescript
// api-gateway/src/gateway.ts
import express from 'express';
import httpProxy from 'http-proxy-middleware';
import jwt from 'jsonwebtoken';
import rateLimit from 'express-rate-limit';

const app = express();

// Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100
});

app.use(limiter);

// Authentication middleware
const authenticateToken = (req, res, next) => {
  const token = req.headers['authorization']?.split(' ')[1];
  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
};

// Route to services
app.use('/api/users', authenticateToken, httpProxy.createProxyMiddleware({
  target: 'http://user-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/users': '/users' }
}));

app.use('/api/orders', authenticateToken, httpProxy.createProxyMiddleware({
  target: 'http://order-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/orders': '/orders' }
}));

app.use('/api/products', httpProxy.createProxyMiddleware({
  target: 'http://product-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/products': '/products' }
}));

// Aggregation endpoint
app.get('/api/order-details/:orderId', authenticateToken, async (req, res) => {
  const orderId = req.params.orderId;

  // Parallel requests to multiple services
  const [order, user, products] = await Promise.all([
    fetch(`http://order-service:3000/orders/${orderId}`).then(r => r.json()),
    fetch(`http://user-service:3000/users/${req.user.id}`).then(r => r.json()),
    fetch(`http://product-service:3000/products?ids=${order.itemIds}`).then(r => r.json())
  ]);

  res.json({ order, user, products });
});
typescript
// api-gateway/src/gateway.ts
import express from 'express';
import httpProxy from 'http-proxy-middleware';
import jwt from 'jsonwebtoken';
import rateLimit from 'express-rate-limit';

const app = express();

// Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100
});

app.use(limiter);

// Authentication middleware
const authenticateToken = (req, res, next) => {
  const token = req.headers['authorization']?.split(' ')[1];
  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
};

// Route to services
app.use('/api/users', authenticateToken, httpProxy.createProxyMiddleware({
  target: 'http://user-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/users': '/users' }
}));

app.use('/api/orders', authenticateToken, httpProxy.createProxyMiddleware({
  target: 'http://order-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/orders': '/orders' }
}));

app.use('/api/products', httpProxy.createProxyMiddleware({
  target: 'http://product-service:3000',
  changeOrigin: true,
  pathRewrite: { '^/api/products': '/products' }
}));

// Aggregation endpoint
app.get('/api/order-details/:orderId', authenticateToken, async (req, res) => {
  const orderId = req.params.orderId;

  // Parallel requests to multiple services
  const [order, user, products] = await Promise.all([
    fetch(`http://order-service:3000/orders/${orderId}`).then(r => r.json()),
    fetch(`http://user-service:3000/users/${req.user.id}`).then(r => r.json()),
    fetch(`http://product-service:3000/products?ids=${order.itemIds}`).then(r => r.json())
  ]);

  res.json({ order, user, products });
});

4. Service Discovery

4. 服务发现

Consul Example

Consul示例

typescript
// service-registry/consul-client.ts
import Consul from 'consul';

export class ServiceRegistry {
  private consul: Consul.Consul;

  constructor() {
    this.consul = new Consul({
      host: 'consul',
      port: 8500
    });
  }

  // Register service
  async register(serviceName: string, servicePort: number) {
    await this.consul.agent.service.register({
      id: `${serviceName}-${process.env.HOSTNAME}`,
      name: serviceName,
      address: process.env.SERVICE_IP,
      port: servicePort,
      check: {
        http: `http://${process.env.SERVICE_IP}:${servicePort}/health`,
        interval: '10s',
        timeout: '5s'
      }
    });
  }

  // Discover service
  async discover(serviceName: string): Promise<string> {
    const result = await this.consul.health.service({
      service: serviceName,
      passing: true
    });

    if (result.length === 0) {
      throw new Error(`Service ${serviceName} not found`);
    }

    // Simple round-robin
    const service = result[Math.floor(Math.random() * result.length)];
    return `http://${service.Service.Address}:${service.Service.Port}`;
  }

  // Deregister on shutdown
  async deregister(serviceId: string) {
    await this.consul.agent.service.deregister(serviceId);
  }
}
typescript
// service-registry/consul-client.ts
import Consul from 'consul';

export class ServiceRegistry {
  private consul: Consul.Consul;

  constructor() {
    this.consul = new Consul({
      host: 'consul',
      port: 8500
    });
  }

  // Register service
  async register(serviceName: string, servicePort: number) {
    await this.consul.agent.service.register({
      id: `${serviceName}-${process.env.HOSTNAME}`,
      name: serviceName,
      address: process.env.SERVICE_IP,
      port: servicePort,
      check: {
        http: `http://${process.env.SERVICE_IP}:${servicePort}/health`,
        interval: '10s',
        timeout: '5s'
      }
    });
  }

  // Discover service
  async discover(serviceName: string): Promise<string> {
    const result = await this.consul.health.service({
      service: serviceName,
      passing: true
    });

    if (result.length === 0) {
      throw new Error(`Service ${serviceName} not found`);
    }

    // Simple round-robin
    const service = result[Math.floor(Math.random() * result.length)];
    return `http://${service.Service.Address}:${service.Service.Port}`;
  }

  // Deregister on shutdown
  async deregister(serviceId: string) {
    await this.consul.agent.service.deregister(serviceId);
  }
}

Kubernetes Service Discovery

Kubernetes服务发现

yaml
undefined
yaml
undefined

user-service-deployment.yaml

user-service-deployment.yaml

apiVersion: v1 kind: Service metadata: name: user-service spec: selector: app: user-service ports: - protocol: TCP port: 80 targetPort: 3000 type: ClusterIP

apiVersion: apps/v1 kind: Deployment metadata: name: user-service spec: replicas: 3 selector: matchLabels: app: user-service template: metadata: labels: app: user-service spec: containers: - name: user-service image: user-service:latest ports: - containerPort: 3000 env: - name: SERVICE_NAME value: "user-service"

```typescript
// Service call in Kubernetes
const userServiceUrl = process.env.USER_SERVICE_URL || 'http://user-service';
const response = await fetch(`${userServiceUrl}/users/${userId}`);

apiVersion: v1 kind: Service metadata: name: user-service spec: selector: app: user-service ports: - protocol: TCP port: 80 targetPort: 3000 type: ClusterIP

apiVersion: apps/v1 kind: Deployment metadata: name: user-service spec: replicas: 3 selector: matchLabels: app: user-service template: metadata: labels: app: user-service spec: containers: - name: user-service image: user-service:latest ports: - containerPort: 3000 env: - name: SERVICE_NAME value: "user-service"

```typescript
// Service call in Kubernetes
const userServiceUrl = process.env.USER_SERVICE_URL || 'http://user-service';
const response = await fetch(`${userServiceUrl}/users/${userId}`);

5. Data Consistency Patterns

5. 数据一致性模式

Saga Pattern (Orchestration)

Saga模式(编排式)

typescript
// order-saga-orchestrator.ts
export class OrderSagaOrchestrator {
  async createOrder(orderData: CreateOrderRequest) {
    const sagaId = uuidv4();
    const saga = new SagaInstance(sagaId);

    try {
      // Step 1: Create order
      const order = await this.orderService.createOrder(orderData);
      saga.addCompensation(() => this.orderService.cancelOrder(order.id));

      // Step 2: Reserve inventory
      await this.inventoryService.reserveItems(order.items);
      saga.addCompensation(() =>
        this.inventoryService.releaseReservation(order.id)
      );

      // Step 3: Process payment
      const payment = await this.paymentService.charge(order.total);
      saga.addCompensation(() =>
        this.paymentService.refund(payment.id)
      );

      // Step 4: Confirm order
      await this.orderService.confirmOrder(order.id);

      return order;
    } catch (error) {
      // Compensate in reverse order
      await saga.compensate();
      throw error;
    }
  }
}
typescript
// order-saga-orchestrator.ts
export class OrderSagaOrchestrator {
  async createOrder(orderData: CreateOrderRequest) {
    const sagaId = uuidv4();
    const saga = new SagaInstance(sagaId);

    try {
      // Step 1: Create order
      const order = await this.orderService.createOrder(orderData);
      saga.addCompensation(() => this.orderService.cancelOrder(order.id));

      // Step 2: Reserve inventory
      await this.inventoryService.reserveItems(order.items);
      saga.addCompensation(() =>
        this.inventoryService.releaseReservation(order.id)
      );

      // Step 3: Process payment
      const payment = await this.paymentService.charge(order.total);
      saga.addCompensation(() =>
        this.paymentService.refund(payment.id)
      );

      // Step 4: Confirm order
      await this.orderService.confirmOrder(order.id);

      return order;
    } catch (error) {
      // Compensate in reverse order
      await saga.compensate();
      throw error;
    }
  }
}

Event Sourcing Pattern

事件溯源模式

typescript
// order-aggregate.ts
export class OrderAggregate {
  private id: string;
  private status: OrderStatus;
  private items: OrderItem[];
  private events: DomainEvent[] = [];

  // Command handler
  createOrder(command: CreateOrderCommand) {
    // Validation
    if (this.id) throw new Error('Order already exists');

    // Apply event
    this.apply(new OrderCreatedEvent({
      orderId: command.orderId,
      userId: command.userId,
      items: command.items
    }));
  }

  // Event handler
  private apply(event: DomainEvent) {
    switch (event.type) {
      case 'OrderCreated':
        this.id = event.orderId;
        this.items = event.items;
        this.status = OrderStatus.PENDING;
        break;
      case 'OrderConfirmed':
        this.status = OrderStatus.CONFIRMED;
        break;
    }
    this.events.push(event);
  }

  getUncommittedEvents(): DomainEvent[] {
    return this.events;
  }
}
typescript
// order-aggregate.ts
export class OrderAggregate {
  private id: string;
  private status: OrderStatus;
  private items: OrderItem[];
  private events: DomainEvent[] = [];

  // Command handler
  createOrder(command: CreateOrderCommand) {
    // Validation
    if (this.id) throw new Error('Order already exists');

    // Apply event
    this.apply(new OrderCreatedEvent({
      orderId: command.orderId,
      userId: command.userId,
      items: command.items
    }));
  }

  // Event handler
  private apply(event: DomainEvent) {
    switch (event.type) {
      case 'OrderCreated':
        this.id = event.orderId;
        this.items = event.items;
        this.status = OrderStatus.PENDING;
        break;
      case 'OrderConfirmed':
        this.status = OrderStatus.CONFIRMED;
        break;
    }
    this.events.push(event);
  }

  getUncommittedEvents(): DomainEvent[] {
    return this.events;
  }
}

6. Service Mesh (Istio)

6. 服务网格(Istio)

yaml
undefined
yaml
undefined

istio-config.yaml

istio-config.yaml

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: order-service spec: hosts:
  • order-service http:
  • match:
    • headers: user-type: exact: premium route:
    • destination: host: order-service subset: v2 weight: 100
  • route:
    • destination: host: order-service subset: v1 weight: 90
    • destination: host: order-service subset: v2 weight: 10

apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: order-service spec: host: order-service trafficPolicy: connectionPool: tcp: maxConnections: 100 http: http1MaxPendingRequests: 50 maxRequestsPerConnection: 2 outlierDetection: consecutiveErrors: 5 interval: 30s baseEjectionTime: 30s subsets:
  • name: v1 labels: version: v1
  • name: v2 labels: version: v2
undefined
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: order-service spec: hosts:
  • order-service http:
  • match:
    • headers: user-type: exact: premium route:
    • destination: host: order-service subset: v2 weight: 100
  • route:
    • destination: host: order-service subset: v1 weight: 90
    • destination: host: order-service subset: v2 weight: 10

apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: order-service spec: host: order-service trafficPolicy: connectionPool: tcp: maxConnections: 100 http: http1MaxPendingRequests: 50 maxRequestsPerConnection: 2 outlierDetection: consecutiveErrors: 5 interval: 30s baseEjectionTime: 30s subsets:
  • name: v1 labels: version: v1
  • name: v2 labels: version: v2
undefined

Best Practices

最佳实践

✅ DO

✅ 建议

  • Design services around business capabilities
  • Use asynchronous communication where possible
  • Implement circuit breakers for resilience
  • Use API gateway for cross-cutting concerns
  • Implement distributed tracing
  • Use service mesh for service-to-service communication
  • Design for failure (chaos engineering)
  • Implement health checks for all services
  • Use correlation IDs for request tracking
  • Version your APIs
  • Implement proper monitoring and alerting
  • Use event-driven architecture for loose coupling
  • Implement idempotent operations
  • Use database per service pattern
  • 围绕业务能力设计服务
  • 尽可能使用异步通信
  • 实现断路器以提升系统韧性
  • 使用API网关处理横切关注点
  • 实现分布式追踪
  • 使用服务网格管理服务间通信
  • 面向故障设计(混沌工程)
  • 为所有服务实现健康检查
  • 使用关联ID追踪请求
  • 对API进行版本管理
  • 实现完善的监控与告警
  • 使用事件驱动架构实现松耦合
  • 实现幂等操作
  • 采用单服务单数据库模式

❌ DON'T

❌ 避免

  • Share databases between services
  • Create overly granular services (nanoservices)
  • Use distributed transactions (two-phase commit)
  • Ignore network latency and failures
  • Share domain models between services
  • Deploy all services as one unit
  • Hardcode service URLs
  • Forget to implement authentication/authorization
  • Use synchronous calls for long-running operations
  • Ignore backward compatibility
  • Skip monitoring and logging
  • Create circular dependencies between services
  • 服务间共享数据库
  • 设计过于细分的服务(纳米服务)
  • 使用分布式事务(两阶段提交)
  • 忽略网络延迟与故障
  • 服务间共享领域模型
  • 将所有服务作为一个单元部署
  • 硬编码服务URL
  • 忽略身份认证与授权实现
  • 对长时间运行的操作使用同步调用
  • 忽略向后兼容性
  • 跳过监控与日志
  • 服务间创建循环依赖

Common Patterns

常见模式

Pattern 1: Backend for Frontend (BFF)

模式1:前端后端(BFF)

typescript
// mobile-bff/src/api.ts - Optimized for mobile
app.get('/api/home', async (req, res) => {
  const [featured, recommendations] = await Promise.all([
    productService.getFeatured(5),
    recommendationService.getForUser(req.user.id, 10)
  ]);
  res.json({ featured, recommendations });
});

// web-bff/src/api.ts - More data for web
app.get('/api/home', async (req, res) => {
  const [featured, recommendations, categories, promotions] = await Promise.all([
    productService.getFeatured(20),
    recommendationService.getForUser(req.user.id, 50),
    categoryService.getAll(),
    promotionService.getActive()
  ]);
  res.json({ featured, recommendations, categories, promotions });
});
typescript
// mobile-bff/src/api.ts - Optimized for mobile
app.get('/api/home', async (req, res) => {
  const [featured, recommendations] = await Promise.all([
    productService.getFeatured(5),
    recommendationService.getForUser(req.user.id, 10)
  ]);
  res.json({ featured, recommendations });
});

// web-bff/src/api.ts - More data for web
app.get('/api/home', async (req, res) => {
  const [featured, recommendations, categories, promotions] = await Promise.all([
    productService.getFeatured(20),
    recommendationService.getForUser(req.user.id, 50),
    categoryService.getAll(),
    promotionService.getActive()
  ]);
  res.json({ featured, recommendations, categories, promotions });
});

Pattern 2: Sidecar Pattern

模式2:边车模式

yaml
undefined
yaml
undefined

Pod with sidecar

Pod with sidecar

apiVersion: v1 kind: Pod metadata: name: app-with-sidecar spec: containers:
  • name: app image: my-app:latest
  • name: logging-sidecar image: fluentd:latest volumeMounts:
    • name: logs mountPath: /logs volumes:
  • name: logs emptyDir: {}
undefined
apiVersion: v1 kind: Pod metadata: name: app-with-sidecar spec: containers:
  • name: app image: my-app:latest
  • name: logging-sidecar image: fluentd:latest volumeMounts:
    • name: logs mountPath: /logs volumes:
  • name: logs emptyDir: {}
undefined

Tools & Resources

工具与资源

  • Service Mesh: Istio, Linkerd, Consul Connect
  • API Gateway: Kong, Apigee, AWS API Gateway
  • Service Discovery: Consul, Eureka, Zookeeper
  • Message Queue: RabbitMQ, Apache Kafka, AWS SQS
  • Orchestration: Kubernetes, Docker Swarm, Nomad
  • Monitoring: Prometheus, Grafana, Datadog
  • Tracing: Jaeger, Zipkin, AWS X-Ray
  • Circuit Breaker: Hystrix, Resilience4j, Polly
  • 服务网格:Istio, Linkerd, Consul Connect
  • API网关:Kong, Apigee, AWS API Gateway
  • 服务发现:Consul, Eureka, Zookeeper
  • 消息队列:RabbitMQ, Apache Kafka, AWS SQS
  • 编排工具:Kubernetes, Docker Swarm, Nomad
  • 监控工具:Prometheus, Grafana, Datadog
  • 追踪工具:Jaeger, Zipkin, AWS X-Ray
  • 断路器:Hystrix, Resilience4j, Polly