微服务架构设计模式 微服务架构将单一应用划分为多个小型服务,每个服务独立开发、部署和扩展,提高了系统的灵活性和可维护性。
微服务基础概念 核心特征 单一职责 :每个服务专注于特定的业务功能独立部署 :服务可以独立更新和部署技术多样性 :不同服务可以使用不同的技术栈去中心化 :避免单点故障和数据存储容错性 :服务之间相互隔离,故障不传播架构对比 方面 单体架构 微服务架构 部署 整体部署 独立部署 技术栈 统一 多样化 团队组织 大团队 小团队 开发速度 初期快 长期快 运维复杂度 简单 复杂
服务划分原则 业务能力划分 services: - name: user-service responsibilities: - 用户注册/登录 - 用户信息管理 - 权限管理 - name: product-service responsibilities: - 商品信息管理 - 库存管理 - 价格管理 - name: order-service responsibilities: - 订单创建 - 订单状态管理 - 订单历史 - name: payment-service responsibilities: - 支付处理 - 退款管理 - 支付记录
数据库划分策略 CREATE TABLE users ( id BIGINT PRIMARY KEY, email VARCHAR (255 ) UNIQUE , name VARCHAR (100 ), created_at TIMESTAMP ); CREATE TABLE products ( id BIGINT PRIMARY KEY, name VARCHAR (255 ), price DECIMAL (10 ,2 ), stock INT ); CREATE TABLE orders ( id BIGINT PRIMARY KEY, user_id BIGINT , total_amount DECIMAL (10 ,2 ), status VARCHAR (20 ), created_at TIMESTAMP );
服务通信模式 同步通信 HTTP REST API @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public User getUser (@PathVariable Long id) { return userService.findById(id); } @PostMapping public User createUser (@RequestBody User user) { return userService.save(user); } } @Service public class OrderService { @Autowired private RestTemplate restTemplate; public User getUserById (Long userId) { String url = "http://user-service/api/users/" + userId; return restTemplate.getForObject(url, User.class); } }
gRPC 通信 syntax = "proto3" ; service UserService { rpc GetUser(GetUserRequest) returns (GetUserResponse) ; rpc CreateUser(CreateUserRequest) returns (CreateUserResponse) ; } message GetUserRequest { int64 id = 1 ; } message GetUserResponse { User user = 1 ; } message User { int64 id = 1 ; string email = 2 ; string name = 3 ; }
@Service public class UserGrpcClient { private final UserServiceGrpc.UserServiceBlockingStub stub; public UserGrpcClient (UserServiceGrpc.UserServiceBlockingStub stub) { this .stub = stub; } public User getUser (long id) { GetUserRequest request = GetUserRequest.newBuilder() .setId(id) .build(); GetUserResponse response = stub.getUser(request); return response.getUser(); } }
异步通信 消息队列 @Service public class OrderEventPublisher { @Autowired private RabbitTemplate rabbitTemplate; public void publishOrderCreated (Order order) { OrderCreatedEvent event = new OrderCreatedEvent ( order.getId(), order.getUserId(), order.getTotalAmount() ); rabbitTemplate.convertAndSend("order.exchange" , "order.created" , event); } } @Component @RabbitListener(queues = "notification.queue") public class OrderNotificationHandler { @RabbitHandler public void handleOrderCreated (OrderCreatedEvent event) { sendNotification(event.getUserId(), "您的订单已创建" ); } }
事件溯源 @Entity public class OrderEvent { @Id private String id; private String orderId; private String eventType; private String eventData; private Instant timestamp; } @Service public class OrderAggregateService { public Order rebuildOrder (String orderId) { List<OrderEvent> events = orderEventRepository.findByOrderId(orderId); Order order = new Order (); for (OrderEvent event : events) { switch (event.getEventType()) { case "ORDER_CREATED" : OrderCreatedData data = parseEventData(event.getEventData()); order.setId(data.getOrderId()); order.setUserId(data.getUserId()); order.setTotalAmount(data.getTotalAmount()); break ; case "ORDER_UPDATED" : break ; } } return order; } }
服务发现与注册 服务注册中心 eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ instance: hostname: localhost prefer-ip-address: true consul: host: localhost port: 8500 discovery: service-name: user-service health-check-path: /actuator/health
负载均衡 @Configuration public class LoadBalancerConfig { @Bean @LoadBalanced public RestTemplate restTemplate () { return new RestTemplate (); } } @Service public class UserServiceClient { @Autowired @LoadBalanced private RestTemplate restTemplate; public User getUser (String userId) { return restTemplate.getForObject( "http://user-service/api/users/" + userId, User.class ); } }
API 网关 网关配置 spring: cloud: gateway: routes: - id: user-service uri: lb://user-service predicates: - Path=/api/users/** filters: - StripPrefix=1 - AddRequestHeader=X-Request-From, Gateway - id: product-service uri: lb://product-service predicates: - Path=/api/products/** filters: - StripPrefix=1
认证与授权 @Component public class AuthenticationFilter implements GlobalFilter , Ordered { @Override public Mono<Void> filter (ServerWebExchange exchange, GatewayFilterChain chain) { String token = exchange.getRequest().getHeaders().getFirst("Authorization" ); if (token == null || !validateToken(token)) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); } return chain.filter(exchange); } @Override public int getOrder () { return -100 ; } }
数据一致性 Saga 模式 @Service public class OrderSagaOrchestrator { public void processOrder (Order order) { try { orderService.createOrder(order); inventoryService.reserveItems(order.getItems()); paymentService.processPayment(order.getPaymentInfo()); orderService.confirmOrder(order.getId()); } catch (Exception e) { orderService.cancelOrder(order.getId()); inventoryService.releaseItems(order.getItems()); paymentService.refundPayment(order.getPaymentInfo()); } } } @Component public class OrderSagaEventHandler { @EventHandler public void handle (OrderCreatedEvent event) { inventoryService.reserveItems(event.getOrderItems()); } @EventHandler public void handle (InventoryReservedEvent event) { paymentService.processPayment(event.getPaymentInfo()); } @EventHandler public void handle (PaymentProcessedEvent event) { orderService.confirmOrder(event.getOrderId()); } }
最终一致性 @Service public class UserEventPublisher { @Autowired private ApplicationEventPublisher eventPublisher; @Transactional public void updateUser (User user) { userRepository.save(user); UserUpdatedEvent event = new UserUpdatedEvent (user.getId(), user.getEmail()); eventPublisher.publishEvent(event); } } @EventListener @Async public void handleUserUpdated (UserUpdatedEvent event) { searchService.updateUserIndex(event.getUserId()); cacheService.updateUserCache(event.getUserId()); notificationService.sendUserUpdateNotification(event.getUserId()); }
监控与日志 分布式追踪 @Configuration public class TracingConfig { @Bean public Tracer tracer () { return BraveTracer.create( Brave.newBuilder() .localServiceName("user-service" ) .build() ); } } @Service public class UserService { @Autowired private Tracer tracer; public User getUser (Long id) { Span span = tracer.nextSpan().name("get-user" ).start(); try (Tracer.SpanInScope ws = tracer.withSpan(span)) { span.tag("user.id" , String.valueOf(id)); User user = userRepository.findById(id); span.tag("user.found" , user != null ); return user; } finally { span.end(); } } }
健康检查 @Component public class UserServiceHealthIndicator implements HealthIndicator { @Autowired private UserRepository userRepository; @Override public Health health () { try { userRepository.count(); return Health.up() .withDetail("database" , "Available" ) .build(); } catch (Exception e) { return Health.down() .withDetail("database" , "Unavailable" ) .withException(e) .build(); } } }
部署策略 容器化部署 FROM openjdk:11 -jre-slimCOPY target/user-service.jar app.jar EXPOSE 8080 ENTRYPOINT ["java" , "-jar" , "/app.jar" ]
version: '3.8' services: user-service: build: ./user-service ports: - "8081:8080" environment: - SPRING_PROFILES_ACTIVE=docker depends_on: - mysql - eureka product-service: build: ./product-service ports: - "8082:8080" environment: - SPRING_PROFILES_ACTIVE=docker depends_on: - mysql - eureka eureka: image: springcloud/eureka ports: - "8761:8761"
Kubernetes 部署 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: 8080 env: - name: SPRING_PROFILES_ACTIVE value: "kubernetes" livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 5 periodSeconds: 5
最佳实践 服务边界清晰 :基于业务能力划分服务数据去中心化 :每个服务拥有独立数据库异步优先 :使用事件驱动架构提高系统弹性容错设计 :实施熔断器、重试、降级机制监控完备 :实现分布式追踪和实时监控自动化部署 :使用 CI/CD 流水线文档齐全 :维护 API 文档和架构决策记录[!tip]
从单体应用逐步迁移到微服务 优先使用成熟的开源框架和工具 重视团队文化和 DevOps 实践 定期回顾和优化服务边界 参考资料