Spring Boot微服务架构实战:从单体到分布式的完整转型指南

发布于:2025-06-25 ⋅ 阅读:(17) ⋅ 点赞:(0)

📖 前言

微服务架构已经成为现代大型应用系统的主流架构模式。作为一名拥有多年企业级开发经验的架构师,我在过去三年中主导了多个大型项目从单体架构向微服务架构的转型,深刻体会到微服务在提升系统可扩展性、可维护性和团队协作效率方面的巨大价值。

今天我将通过一个完整的电商系统案例,详细展示如何使用Spring Boot技术栈设计和实现微服务架构,让你从零开始掌握微服务开发的核心技能!

🎯 本文你将学到:

  • 微服务架构设计原则和最佳实践
  • Spring Cloud微服务技术栈完整应用
  • 服务注册与发现、配置中心、网关设计
  • 分布式事务处理和数据一致性方案
  • 微服务监控、日志收集和链路追踪
  • 从单体到微服务的完整迁移策略

🚀 技术架构总览

核心技术栈

- Spring Boot 3.2.x
- Spring Cloud 2023.0.x
- Nacos 2.3.x (注册中心、配置中心)
- Spring Cloud Gateway (API网关)
- OpenFeign (服务调用)
- Seata (分布式事务)
- Redis (缓存)
- RocketMQ (消息队列)
- MySQL 8.0 (数据库)
- Docker + Kubernetes (容器化部署)

微服务拆分设计

├── gateway-service          # API网关服务
├── user-service            # 用户服务
├── product-service          # 商品服务
├── order-service            # 订单服务
├── payment-service          # 支付服务
├── inventory-service        # 库存服务
├── notification-service     # 通知服务
└── common-modules           # 公共模块
    ├── common-core         # 核心工具类
    ├── common-security     # 安全认证
    ├── common-redis        # Redis配置
    └── common-feign        # Feign配置

🏗️ 微服务架构设计

整体架构图

                           ┌─────────────────┐
                           │   Web Frontend  │
                           │   Mobile App    │
                           └─────────┬───────┘
                                     │
                           ┌─────────▼───────┐
                           │  API Gateway    │
                           │ (Load Balancer) │
                           └─────────┬───────┘
                                     │
        ┌────────────────────────────┼────────────────────────────┐
        │                           │                            │
┌───────▼────────┐         ┌────────▼─────────┐         ┌───────▼────────┐
│  User Service  │         │ Product Service  │         │ Order Service  │
│   (Port 8001)  │         │   (Port 8002)   │         │  (Port 8003)   │
└───────┬────────┘         └────────┬─────────┘         └───────┬────────┘
        │                           │                           │
┌───────▼────────┐         ┌────────▼─────────┐         ┌───────▼────────┐
│Payment Service │         │Inventory Service │         │Notify Service  │
│   (Port 8004)  │         │   (Port 8005)   │         │  (Port 8006)   │
└────────────────┘         └──────────────────┘         └────────────────┘
        │                           │                           │
        └───────────────────────────┼───────────────────────────┘
                                    │
                    ┌───────────────▼───────────────┐
                    │        Shared Services        │
                    │  • Nacos (Registry/Config)   │
                    │  • Redis (Cache)              │
                    │  • RocketMQ (Message Queue)   │
                    │  • MySQL (Database)           │
                    │  • Seata (Transaction)        │
                    └───────────────────────────────┘

服务依赖关系

# 服务间调用关系
gateway-service:
  - routes to all services
  
order-service:
  - calls: user-service, product-service, inventory-service, payment-service
  - sends: notification-service (async)
  
payment-service:
  - calls: user-service
  - sends: order-service (callback)
  
inventory-service:
  - calls: product-service
  
notification-service:
  - receives: order-service, payment-service

📦 核心服务实现

1. API网关服务设计

gateway-service架构:

// GatewayApplication.java
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

// 网关配置
@Configuration
public class GatewayConfig {
    
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("user-service", r -> r.path("/api/user/**")
                        .filters(f -> f.stripPrefix(2)
                                .addRequestHeader("X-Gateway", "spring-cloud-gateway")
                                .circuitBreaker(config -> config.setName("userServiceCB")))
                        .uri("lb://user-service"))
                .route("product-service", r -> r.path("/api/product/**")
                        .filters(f -> f.stripPrefix(2)
                                .retry(retryConfig -> retryConfig.setRetries(3)))
                        .uri("lb://product-service"))
                .route("order-service", r -> r.path("/api/order/**")
                        .filters(f -> f.stripPrefix(2)
                                .requestRateLimiter(config -> {
                                    config.setRateLimiter(redisRateLimiter());
                                    config.setKeyResolver(userKeyResolver());
                                }))
                        .uri("lb://order-service"))
                .build();
    }
    
    @Bean
    public RedisRateLimiter redisRateLimiter() {
        return new RedisRateLimiter(10, 20, 1);
    }
    
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> exchange.getRequest().getHeaders()
                .getFirst("X-User-Id") != null ? 
                Mono.just(exchange.getRequest().getHeaders().getFirst("X-User-Id")) :
                Mono.just("anonymous");
    }
}

// 全局异常处理
@Component
@Order(-1)
public class GlobalErrorHandler implements ErrorWebExceptionHandler {
    
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        ServerHttpResponse response = exchange.getResponse();
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        
        String errorMsg = switch (ex) {
            case ConnectTimeoutException ignored -> "服务连接超时";
            case CircuitBreakerOpenException ignored -> "服务熔断,请稍后重试";
            case RetryExhaustedException ignored -> "服务重试次数耗尽";
            default -> "网关内部错误";
        };
        
        String result = """
                {
                    "code": 500,
                    "message": "%s",
                    "timestamp": %d
                }
                """.formatted(errorMsg, System.currentTimeMillis());
        
        DataBuffer buffer = response.bufferFactory().wrap(result.getBytes());
        return response.writeWith(Mono.just(buffer));
    }
}

gateway配置文件:

# application.yml
server:
  port: 8000

spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: microservice
        group: DEFAULT_GROUP
      config:
        server-addr: localhost:8848
        namespace: microservice
        group: DEFAULT_GROUP
        file-extension: yml
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      default-filters:
        - AddRequestHeader=X-Gateway-Source, spring-cloud-gateway
        - AddResponseHeader=X-Response-Time, #{T(System).currentTimeMillis()}
      globalcors:
        cors-configurations:
          '[/**]':
            allowed-origins: "*"
            allowed-methods: "*"
            allowed-headers: "*"
            allow-credentials: true

# Redis配置(用于限流)
  redis:
    host: localhost
    port: 6379
    database: 0
    timeout: 3000ms

# 监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,gateway
  endpoint:
    health:
      show-details: always

# 日志配置
logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    reactor.netty.http.client: DEBUG

2. 用户服务实现

用户服务核心代码:

// UserService
@Service
@Transactional
@Slf4j
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private UserEventPublisher eventPublisher;
    
    public UserDTO createUser(CreateUserRequest request) {
        log.info("创建用户: {}", request.getUsername());
        
        // 检查用户名是否存在
        if (userRepository.existsByUsername(request.getUsername())) {
            throw new BusinessException("用户名已存在");
        }
        
        // 创建用户
        User user = User.builder()
                .username(request.getUsername())
                .email(request.getEmail())
                .password(passwordEncoder.encode(request.getPassword()))
                .phone(request.getPhone())
                .status(UserStatus.ACTIVE)
                .build();
        
        User savedUser = userRepository.save(user);
        
        // 发布用户创建事件
        eventPublisher.publishUserCreatedEvent(savedUser);
        
        // 清除相关缓存
        redisTemplate.delete("user:list:*");
        
        log.info("用户创建成功: {}", savedUser.getId());
        return convertToDTO(savedUser);
    }
    
    @Cacheable(value = "user:detail", key = "#userId", unless = "#result == null")
    public UserDTO getUserById(Long userId) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        return convertToDTO(user);
    }
    
    @CacheEvict(value = "user:detail", key = "#userId")
    public UserDTO updateUser(Long userId, UpdateUserRequest request) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException("用户不存在"));
        
        // 更新用户信息
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        
        User savedUser = userRepository.save(user);
        
        // 发布用户更新事件
        eventPublisher.publishUserUpdatedEvent(savedUser);
        
        return convertToDTO(savedUser);
    }
    
    private UserDTO convertToDTO(User user) {
        return UserDTO.builder()
                .id(user.getId())
                .username(user.getUsername())
                .email(user.getEmail())
                .phone(user.getPhone())
                .status(user.getStatus())
                .createTime(user.getCreateTime())
                .build();
    }
}

// UserController
@RestController
@RequestMapping("/users")
@Validated
@Slf4j
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @PostMapping
    public Result<UserDTO> createUser(@Valid @RequestBody CreateUserRequest request) {
        UserDTO user = userService.createUser(request);
        return Result.success(user);
    }
    
    @GetMapping("/{userId}")
    public Result<UserDTO> getUserById(@PathVariable Long userId) {
        UserDTO user = userService.getUserById(userId);
        return Result.success(user);
    }
    
    @PutMapping("/{userId}")
    public Result<UserDTO> updateUser(@PathVariable Long userId, 
                                     @Valid @RequestBody UpdateUserRequest request) {
        UserDTO user = userService.updateUser(userId, request);
        return Result.success(user);
    }
    
    @GetMapping("/{userId}/orders")
    public Result<List<OrderDTO>> getUserOrders(@PathVariable Long userId) {
        // 通过Feign调用订单服务
        List<OrderDTO> orders = orderServiceClient.getOrdersByUserId(userId);
        return Result.success(orders);
    }
}

// Feign客户端
@FeignClient(
    name = "order-service",
    fallbackFactory = OrderServiceFallbackFactory.class,
    configuration = FeignConfig.class
)
public interface OrderServiceClient {
    
    @GetMapping("/orders/user/{userId}")
    List<OrderDTO> getOrdersByUserId(@PathVariable("userId") Long userId);
    
    @PostMapping("/orders/{orderId}/cancel")
    Result<Void> cancelOrder(@PathVariable("orderId") Long orderId);
}

// Feign降级处理
@Component
public class OrderServiceFallbackFactory implements FallbackFactory<OrderServiceClient> {
    
    @Override
    public OrderServiceClient create(Throwable cause) {
        log.error("订单服务调用失败", cause);
        
        return new OrderServiceClient() {
            @Override
            public List<OrderDTO> getOrdersByUserId(Long userId) {
                // 返回缓存数据或空列表
                return Collections.emptyList();
            }
            
            @Override
            public Result<Void> cancelOrder(Long orderId) {
                return Result.error("订单服务暂时不可用,请稍后重试");
            }
        };
    }
}

3. 订单服务实现

订单服务核心业务:

// OrderService
@Service
@Transactional
@Slf4j
public class OrderService {
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    @Autowired
    private ProductServiceClient productServiceClient;
    
    @Autowired
    private InventoryServiceClient inventoryServiceClient;
    
    @Autowired
    private PaymentServiceClient paymentServiceClient;
    
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    
    @GlobalTransactional(rollbackFor = Exception.class)
    public OrderDTO createOrder(CreateOrderRequest request) {
        log.info("创建订单开始: {}", request);
        
        try {
            // 1. 验证用户信息
            UserDTO user = userServiceClient.getUserById(request.getUserId());
            if (user == null) {
                throw new BusinessException("用户不存在");
            }
            
            // 2. 验证商品信息并计算价格
            List<OrderItem> orderItems = new ArrayList<>();
            BigDecimal totalAmount = BigDecimal.ZERO;
            
            for (CreateOrderRequest.OrderItemRequest itemRequest : request.getItems()) {
                ProductDTO product = productServiceClient.getProductById(itemRequest.getProductId());
                if (product == null) {
                    throw new BusinessException("商品不存在: " + itemRequest.getProductId());
                }
                
                // 检查库存
                boolean hasStock = inventoryServiceClient.checkStock(
                    itemRequest.getProductId(), itemRequest.getQuantity());
                if (!hasStock) {
                    throw new BusinessException("库存不足: " + product.getName());
                }
                
                OrderItem orderItem = OrderItem.builder()
                        .productId(itemRequest.getProductId())
                        .productName(product.getName())
                        .price(product.getPrice())
                        .quantity(itemRequest.getQuantity())
                        .amount(product.getPrice().multiply(BigDecimal.valueOf(itemRequest.getQuantity())))
                        .build();
                
                orderItems.add(orderItem);
                totalAmount = totalAmount.add(orderItem.getAmount());
            }
            
            // 3. 创建订单
            Order order = Order.builder()
                    .userId(request.getUserId())
                    .orderNo(generateOrderNo())
                    .totalAmount(totalAmount)
                    .status(OrderStatus.PENDING)
                    .orderItems(orderItems)
                    .build();
            
            Order savedOrder = orderRepository.save(order);
            
            // 4. 扣减库存
            for (OrderItem item : orderItems) {
                inventoryServiceClient.reduceStock(item.getProductId(), item.getQuantity());
            }
            
            // 5. 创建支付订单
            CreatePaymentRequest paymentRequest = CreatePaymentRequest.builder()
                    .orderId(savedOrder.getId())
                    .userId(savedOrder.getUserId())
                    .amount(savedOrder.getTotalAmount())
                    .build();
            
            PaymentDTO payment = paymentServiceClient.createPayment(paymentRequest);
            
            // 6. 发送订单创建消息
            OrderCreatedEvent event = OrderCreatedEvent.builder()
                    .orderId(savedOrder.getId())
                    .userId(savedOrder.getUserId())
                    .totalAmount(savedOrder.getTotalAmount())
                    .build();
            
            rocketMQTemplate.convertAndSend("order-topic:created", event);
            
            log.info("订单创建成功: {}", savedOrder.getId());
            return convertToDTO(savedOrder, payment);
            
        } catch (Exception e) {
            log.error("订单创建失败", e);
            throw new BusinessException("订单创建失败: " + e.getMessage());
        }
    }
    
    @Transactional(readOnly = true)
    public OrderDTO getOrderById(Long orderId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new BusinessException("订单不存在"));
        return convertToDTO(order, null);
    }
    
    @GlobalTransactional(rollbackFor = Exception.class)
    public void cancelOrder(Long orderId) {
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new BusinessException("订单不存在"));
        
        if (!order.canCancel()) {
            throw new BusinessException("订单状态不允许取消");
        }
        
        // 恢复库存
        for (OrderItem item : order.getOrderItems()) {
            inventoryServiceClient.restoreStock(item.getProductId(), item.getQuantity());
        }
        
        // 取消支付
        paymentServiceClient.cancelPayment(order.getId());
        
        // 更新订单状态
        order.setStatus(OrderStatus.CANCELLED);
        orderRepository.save(order);
        
        // 发送订单取消消息
        OrderCancelledEvent event = OrderCancelledEvent.builder()
                .orderId(orderId)
                .userId(order.getUserId())
                .build();
        
        rocketMQTemplate.convertAndSend("order-topic:cancelled", event);
    }
    
    private String generateOrderNo() {
        return "ORD" + System.currentTimeMillis() + 
               String.format("%04d", new Random().nextInt(10000));
    }
    
    private OrderDTO convertToDTO(Order order, PaymentDTO payment) {
        return OrderDTO.builder()
                .id(order.getId())
                .orderNo(order.getOrderNo())
                .userId(order.getUserId())
                .totalAmount(order.getTotalAmount())
                .status(order.getStatus())
                .items(order.getOrderItems().stream()
                        .map(this::convertItemToDTO)
                        .collect(Collectors.toList()))
                .payment(payment)
                .createTime(order.getCreateTime())
                .build();
    }
}

// 支付回调处理
@RocketMQMessageListener(
    topic = "payment-topic",
    consumerGroup = "order-payment-consumer",
    selectorExpression = "success || failed"
)
@Component
public class PaymentResultListener implements RocketMQListener<PaymentResultEvent> {
    
    @Autowired
    private OrderService orderService;
    
    @Override
    public void onMessage(PaymentResultEvent event) {
        log.info("收到支付结果: {}", event);
        
        try {
            if ("success".equals(event.getStatus())) {
                orderService.handlePaymentSuccess(event.getOrderId(), event.getPaymentId());
            } else {
                orderService.handlePaymentFailed(event.getOrderId(), event.getReason());
            }
        } catch (Exception e) {
            log.error("处理支付结果失败", e);
            // 可以发送到死信队列或者重试
        }
    }
}

4. 配置中心与服务发现

Nacos配置管理:

# 公共配置 (common.yml)
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      minimum-idle: 5
      maximum-pool-size: 20
      idle-timeout: 300000
      connection-timeout: 20000
      max-lifetime: 1200000
  
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
  
  redis:
    host: localhost
    port: 6379
    database: 0
    timeout: 3000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0

# RocketMQ配置
rocketmq:
  name-server: localhost:9876
  producer:
    group: microservice-producer
    send-message-timeout: 3000
    retry-times-when-send-failed: 3

# Seata分布式事务配置
seata:
  application-id: ${spring.application.name}
  tx-service-group: microservice-group
  service:
    vgroup-mapping:
      microservice-group: default
    grouplist:
      default: localhost:8091
  registry:
    type: nacos
    nacos:
      server-addr: localhost:8848
      namespace: microservice

# 监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always

# 日志配置
logging:
  level:
    com.example: INFO
    org.springframework.cloud: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%X{traceId}] %logger{36} - %msg%n"

🔧 分布式事务处理

Seata分布式事务配置

AT模式事务处理:

// 分布式事务配置
@Configuration
public class SeataConfig {
    
    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
        return new GlobalTransactionScanner("microservice-seata", "microservice-group");
    }
}

// 事务管理器
@Component
public class DistributedTransactionManager {
    
    @GlobalTransactional(rollbackFor = Exception.class, timeoutMills = 30000)
    public void executeDistributedTransaction(TransactionContext context) {
        try {
            // 执行业务逻辑
            context.getActions().forEach(action -> {
                try {
                    action.execute();
                } catch (Exception e) {
                    log.error("分布式事务执行失败", e);
                    throw new RuntimeException("事务执行失败", e);
                }
            });
        } catch (Exception e) {
            log.error("分布式事务回滚", e);
            throw e;
        }
    }
}

// TCC模式实现示例
@LocalTCC
public interface InventoryTccService {
    
    @TwoPhaseBusinessAction(
        name = "reduceStock",
        commitMethod = "commit",
        rollbackMethod = "rollback"
    )
    boolean reduceStock(BusinessActionContext context, 
                       @BusinessActionContextParameter("productId") Long productId,
                       @BusinessActionContextParameter("quantity") Integer quantity);
    
    boolean commit(BusinessActionContext context);
    
    boolean rollback(BusinessActionContext context);
}

@Service
public class InventoryTccServiceImpl implements InventoryTccService {
    
    @Autowired
    private InventoryRepository inventoryRepository;
    
    @Override
    public boolean reduceStock(BusinessActionContext context, Long productId, Integer quantity) {
        log.info("TCC Try: 冻结库存 productId={}, quantity={}", productId, quantity);
        
        // 冻结库存而不是直接扣减
        Inventory inventory = inventoryRepository.findByProductId(productId);
        if (inventory.getAvailableStock() < quantity) {
            throw new BusinessException("库存不足");
        }
        
        inventory.setFrozenStock(inventory.getFrozenStock() + quantity);
        inventoryRepository.save(inventory);
        
        return true;
    }
    
    @Override
    public boolean commit(BusinessActionContext context) {
        Long productId = Long.valueOf(context.getActionContext("productId").toString());
        Integer quantity = Integer.valueOf(context.getActionContext("quantity").toString());
        
        log.info("TCC Commit: 确认扣减库存 productId={}, quantity={}", productId, quantity);
        
        Inventory inventory = inventoryRepository.findByProductId(productId);
        inventory.setActualStock(inventory.getActualStock() - quantity);
        inventory.setFrozenStock(inventory.getFrozenStock() - quantity);
        inventoryRepository.save(inventory);
        
        return true;
    }
    
    @Override
    public boolean rollback(BusinessActionContext context) {
        Long productId = Long.valueOf(context.getActionContext("productId").toString());
        Integer quantity = Integer.valueOf(context.getActionContext("quantity").toString());
        
        log.info("TCC Rollback: 释放冻结库存 productId={}, quantity={}", productId, quantity);
        
        Inventory inventory = inventoryRepository.findByProductId(productId);
        inventory.setFrozenStock(inventory.getFrozenStock() - quantity);
        inventoryRepository.save(inventory);
        
        return true;
    }
}

📊 监控与链路追踪

Spring Cloud Sleuth + Zipkin

链路追踪配置:

# 链路追踪配置
spring:
  sleuth:
    sampler:
      probability: 1.0  # 采样率100%(生产环境建议0.1)
    zipkin:
      base-url: http://localhost:9411
      sender:
        type: web
    web:
      client:
        enabled: true
    feign:
      enabled: true
    rocketmq:
      enabled: true

自定义链路追踪:

// 链路追踪组件
@Component
public class TraceService {
    
    private final Tracer tracer;
    
    public TraceService(Tracer tracer) {
        this.tracer = tracer;
    }
    
    public <T> T traceCall(String operationName, Supplier<T> supplier) {
        Span span = tracer.nextSpan().name(operationName);
        try (Tracer.SpanInScope ws = tracer.withSpanInScope(span)) {
            span.start();
            return supplier.get();
        } catch (Exception e) {
            span.tag("error", e.getMessage());
            throw e;
        } finally {
            span.end();
        }
    }
    
    public void addTag(String key, String value) {
        Span currentSpan = tracer.currentSpan();
        if (currentSpan != null) {
            currentSpan.tag(key, value);
        }
    }
}

// 使用示例
@Service
public class OrderTraceService {
    
    @Autowired
    private TraceService traceService;
    
    public OrderDTO createOrder(CreateOrderRequest request) {
        return traceService.traceCall("create-order", () -> {
            traceService.addTag("user.id", request.getUserId().toString());
            traceService.addTag("order.items.count", String.valueOf(request.getItems().size()));
            
            // 执行业务逻辑
            return doCreateOrder(request);
        });
    }
}

🚀 部署配置

Docker化部署

多服务docker-compose:

version: '3.8'

services:
  # Nacos
  nacos:
    image: nacos/nacos-server:v2.3.0
    container_name: nacos
    environment:
      - MODE=standalone
      - SPRING_DATASOURCE_PLATFORM=mysql
      - MYSQL_SERVICE_HOST=mysql
      - MYSQL_SERVICE_DB_NAME=nacos
      - MYSQL_SERVICE_USER=nacos
      - MYSQL_SERVICE_PASSWORD=nacos123456
    ports:
      - "8848:8848"
    depends_on:
      - mysql
    networks:
      - microservice-network

  # API Gateway
  gateway-service:
    build: ./gateway-service
    container_name: gateway-service
    ports:
      - "8000:8000"
    environment:
      - NACOS_SERVER_ADDR=nacos:8848
      - REDIS_HOST=redis
    depends_on:
      - nacos
      - redis
    networks:
      - microservice-network

  # User Service
  user-service:
    build: ./user-service
    container_name: user-service
    ports:
      - "8001:8001"
    environment:
      - NACOS_SERVER_ADDR=nacos:8848
      - MYSQL_HOST=mysql
      - REDIS_HOST=redis
    depends_on:
      - nacos
      - mysql
      - redis
    networks:
      - microservice-network

  # Product Service
  product-service:
    build: ./product-service
    container_name: product-service
    ports:
      - "8002:8002"
    environment:
      - NACOS_SERVER_ADDR=nacos:8848
      - MYSQL_HOST=mysql
      - REDIS_HOST=redis
    depends_on:
      - nacos
      - mysql
      - redis
    networks:
      - microservice-network

  # Order Service
  order-service:
    build: ./order-service
    container_name: order-service
    ports:
      - "8003:8003"
    environment:
      - NACOS_SERVER_ADDR=nacos:8848
      - MYSQL_HOST=mysql
      - REDIS_HOST=redis
      - ROCKETMQ_NAME_SERVER=rocketmq:9876
      - SEATA_SERVER_ADDR=seata:8091
    depends_on:
      - nacos
      - mysql
      - redis
      - rocketmq
      - seata
    networks:
      - microservice-network

  # Supporting Services
  mysql:
    image: mysql:8.0
    container_name: mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root123456
      - MYSQL_DATABASE=microservice
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
      - ./sql:/docker-entrypoint-initdb.d
    networks:
      - microservice-network

  redis:
    image: redis:7-alpine
    container_name: redis
    ports:
      - "6379:6379"
    networks:
      - microservice-network

  rocketmq:
    image: apache/rocketmq:5.1.4
    container_name: rocketmq
    ports:
      - "9876:9876"
      - "10911:10911"
    environment:
      - NAMESRV_ADDR=localhost:9876
    networks:
      - microservice-network

  seata:
    image: seataio/seata-server:1.8.0
    container_name: seata
    ports:
      - "8091:8091"
    environment:
      - SEATA_CONFIG_NAME=file:/root/seata-config/registry
    volumes:
      - ./seata:/root/seata-config
    networks:
      - microservice-network

volumes:
  mysql_data:

networks:
  microservice-network:
    driver: bridge

🎯 总结

通过本文的完整实战演示,我们成功构建了:

✅ 核心成果:

  • 完整的Spring Boot微服务架构体系
  • 生产级的服务治理和配置管理
  • 分布式事务和数据一致性方案
  • 完善的监控和链路追踪体系

📈 关键优势:

  • 高可用性:服务隔离、熔断降级、容错处理
  • 高扩展性:服务独立部署、水平扩展
  • 高性能:分布式缓存、异步消息处理
  • 易维护:统一配置管理、链路追踪、日志聚合

🚀 最佳实践建议:

  1. 合理进行服务拆分,避免过度拆分
  2. 重视数据一致性设计,选择合适的事务模式
  3. 完善监控和告警机制,提升运维效率
  4. 持续优化性能,关注服务间调用开销
  5. 建立完整的测试体系,保证代码质量

微服务架构是现代大型系统的必然选择。掌握Spring Boot微服务开发技能,将让你在分布式系统设计和开发中游刃有余!


🔖 相关文章推荐:

  • Docker容器化部署实战指南
  • Kubernetes微服务编排实战
  • 分布式系统设计模式详解

💬 交流讨论:
你在微服务架构实践中遇到过哪些挑战?欢迎在评论区分享你的经验和解决方案!


网站公告

今日签到

点亮在社区的每一天
去签到