name: 微服务架构 description: 设计和实现微服务架构,包括服务边界、通信模式、API网关、服务网格、服务发现和分布式系统模式。适用于构建微服务、分布式系统或面向服务的架构。
微服务架构
概览
全面的微服务架构设计、实施和维护指南。涵盖服务分解、通信模式、数据管理、部署策略和分布式系统的可观测性。
使用场景
- 设计新的微服务架构
- 将单体应用分解为微服务
- 实现服务间通信
- 设置API网关和服务网格
- 实现服务发现
- 管理分布式事务
- 设计服务间数据一致性
- 独立扩展服务
指南
1. 服务边界设计
领域驱动设计(DDD)方法
界限上下文:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 订单服务 │ │ 用户服务 │ │ 支付服务 │
│ │ │ │ │ │
│ - 创建订单 │ │ - 用户档案 │ │ - 处理支付 │
│ - 订单状态 │ │ - 认证 │ │ - 退款 │
│ - 订单历史 │ │ - 偏好设置 │ │ - 交易 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
分解策略:
- 按业务能力
电子商务系统:
- 产品目录服务
- 购物车服务
- 订单管理服务
- 支付服务
- 库存服务
- 运输服务
- 用户账户服务
- 按子域
医疗保健系统:
- 患者管理(核心域)
- 预约安排(核心域)
- 计费(支撑域)
- 通知(通用域)
- 报告(通用域)
服务设计示例
// 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. 验证订单
const order = Order.create(request);
// 2. 检查库存(同步调用)
const available = await this.inventoryClient.checkAvailability(
order.items
);
if (!available) {
throw new InsufficientInventoryError();
}
// 3. 保存订单
await this.orderRepository.save(order);
// 4. 发布事件(异步)
await this.eventBus.publish(new OrderCreatedEvent(order));
return order;
}
}
2. 通信模式
同步通信(REST/gRPC)
REST API 示例:
// user-service/src/api/user.controller.ts
import express from 'express';
const router = express.Router();
// 获取用户档案
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: '用户未找到' });
} else {
res.status(500).json({ error: '内部服务器错误' });
}
}
});
// 服务间调用,带有断路器
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: '未知用户' }));
gRPC 示例:
// 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;
}
// 实现
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;
// 服务器
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());
异步通信(消息队列)
基于事件的RabbitMQ:
// 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) {
// 预留库存
await inventoryService.reserveItems(order.items);
}
}
Kafka事件流:
// 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
}
}
]
});
}
// 消费者
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网关模式
// 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();
// 速率限制
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15分钟
max: 100
});
app.use(limiter);
// 认证中间件
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();
});
};
// 路由到服务
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' }
}));
// 聚合端点
app.get('/api/order-details/:orderId', authenticateToken, async (req, res) => {
const orderId = req.params.orderId;
// 并行请求多个服务
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. 服务发现
Consul示例
// 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
});
}
// 注册服务
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'
}
});
}
// 发现服务
async discover(serviceName: string): Promise<string> {
const result = await this.consul.health.service({
service: serviceName,
passing: true
});
if (result.length === 0) {
throw new Error(`服务 ${serviceName} 未找到`);
}
// 简单的轮询
const service = result[Math.floor(Math.random() * result.length)];
return `http://${service.Service.Address}:${service.Service.Port}`;
}
// 关闭时注销
async deregister(serviceId: string) {
await this.consul.agent.service.deregister(serviceId);
}
}
Kubernetes服务发现
# 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"
// Kubernetes中的服务调用
const userServiceUrl = process.env.USER_SERVICE_URL || 'http://user-service';
const response = await fetch(`${userServiceUrl}/users/${userId}`);
5. 数据一致性模式
Saga模式(编排)
// order-saga-orchestrator.ts
export class OrderSagaOrchestrator {
async createOrder(orderData: CreateOrderRequest) {
const sagaId = uuidv4();
const saga = new SagaInstance(sagaId);
try {
// 第1步:创建订单
const order = await this.orderService.createOrder(orderData);
saga.addCompensation(() => this.orderService.cancelOrder(order.id));
// 第2步:预留库存
await this.inventoryService.reserveItems(order.items);
saga.addCompensation(() =>
this.inventoryService.releaseReservation(order.id)
);
// 第3步:处理支付
const payment = await this.paymentService.charge(order.total);
saga.addCompensation(() =>
this.paymentService.refund(payment.id)
);
// 第4步:确认订单
await this.orderService.confirmOrder(order.id);
return order;
} catch (error) {
// 反向补偿
await saga.compensate();
throw error;
}
}
}
事件溯源模式
// order-aggregate.ts
export class OrderAggregate {
private id: string;
private status: OrderStatus;
private items: OrderItem[];
private events: DomainEvent[] = [];
// 命令处理器
createOrder(command: CreateOrderCommand) {
// 验证
if (this.id) throw new Error('订单已存在');
// 应用事件
this.apply(new OrderCreatedEvent({
orderId: command.orderId,
userId: command.userId,
items: command.items
}));
}
// 事件处理器
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. 服务网格(Istio)
# 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
最佳实践
✅ DO
- 围绕业务能力设计服务
- 尽可能使用异步通信
- 实现断路器以增强弹性
- 使用API网关处理跨领域关注点
- 实施分布式跟踪
- 使用服务网格进行服务间通信
- 为失败而设计(混沌工程)
- 为所有服务实施健康检查
- 使用相关ID进行请求跟踪
- 版本化您的API
- 实施适当的监控和警报
- 使用事件驱动架构以实现松散耦合
- 实施幂等操作
- 使用数据库每服务模式
❌ DON’T
- 在服务之间共享数据库
- 创建过度细化的服务(纳米服务)
- 使用分布式事务(两阶段提交)
- 忽视网络延迟和故障
- 在服务之间共享领域模型
- 将所有服务作为一个单元部署
- 硬编码服务URL
- 忘记实施认证/授权
- 对长时间运行的操作使用同步调用
- 忽视向后兼容性
- 跳过监控和日志记录
- 创建服务之间的循环依赖
常见模式
模式1:前端后端(BFF)
// mobile-bff/src/api.ts - 针对移动设备优化
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 - 为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 });
});
模式2:边车模式
# 带有边车的Pod
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: {}
工具和资源
- 服务网格: 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