微服务架构已成为现代后端开发的主流选择。但真正做好微服务并非易事——过度拆分会导致分布式噩梦,拆分不足又失去微服务的价值。本文将基于实战经验,分享微服务架构的完整实践指南。

何时需要微服务

微服务不是银弹,先判断是否真的需要:

单体架构的优势场景

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 小团队、简单业务 - 单体架构更合适
class MonolithApp {
  // 所有功能在一个进程内
  // 简单的函数调用
  // 统一的事务管理
  // 易于开发和测试

  handleOrder(order: Order) {
    this.inventory.check(order);
    this.payment.process(order);
    this.shipping.arrange(order);
    // 简单的事务保证一致性
  }
}

适合单体的条件:

  • 团队 < 10人
  • 业务领域简单
  • 部署频率要求不高
  • 预期流量可控

微服务的优势场景

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 大团队、复杂业务 - 微服务更合适
// 订单服务
class OrderService {
  @MessagePattern('order.created')
  async handleOrder(data: OrderDTO) {
    // 发布事件,其他服务订阅
    this.eventBus.emit('order.created', data);
  }
}

// 库存服务
class InventoryService {
  @EventPattern('order.created')
  async reserveStock(data: OrderDTO) {
    // 独立的库存管理逻辑
  }
}

需要微服务的信号:

  • 单个服务部署影响全系统
  • 不同模块需要独立扩展
  • 团队规模持续增长
  • 技术栈需要差异化

服务拆分策略

按业务能力拆分(推荐)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 领域驱动设计(DDD)指导服务边界

// 用户服务 - 身份与认证
interface UserService {
  register(dto: RegisterDTO): Promise<User>;
  authenticate(credentials: Credentials): Promise<Token>;
  getProfile(userId: string): Promise<Profile>;
}

// 商品服务 - 商品目录管理
interface ProductService {
  list(filters: ProductFilter): Promise<Product[]>;
  create(dto: ProductDTO): Promise<Product>;
  updateStock(productId: string, quantity: number): Promise<void>;
}

// 订单服务 - 交易流程
interface OrderService {
  create(dto: OrderDTO): Promise<Order>;
  cancel(orderId: string): Promise<void>;
  getStatus(orderId: string): Promise<OrderStatus>;
}

避免的拆分陷阱

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// ❌ 按技术层拆分 - 错误示例
// 服务A: 处理所有Controller
// 服务B: 处理所有Service
// 服务C: 处理所有DAO
// 这样只是分布式单体

// ✅ 按业务域拆分 - 正确示例
// 用户服务: 完整的用户管理功能
// 订单服务: 完整的订单处理功能
// 每个服务都有完整的层次结构

核心基础设施

API网关

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 使用NestJS实现API网关
import { Controller, Get, Proxy } from '@nestjs/common';

@Controller()
export class GatewayController {
  // 路由到用户服务
  @Get('api/users/:id')
  @Proxy({ service: 'user-service' })
  getUser() {}

  // 路由到订单服务
  @Get('api/orders/:id')
  @Proxy({ service: 'order-service' })
  getOrder() {}

  // 聚合多个服务的结果
  @Get('api/user-orders/:userId')
  async getUserOrders(@Param('userId') userId: string) {
    const [user, orders] = await Promise.all([
      this.userService.getOne(userId),
      this.orderService.getUserOrders(userId)
    ]);

    return { user, orders };
  }
}

服务注册与发现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Consul服务注册
import { Client } from 'consul';

const consul = new Client();

// 服务启动时注册
async function registerService() {
  await consul.agent.service.register({
    name: 'order-service',
    address: process.env.SERVICE_HOST,
    port: parseInt(process.env.SERVICE_PORT),
    check: {
      http: `http://${process.env.SERVICE_HOST}:${process.env.SERVICE_PORT}/health`,
      interval: '10s'
    },
    tags: ['v1', 'orders']
  });
}

// 服务发现
async function discoverService(serviceName: string) {
  const services = await consul.agent.service.list();
  const instances = Object.values(services)
    .filter(s => s.Service === serviceName);

  // 负载均衡:随机选择
  return instances[Math.floor(Math.random() * instances.length)];
}

配置中心

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 集中式配置管理
import { ConfigService } from '@nestjs/config';

// 配置优先级:环境变量 > 远程配置 > 本地文件
async function loadConfig() {
  const config = new ConfigService();

  return {
    database: {
      host: config.get('DB_HOST', 'localhost'),
      port: config.get('DB_PORT', 5432),
      username: config.get('DB_USER'),
      password: config.get('DB_PASS')
    },
    redis: {
      host: config.get('REDIS_HOST'),
      port: config.get('REDIS_PORT', 6379)
    },
    features: {
      enableCache: config.get('ENABLE_CACHE', true),
      enableRateLimit: config.get('ENABLE_RATELIMIT', true)
    }
  };
}

服务间通信

同步通信:REST/gRPC

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// REST API - 简单场景
import axios from 'axios';

class UserServiceClient {
  private baseURL = 'http://user-service';

  async getUser(userId: string): Promise<User> {
    const { data } = await axios.get(
      `${this.baseURL}/users/${userId}`
    );
    return data;
  }
}

// gRPC - 高性能场景
// user.proto
syntax = "proto3";
service UserService {
  rpc GetUser(GetUserRequest) returns (UserResponse);
}

// 生成的TypeScript客户端
const client = new UserServiceClient('user-service:50051');

const user = await client.getUser({ userId: '123' });

异步通信:消息队列

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 使用RabbitMQ事件驱动
import { AmqpConnection } from '@nestjs-plus/rabbitmq';

class OrderService {
  constructor(private amqp: AmqpConnection) {}

  async createOrder(dto: OrderDTO): Promise<Order> {
    const order = await this.saveOrder(dto);

    // 发布订单创建事件
    await this.amqp.publish('order.exchange', 'order.created', {
      orderId: order.id,
      userId: order.userId,
      items: order.items,
      total: order.total
    });

    return order;
  }
}

// 库存服务订阅事件
class InventoryService {
  @RabbitSubscribe({
    exchange: 'order.exchange',
    routingKey: 'order.created',
    queue: 'inventory.order.created'
  })
  async handleOrderCreated(event: OrderCreatedEvent) {
    await this.reserveStock(event.items);
  }
}

数据一致性

Saga模式:分布式事务

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 订单处理Saga
class OrderSaga {
  private steps = [
    'validateOrder',
    'reserveInventory',
    'processPayment',
    'confirmOrder'
  ];

  async execute(orderId: string): Promise<void> {
    const saga = new SagaLog(orderId);

    for (const step of this.steps) {
      try {
        await this.executeStep(step, orderId);
        saga.markCompleted(step);
      } catch (error) {
        // 执行补偿操作
        await this.compensate(saga);
        throw error;
      }
    }
  }

  private async compensate(saga: SagaLog): Promise<void> {
    const completedSteps = saga.getCompletedSteps();

    // 逆序执行补偿
    for (const step of completedSteps.reverse()) {
      await this.executeCompensation(step, saga.orderId);
    }
  }
}

最终一致性方案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 事件溯源 + CQRS
class OrderEventStore {
  async append(event: OrderEvent): Promise<void> {
    // 追加事件到事件流
    await this.db.events.insert({
      aggregateId: event.orderId,
      type: event.type,
      data: JSON.stringify(event.data),
      timestamp: Date.now(),
      version: event.version
    });
  }

  async getEvents(orderId: string): Promise<OrderEvent[]> {
    return await this.db.events
      .where('aggregateId', orderId)
      .orderBy('timestamp', 'asc');
  }

  // 从事件重建状态
  async rebuild(orderId: string): Promise<Order> {
    const events = await this.getEvents(orderId);
    return events.reduce((order, event) => {
      return this.applyEvent(order, event);
    }, new Order());
  }
}

可观测性

分布式追踪

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// OpenTelemetry集成
import { trace } from '@opentelemetry/api';

const tracer = trace.getTracer('order-service');

async function processOrder(orderId: string) {
  const span = tracer.startSpan('processOrder');

  try {
    span.setAttribute('order.id', orderId);

    // 自动传播追踪上下文
    const user = await this.userService.getUser(userId);
    const inventory = await this.inventoryService.check(items);

    span.setStatus({ code: SpanStatusCode.OK });
  } catch (error) {
    span.recordException(error);
    throw error;
  } finally {
    span.end();
  }
}

指标监控

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Prometheus指标
import { Counter, Histogram } from 'prom-client';

export const orderCreatedCounter = new Counter({
  name: 'orders_created_total',
  help: 'Total orders created',
  labelNames: ['status']
});

export const orderProcessingTime = new Histogram({
  name: 'order_processing_seconds',
  help: 'Order processing time',
  buckets: [0.1, 0.5, 1, 2, 5]
});

async function createOrder(dto: OrderDTO) {
  const start = Date.now();

  try {
    const order = await this.service.create(dto);
    orderCreatedCounter.labels('success').inc();
    return order;
  } catch (error) {
    orderCreatedCounter.labels('failed').inc();
    throw error;
  } finally {
    orderProcessingTime.observe((Date.now() - start) / 1000);
  }
}

部署策略

容器化部署

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000
CMD ["node", "dist/main.js"]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# docker-compose.yml
version: '3.8'
services:
  order-service:
    build: ./services/order
    environment:
      - DB_HOST=postgres
      - REDIS_HOST=redis
    depends_on:
      - postgres
      - redis

  postgres:
    image: postgres:16
    environment:
      - POSTGRES_DB=orders

  redis:
    image: redis:7-alpine

Kubernetes部署

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
      - name: order-service
        image: order-service:v1.0.0
        ports:
        - containerPort: 3000
        env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: app-config
              key: db.host
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
  - port: 80
    targetPort: 3000
  type: ClusterIP

常见陷阱与解决方案

陷阱1:过度拆分

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// ❌ 错误:每个功能一个服务
class UserEmailService {}
class UserProfileService {}
class UserPreferenceService {}
class UserAuthService {}

// ✅ 正确:相关的功能在一个服务
class UserService {
  // 统一的用户域
  handleEmail() {}
  handleProfile() {}
  handlePreference() {}
  handleAuth() {}
}

陷阱2:分布式事务滥用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// ❌ 2PC/3PC - 性能差、复杂度高
async function createOrder() {
  await transaction.begin();
  await orderService.create();
  await inventoryService.reserve(); // 2PC
  await paymentService.charge(); // 2PC
  await transaction.commit();
}

// ✅ Saga模式 - 最终一致
async function createOrder() {
  const order = await orderService.create();
  await inventoryService.reserve(order);
  await paymentService.charge(order);

  // 失败时通过补偿操作回滚
}

总结

微服务架构是一把双刃剑:

收益:

  • 独立部署和扩展
  • 技术栈灵活
  • 故障隔离
  • 团队自治

代价:

  • 分布式复杂度
  • 运维成本增加
  • 调试困难
  • 数据一致性挑战

关键决策点:

  1. 是否真的需要微服务?
  2. 如何合理划分服务边界?
  3. 如何处理分布式事务?
  4. 如何保证系统可观测性?

记住:从简单开始,在需要时进化。不要为了微服务而微服务。