# Spring Boot 3微服务架构:构建企业级分布式系统实战
在数字化转型浪潮中,企业级应用对高可用、可扩展架构的需求日益迫切。基于Spring Boot 3的微服务架构,通过现代化的技术栈和设计模式,为构建分布式系统提供了完整的解决方案。
## 微服务基础架构设计
Spring Boot 3配合Spring Cloud 2022.x,构建了完整的微服务生态系统。
```java
// 服务注册与发现配置
// discovery-service/src/main/java/com/example/discovery/DiscoveryApplication.java
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryApplication.class, args);
}
}
// application-discovery.yml
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
enable-self-preservation: false
renewal-percent-threshold: 0.85
spring:
application:
name: discovery-service
security:
user:
name: admin
password: ${DISCOVERY_PASSWORD:admin123}
```
## 配置中心与服务治理
```java
// config-service/src/main/java/com/example/config/ConfigApplication.java
@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
// application-config.yml
server:
port: 8888
spring:
application:
name: config-service
profiles:
active: native
cloud:
config:
server:
native:
search-locations: classpath:/config-repo
encrypt:
enabled: true
bootstrap: true
encrypt:
key: ${CONFIG_ENCRYPT_KEY:changeme}
# Git仓库配置(可选)
# spring:
# cloud:
# config:
# server:
# git:
# uri: https://github.com/your-repo/config-repo
# search-paths: '{application}'
# default-label: main
// config-repo/application-common.yml
# 公共配置
spring:
datasource:
url: jdbc:mysql://${DB_HOST:localhost}:3306/${DB_NAME:microservice}?useSSL=false&serverTimezone=UTC
username: ${DB_USER:root}
password: ${DB_PASSWORD:password}
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
format_sql: true
redis:
host: ${REDIS_HOST:localhost}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:}
timeout: 5000ms
lettuce:
pool:
max-active: 20
max-idle: 10
min-idle: 5
max-wait: -1ms
# Spring Cloud配置
eureka:
client:
service-url:
defaultZone: http://${EUREKA_HOST:localhost}:8761/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.application.instance-id:${random.value}}
# 熔断器配置
resilience4j:
circuitbreaker:
instances:
default:
register-health-indicator: true
sliding-window-size: 10
minimum-number-of-calls: 5
permitted-number-of-calls-in-half-open-state: 3
automatic-transition-from-open-to-half-open-enabled: true
wait-duration-in-open-state: 5s
failure-rate-threshold: 50
event-consumer-buffer-size: 10
retry:
instances:
default:
max-attempts: 3
wait-duration: 1s
retry-exceptions:
- org.springframework.web.client.HttpServerErrorException
- java.net.ConnectException
bulkhead:
instances:
default:
max-concurrent-calls: 25
max-wait-duration: 0
# Sleuth链路追踪
spring:
sleuth:
enabled: true
sampler:
probability: 1.0
propagation:
type: B3
zipkin:
base-url: http://${ZIPKIN_HOST:localhost}:9411/
# 监控配置
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: always
metrics:
export:
prometheus:
enabled: true
distribution:
percentiles-histogram:
http.server.requests: true
tracing:
sampling:
probability: 0.1
```
## 业务微服务实现
```java
// user-service/src/main/java/com/example/user/UserApplication.java
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
// UserController.java - 用户服务API
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
@Slf4j
public class UserController {
private final UserService userService;
private final OrderServiceClient orderServiceClient;
private final CircuitBreakerFactory circuitBreakerFactory;
private final Tracer tracer;
@Operation(summary = "获取用户详情")
@GetMapping("/{userId}")
@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
public ResponseEntity
UserDTO user = userService.getUserById(userId);
return ResponseEntity.ok(user);
}
@Operation(summary = "获取用户订单")
@GetMapping("/{userId}/orders")
@PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
public ResponseEntity> getUserOrders(@PathVariable Long userId) {
// 使用熔断器包装外部调用
CircuitBreaker circuitBreaker = circuitBreakerFactory.create("orderService");
List
() -> orderServiceClient.getUserOrders(userId),
throwable -> {
log.error("获取用户订单失败,使用降级策略", throwable);
return Collections.emptyList();
}
);
// 添加链路追踪信息
Span span = tracer.nextSpan().name("user-orders-query").start();
try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
span.tag("user.id", userId.toString());
span.tag("order.count", String.valueOf(orders.size()));
} finally {
span.end();
}
return ResponseEntity.ok(orders);
}
@Operation(summary = "创建用户")
@PostMapping
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity
UserDTO user = userService.createUser(createDTO);
return ResponseEntity.status(HttpStatus.CREATED)
.header("Location", "/api/v1/users/" + user.getId())
.body(user);
}
@Operation(summary = "批量用户查询")
@GetMapping("/batch")
public ResponseEntity> getUsersBatch(@RequestParam List
// 使用并行流提高查询性能
List
.map(userId -> CompletableFuture.supplyAsync(
() -> userService.getUserById(userId),
userService.getExecutor()
))
.collect(Collectors.toList());
List
.map(CompletableFuture::join)
.filter(Objects::nonNull)
.collect(Collectors.toList());
return ResponseEntity.ok(users);
}
}
// UserService.java - 用户服务业务逻辑
@Service
@RequiredArgsConstructor
@Slf4j
public class UserService {
private final UserRepository userRepository;
private final RoleRepository roleRepository;
private final PasswordEncoder passwordEncoder;
private final CacheManager cacheManager;
private final EventPublisher eventPublisher;
private final RetryTemplate retryTemplate;
@Transactional
public UserDTO createUser(CreateUserDTO createDTO) {
// 检查用户名是否已存在
if (userRepository.existsByUsername(createDTO.getUsername())) {
throw new BusinessException("用户名已存在");
}
// 检查邮箱是否已注册
if (userRepository.existsByEmail(createDTO.getEmail())) {
throw new BusinessException("邮箱已被注册");
}
// 创建用户实体
User user = User.builder()
.username(createDTO.getUsername())
.password(passwordEncoder.encode(createDTO.getPassword()))
.email(createDTO.getEmail())
.phone(createDTO.getPhone())
.status(UserStatus.ACTIVE)
.build();
// 分配默认角色
Role userRole = roleRepository.findByName("ROLE_USER")
.orElseThrow(() -> new ResourceNotFoundException("默认角色不存在"));
user.addRole(userRole);
// 使用重试机制保存用户
User savedUser = retryTemplate.execute(context -> {
log.info("保存用户,重试次数: {}", context.getRetryCount());
return userRepository.save(user);
});
// 清除缓存
evictUserCache(savedUser.getId(), savedUser.getUsername());
// 发布用户创建事件
eventPublisher.publishEvent(new UserCreatedEvent(
savedUser.getId(),
savedUser.getUsername(),
savedUser.getEmail()
));
log.info("用户创建成功: {}", savedUser.getUsername());
return UserMapper.INSTANCE.toDTO(savedUser);
}
@Cacheable(value = "users", key = "#userId")
public UserDTO getUserById(Long userId) {
return userRepository.findById(userId)
.map(UserMapper.INSTANCE::toDTO)
.orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
}
@Cacheable(value = "users", key = "#username")
public UserDTO getUserByUsername(String username) {
return userRepository.findByUsername(username)
.map(UserMapper.INSTANCE::toDTO)
.orElseThrow(() -> new ResourceNotFoundException("用户不存在"));
}
<"b3.p5k3.org.cn"><"r9.p5k3.org.cn"><"k2.p5k3.org.cn">
@Caching(evict = {
@CacheEvict(value = "users", key = "#userId"),
@CacheEvict(value = "users", key = "#username")
})
public void evictUserCache(Long userId, String username) {
log.debug("清除用户缓存: userId={}, username={}", userId, username);
}
@Async("userTaskExecutor")
public CompletableFuture
return CompletableFuture.completedFuture(getUserById(userId));
}
@Bean("userTaskExecutor")
public Executor userTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("user-task-");
executor.initialize();
return executor;
}
}
// OrderServiceClient.java - Feign客户端
@FeignClient(
name = "order-service",
url = "${feign.client.order-service.url:}",
configuration = OrderServiceClientConfig.class,
fallbackFactory = OrderServiceClientFallbackFactory.class
)
public interface OrderServiceClient {
@GetMapping("/api/v1/orders/users/{userId}")
List
@PostMapping("/api/v1/orders")
OrderDTO createOrder(@RequestBody CreateOrderDTO createDTO);
@GetMapping("/api/v1/orders/{orderId}")
OrderDTO getOrderDetail(@PathVariable Long orderId);
}
// OrderServiceClientConfig.java - Feign配置
@Configuration
public class OrderServiceClientConfig {
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(1000, 2000, 3);
}
@Bean
public ErrorDecoder feignErrorDecoder() {
return new FeignErrorDecoder();
}
@Bean
public RequestInterceptor oauth2FeignRequestInterceptor() {
return requestTemplate -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.getCredentials() instanceof String token) {
requestTemplate.header("Authorization", "Bearer " + token);
}
};
}
}
// OrderServiceClientFallbackFactory.java - 降级工厂
@Component
@Slf4j
public class OrderServiceClientFallbackFactory implements FallbackFactory
@Override
public OrderServiceClient create(Throwable cause) {
return new OrderServiceClient() {
@Override
public List
log.warn("订单服务不可用,返回空订单列表", cause);
return Collections.emptyList();
}
@Override
public OrderDTO createOrder(CreateOrderDTO createDTO) {
log.error("订单服务不可用,无法创建订单", cause);
throw new ServiceUnavailableException("订单服务暂时不可用");
}
@Override
public OrderDTO getOrderDetail(Long orderId) {
log.error("订单服务不可用,无法获取订单详情", cause);
throw new ServiceUnavailableException("订单服务暂时不可用");
}
};
}
}
```
## 分布式事务管理
```java
// TransactionService.java - 分布式事务服务
@Service
@RequiredArgsConstructor
@Slf4j
public class TransactionService {
private final UserService userService;
private final AccountService accountService;
private final OrderService orderService;
private final InventoryService inventoryService;
private final TransactionTemplate transactionTemplate;
private final StringRedisTemplate redisTemplate;
@Transactional(rollbackFor = Exception.class)
public OrderDTO placeOrderWithTransaction(PlaceOrderDTO orderDTO) {
// 阶段1:验证和预处理
validateOrder(orderDTO);
// 阶段2:创建订单(本地事务)
OrderDTO order = orderService.createOrder(orderDTO);
// 阶段3:扣减库存(分布式事务)
try {
inventoryService.deductInventory(orderDTO.getItems());
} catch (Exception e) {
// 库存扣减失败,补偿订单
orderService.cancelOrder(order.getId(), "库存不足");
throw new BusinessException("库存扣减失败", e);
}
// 阶段4:扣减账户余额(分布式事务)
try {
accountService.deductBalance(orderDTO.getUserId(), order.getFinalAmount());
} catch (Exception e) {
// 余额扣减失败,补偿库存和订单
inventoryService.restoreInventory(orderDTO.getItems());
orderService.cancelOrder(order.getId(), "余额不足");
throw new BusinessException("余额扣减失败", e);
}
// 阶段5:发送订单创建消息
sendOrderCreatedMessage(order);
return order;
}
@Saga
public void processPaymentSaga(PaymentSagaDTO sagaDTO) {
// Saga模式处理分布式事务
TransactionSaga saga = new TransactionSaga("payment-saga-" + sagaDTO.getOrderId());
saga.start()
.step("deduct-inventory")
.invoke(() -> inventoryService.deductInventory(sagaDTO.getItems()))
.withCompensation(() -> inventoryService.restoreInventory(sagaDTO.getItems()))
.step("deduct-balance")
.invoke(() -> accountService.deductBalance(sagaDTO.getUserId(), sagaDTO.getAmount()))
.withCompensation(() -> accountService.refundBalance(sagaDTO.getUserId(), sagaDTO.getAmount()))
.step("create-order")
.invoke(() -> orderService.createOrder(sagaDTO.getOrderDTO()))
.withCompensation(() -> orderService.cancelOrder(sagaDTO.getOrderId(), "支付失败"))
.step("send-notification")
.invoke(() -> notificationService.sendOrderNotification(sagaDTO.getOrderId()))
.end();
saga.execute();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void recordTransactionLog(TransactionLog log) {
// 记录事务日志
transactionLogRepository.save(log);
// 发布事务事件
applicationEventPublisher.publishEvent(
new TransactionRecordedEvent(log.getId(), log.getType(), log.getStatus())
);
}
private void validateOrder(PlaceOrderDTO orderDTO) {
// 验证用户状态
UserDTO user = userService.getUserById(orderDTO.getUserId());
if (!UserStatus.ACTIVE.equals(user.getStatus())) {
throw new BusinessException("用户状态异常");
}
// 验证商品状态
orderDTO.getItems().forEach(item -> {
ProductDTO product = productService.getProductById(item.getProductId());
if (!product.isAvailable()) {
throw new BusinessException("商品" + product.getName() + "不可用");
}
});
// 分布式锁:防止重复下单
String lockKey = "order:lock:" + orderDTO.getUserId() + ":" + orderDTO.getItemsHash();
Boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", Duration.ofSeconds(30));
if (Boolean.FALSE.equals(locked)) {
throw new BusinessException("操作过于频繁,请稍后重试");
}
}
}
// Seata分布式事务配置
@Configuration
public class SeataConfig {
<"p5.p5k3.org.cn"><"m1.p5k3.org.cn"><"a8.p5k3.org.cn">
@Bean
public DataSourceProxy dataSourceProxy(DataSource dataSource) {
return new DataSourceProxy(dataSource);
}
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
return new GlobalTransactionScanner(
"${spring.application.name}",
"my_test_tx_group"
);
}
@Bean
public FailureHandler failureHandler() {
return new DefaultFailureHandlerImpl();
}
}
// 使用Seata分布式事务
@Service
public class OrderServiceWithSeata {
@GlobalTransactional(name = "create-order-tx", timeoutMills = 60000)
public OrderDTO createOrderWithSeata(CreateOrderDTO createDTO) {
// 创建订单
OrderDTO order = createOrder(createDTO);
// 扣减库存(跨服务)
inventoryService.deductInventory(createDTO.getItems());
// 扣减余额(跨服务)
accountService.deductBalance(createDTO.getUserId(), order.getFinalAmount());
return order;
}
}
```
## 监控与可观测性
```yaml
# prometheus.yml - 监控配置
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
rule_files:
- "alert-rules.yml"
scrape_configs:
- job_name: 'spring-boot-apps'
metrics_path: '/actuator/prometheus'
static_configs:
- targets:
- 'user-service:8080'
- 'order-service:8080'
- 'product-service:8080'
- 'inventory-service:8080'
- 'payment-service:8080'
relabel_configs:
- source_labels: [__address__]
target_label: instance
- source_labels: [__meta_docker_container_name]
target_label: container
- job_name: 'eureka'
static_configs:
- targets: ['discovery-service:8761']
- job_name: 'zipkin'
static_configs:
- targets: ['zipkin:9411']
# grafana-dashboard.json
{
"title": "微服务监控仪表板",
"panels": [
{
"title": "服务请求量",
"targets": [
{
"expr": "sum(rate(http_server_requests_seconds_count[5m])) by (application)",
"legendFormat": "{{application}}"
}
],
"type": "graph"
},
{
"title": "服务响应时间P95",
"targets": [
{
"expr": "histogram_quantile(0.95, sum(rate(http_server_requests_seconds_bucket[5m])) by (le, application))",
"legendFormat": "{{application}}"
}
],
"type": "graph"
},
{
"title": "熔断器状态",
"targets": [
{
"expr": "resilience4j_circuitbreaker_state{state=\"OPEN\"}",
"legendFormat": "{{name}}"
}
],
"type": "stat"
},
{
"title": "数据库连接池",
"targets": [
{
"expr": "hikaricp_connections_active{pool=\"userService\"}",
"legendFormat": "活跃连接"
},
{
"expr": "hikaricp_connections_idle{pool=\"userService\"}",
"legendFormat": "空闲连接"
}
],
"type": "gauge"
}
]
}
// HealthIndicator.java - 健康检查
@Component
public class ServiceHealthIndicator implements HealthIndicator {
private final UserRepository userRepository;
private final RedisConnectionFactory redisConnectionFactory;
private final RestTemplate restTemplate;
@Override
public Health health() {
Health.Builder builder = Health.up();
// 检查数据库连接
try {
long userCount = userRepository.count();
builder.withDetail("database.users.count", userCount);
} catch (Exception e) {
builder.down()
.withDetail("database.error", e.getMessage());
}
// 检查Redis连接
try {
RedisConnection connection = redisConnectionFactory.getConnection();
String pong = connection.ping();
builder.withDetail("redis.status", "UP")
.withDetail("redis.response", pong);
connection.close();
} catch (Exception e) {
builder.down()
.withDetail("redis.error", e.getMessage());
}
// 检查依赖服务
checkDependencyServices(builder);
return builder.build();
}
private void checkDependencyServices(Health.Builder builder) {
Map
"order-service", "http://order-service:8080/actuator/health",
"inventory-service", "http://inventory-service:8080/actuator/health"
);
services.forEach((serviceName, url) -> {
try {
ResponseEntity
if (response.getStatusCode().is2xxSuccessful()) {
builder.withDetail(serviceName + ".status", "UP");
} else {
builder.withDetail(serviceName + ".status", "DOWN");
}
} catch (Exception e) {
builder.withDetail(serviceName + ".status", "DOWN")
.withDetail(serviceName + ".error", e.getMessage());
}
});
}
}
```
基于Spring Boot 3的微服务架构为企业级分布式系统提供了现代化解决方案。通过服务注册与发现、配置中心、熔断器、分布式事务等核心组件,构建了高可用、可扩展的微服务生态系统。在实际部署中,需要结合容器化技术、服务网格和可观测性工具,形成完整的DevOps流水线,确保系统的稳定运行和高效运维。随着业务规模的增长,还需要持续优化架构设计,平衡微服务的粒度与治理复杂度。