0
点赞
收藏
分享

微信扫一扫

Spring Boot微服务架构实战指南

闲云困兽 18小时前 阅读 1

概述

微服务架构是现代企业级应用开发的主流模式,它将单体应用拆分为多个独立的、可部署的服务。Spring Boot作为Java生态中最受欢迎的框架,为微服务开发提供了完整的解决方案。本文将深入探讨如何使用Spring Boot构建高效、可扩展的微服务系统。

核心技术组件

1. 技术栈选择

  • Spring Boot: 核心框架,简化配置
  • Spring Cloud: 微服务治理工具集
  • Eureka: 服务注册与发现
  • Feign: 声明式HTTP客户端
  • Hystrix: 熔断器模式实现
  • Gateway: API网关

项目架构设计

用户服务实现

@RestController
@RequestMapping("/api/users")
@Slf4j
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @GetMapping("/{id}")
    @Cacheable(value = "users", key = "#id")
    public ResponseEntity<UserDTO> getUserById(@PathVariable Long id) {
        log.info("获取用户信息: {}", id);
        
        try {
            UserDTO user = userService.findById(id);
            if (user != null) {
                return ResponseEntity.ok(user);
            } else {
                return ResponseEntity.notFound().build();
            }
        } catch (Exception e) {
            log.error("获取用户信息失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
    
    @PostMapping
    @Transactional
    public ResponseEntity<UserDTO> createUser(@Valid @RequestBody CreateUserRequest request) {
        log.info("创建用户: {}", request.getUsername());
        
        // 参数验证
        if (userService.existsByUsername(request.getUsername())) {
            return ResponseEntity.badRequest()
                .body(new ErrorResponse("用户名已存在"));
        }
        
        UserDTO createdUser = userService.createUser(request);
        
        // 发布用户创建事件
        eventPublisher.publishEvent(new UserCreatedEvent(createdUser));
        
        return ResponseEntity.status(HttpStatus.CREATED).body(createdUser);
    }
}

服务间通信配置

@Component
@FeignClient(name = "order-service", fallback = OrderServiceFallback.class)
public interface OrderServiceClient {
    
    @GetMapping("/api/orders/user/{userId}")
    List<OrderDTO> getUserOrders(@PathVariable("userId") Long userId);
    
    @PostMapping("/api/orders")
    OrderDTO createOrder(@RequestBody CreateOrderRequest request);
}

@Component
public class OrderServiceFallback implements OrderServiceClient {
    
    @Override
    public List<OrderDTO> getUserOrders(Long userId) {
        log.warn("订单服务调用失败,返回默认值");
        return Collections.emptyList();
    }
    
    @Override
    public OrderDTO createOrder(CreateOrderRequest request) {
        log.error("订单服务不可用");
        throw new ServiceUnavailableException("订单服务暂时不可用");
    }
}

配置管理与服务发现

application.yml配置

server:
  port: ${SERVER_PORT:8080}

spring:
  application:
    name: user-service
  
  datasource:
    url: jdbc:mysql://localhost:3306/user_db?useSSL=false&serverTimezone=UTC
    username: ${DB_USERNAME:root}
    password: ${DB_PASSWORD:password}
    driver-class-name: com.mysql.cj.jdbc.Driver
  
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
  
  redis:
    host: ${REDIS_HOST:localhost}
    port: 6379
    timeout: 2000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 30

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always

logging:
  level:
    com.example: INFO
    org.springframework.web: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

启动类配置

@SpringBootApplication
@EnableEurekaClient
@EnableJpaRepositories
@EnableCaching
@EnableScheduling
public class UserServiceApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
            .serializeKeysWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair
                .fromSerializer(new GenericJackson2JsonRedisSerializer()))
            .entryTtl(Duration.ofMinutes(30));
            
        return RedisCacheManager.builder(factory)
            .cacheDefaults(config)
            .build();
    }
}

数据持久化层

实体类定义

@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(unique = true, nullable = false)
    private String username;
    
    @Column(nullable = false)
    private String email;
    
    @Column(name = "phone_number")
    private String phoneNumber;
    
    @Enumerated(EnumType.STRING)
    private UserStatus status = UserStatus.ACTIVE;
    
    @CreationTimestamp
    @Column(name = "created_at")
    private LocalDateTime createdAt;
    
    @UpdateTimestamp
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;
    
    @Version
    private Integer version;
}

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    
    Optional<User> findByUsername(String username);
    
    boolean existsByUsername(String username);
    
    @Query("SELECT u FROM User u WHERE u.status = :status")
    Page<User> findByStatus(@Param("status") UserStatus status, Pageable pageable);
    
    @Modifying
    @Query("UPDATE User u SET u.status = :status WHERE u.id = :id")
    int updateUserStatus(@Param("id") Long id, @Param("status") UserStatus status);
}

服务层实现

@Service
@Transactional
@Slf4j
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    @Retryable(value = {DataAccessException.class}, maxAttempts = 3)
    public UserDTO createUser(CreateUserRequest request) {
        log.info("创建新用户: {}", request.getUsername());
        
        User user = userMapper.toEntity(request);
        user.setStatus(UserStatus.ACTIVE);
        
        User savedUser = userRepository.save(user);
        
        // 发布事件
        eventPublisher.publishEvent(new UserCreatedEvent(savedUser.getId()));
        
        return userMapper.toDTO(savedUser);
    }
    
    @Cacheable(value = "users", key = "#id", unless = "#result == null")
    public UserDTO findById(Long id) {
        return userRepository.findById(id)
            .map(userMapper::toDTO)
            .orElse(null);
    }
    
    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
        log.info("用户已删除: {}", id);
    }
}

监控与健康检查

@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public Health health() {
        try {
            long userCount = userRepository.count();
            return Health.up()
                .withDetail("users.count", userCount)
                .withDetail("status", "服务正常运行")
                .build();
        } catch (Exception e) {
            return Health.down()
                .withDetail("error", e.getMessage())
                .build();
        }
    }
}

@RestController
@RequestMapping("/actuator/custom")
public class CustomMetricsController {
    
    @Autowired
    private MeterRegistry meterRegistry;
    
    @GetMapping("/metrics")
    public Map<String, Object> getCustomMetrics() {
        Map<String, Object> metrics = new HashMap<>();
        
        Counter.Sample sample = Timer.start(meterRegistry);
        // 业务逻辑执行时间统计
        sample.stop(Timer.builder("business.execution.time")
            .description("业务执行时间")
            .register(meterRegistry));
            
        return metrics;
    }
}

Docker部署配置

FROM openjdk:11-jre-slim

VOLUME /tmp

COPY target/user-service-1.0.0.jar app.jar

EXPOSE 8080

ENV JAVA_OPTS=""

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar"]

最佳实践总结

1. 服务设计原则

  • 单一职责: 每个服务专注于特定的业务领域
  • 无状态设计: 服务实例间可以任意切换
  • 数据库独立: 避免服务间直接数据库访问

2. 性能优化策略

  • 合理使用缓存减少数据库访问
  • 实现服务熔断避免级联失败
  • 采用异步处理提升响应速度
  • 数据库连接池优化

3. 监控与运维

  • 集成APM工具进行性能监控
  • 实现分布式链路追踪
  • 配置告警机制及时发现问题
  • 定期进行容量规划和性能测试

微服务架构虽然带来了系统的灵活性和可扩展性,但也增加了复杂度。通过Spring Boot生态的支持,我们可以更轻松地构建和管理微服务系统,实现企业级应用的现代化改造。

举报

相关推荐

0 条评论