Java 微服务架构实战学习文档
第一章 微服务架构基础
1.1 架构演进历程
单体架构 → 垂直拆分 → SOA → 微服务 → 云原生 → 服务网格
| 架构阶段 | 特点 | 适用场景 |
|---|---|---|
| 单体架构 | 统一部署、简单开发、难以扩展 | 小型项目、初创团队 |
| SOA | 服务总线、重量级 ESB | 企业级系统集成 |
| 微服务 | 独立部署、轻量通信、去中心化 | 中大型互联网应用 |
| 云原生 | 容器化、DevOps、持续交付 | 弹性伸缩、高可用场景 |
| 服务网格 | Sidecar 代理、流量治理 | 大规模微服务集群 |
1.2 微服务核心特征
九大核心特征:
- 服务组件化:每个服务独立开发、测试、部署
- 按业务能力组织团队:康威定律,团队对齐服务边界
- 去中心化治理:技术栈异构、数据独立
- 去中心化数据管理:每个服务独立数据库
- 基础设施自动化:CI/CD、自动化测试
- 容错设计:熔断、降级、限流
- 演进式设计:逐步拆分,持续优化
- 轻量级通信:HTTP/REST 或 gRPC
- 服务发现与注册:动态服务寻址
1.3 服务拆分原则
DDD 领域驱动设计拆分法
// 示例:电商系统领域划分
├── 用户域 (User Domain)
│ ├── 用户服务 (user-service)
│ └── 权限服务 (auth-service)
├── 商品域 (Product Domain)
│ ├── 商品服务 (product-service)
│ └── 类目服务 (category-service)
├── 交易域 (Trade Domain)
│ ├── 订单服务 (order-service)
│ ├── 库存服务 (inventory-service)
│ └── 支付服务 (payment-service)
└── 营销域 (Marketing Domain)
├── 优惠券服务 (coupon-service)
└── 秒杀服务 (seckill-service)
拆分原则 checklist
- 单一职责原则:一个服务只负责一个业务功能
- 高内聚低耦合:服务内部紧密相关,服务间依赖最小化
- 独立部署:每个服务可独立打包、发布、回滚
- 独立扩展:根据负载单独扩容特定服务
- 独立数据:每个服务拥有独立的数据存储
1.4 常见设计模式
| 模式名称 | 解决的问题 | 典型实现 |
|---|---|---|
| API 网关模式 | 统一入口、认证鉴权 | Spring Cloud Gateway |
| 服务发现模式 | 动态服务寻址 | Nacos、Consul |
| 断路器模式 | 防止级联故障 | Sentinel、Resilience4j |
| 配置中心模式 | 集中配置管理 | Nacos Config |
| 事件溯源模式 | 审计追踪、状态重建 | Kafka + Event Store |
| Saga 模式 | 分布式事务 | Seata Saga |
| CQRS 模式 | 读写分离 | 命令端/查询端分离 |
| BFF 模式 | 适配不同客户端 | Backend for Frontend |
第二章 Spring Cloud Alibaba 核心组件
2.1 技术栈全景图
┌─────────────────────────────────────────────────────────────┐
│ 接入层 │
│ Spring Cloud Gateway (API 网关) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 服务治理层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Nacos │ │ Sentinel │ │ Seata │ │
│ │ 注册/配置 │ │ 熔断限流 │ │ 分布式事务 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 服务通信层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ OpenFeign │ │ Dubbo │ │ RocketMQ │ │
│ │ HTTP 调用 │ │ RPC 调用 │ │ 异步消息 │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 数据层 │
│ MySQL │ Redis │ Elasticsearch │ MongoDB │ ShardingSphere │
└─────────────────────────────────────────────────────────────┘
2.2 版本兼容性矩阵(2025 最新)
| 组件 | 推荐版本 | Spring Boot 兼容 | JDK 要求 |
|---|---|---|---|
| Spring Cloud Alibaba | 2025.0.0 | 3.4.0+ | 17+ |
| Spring Cloud | 2025.0.0 | 3.4.0+ | 17+ |
| Nacos | 3.0+ | - | 8+ |
| Sentinel | 1.8.8+ | - | 8+ |
| Seata | 2.2+ | - | 8+ |
| RocketMQ | 5.3+ | - | 8+ |
重要提示:Spring Cloud 2025.0.0 与 Spring Boot 4.0.1+ 存在兼容性问题,请使用 Spring Cloud 2025.1.x 版本
2.3 快速开始:项目脚手架
Maven 父工程配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>microservice-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Microservice Parent</name>
<description>微服务父工程</description>
<properties>
<java.version>17</java.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- Spring 生态版本 -->
<spring-boot.version>3.4.0</spring-boot.version>
<spring-cloud.version>2025.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2025.0.0</spring-cloud-alibaba.version>
<!-- 工具版本 -->
<lombok.version>1.18.30</lombok.version>
<mapstruct.version>1.5.5.Final</mapstruct.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud BOM -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud Alibaba BOM -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
第三章 服务治理与通信
3.1 Nacos 3.0:注册与配置中心
3.1.1 核心架构升级
| 特性 | Nacos 2.x | Nacos 3.0 |
|---|---|---|
| 通信协议 | HTTP + gRPC | 纯 gRPC(性能提升 3-5 倍) |
| 一致性协议 | Raft / Distro | DistroConsistency(去中心化) |
| 注册机制 | 客户端主动推送 | 服务端轮询 + 异步注册 |
| 健康检查 | 固定心跳 | 智能动态心跳(指数退避) |
| 元数据 | JSON 传输 | Protobuf(体积减少 60%) |
| 灰度发布 | 基础权重 | 基于标签的动态路由 |
3.1.2 服务注册实战
依赖引入:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置文件:
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: ${NACOS_SERVER:localhost:8848}
namespace: ${NACOS_NAMESPACE:prod}
group: ${NACOS_GROUP:DEFAULT_GROUP}
metadata:
version: 1.0.0
region: beijing
# 3.0 新增:智能心跳配置
heart-beat-interval: 3000
heart-beat-timeout: 9000
# 3.0 新增:异步注册
async-register-enabled: true
启动类:
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
3.1.3 配置中心实战
动态配置监听:
@Component
@Data
@ConfigurationProperties(prefix = "user")
@NacosConfigurationProperties(dataId = "user-service.yaml", autoRefreshed = true)
public class UserProperties {
private Integer maxLoginRetry;
private Long tokenExpireTime;
private List<String> whitelistIps;
}
// 监听配置变更
@Component
public class ConfigChangeListener {
@NacosConfigListener(dataId = "user-service.yaml")
public void onMessage(String config) {
log.info("配置已更新: {}", config);
// 刷新本地缓存、重置限流阈值等
}
}
配置分层管理:
nacos-config/
├── shared-config/ # 共享配置
│ ├── common-log.yaml # 日志配置
│ ├── common-redis.yaml # Redis 配置
│ └── common-db.yaml # 数据库配置
├── service-config/ # 服务专属配置
│ ├── user-service.yaml
│ ├── order-service.yaml
│ └── pay-service.yaml
└── env-config/ # 环境配置
├── application-dev.yaml
├── application-test.yaml
└── application-prod.yaml
3.2 Spring Cloud Gateway 4.3
3.2.1 2025 版本重大变更
| 旧模块名 | 新模块名 | 说明 |
|---|---|---|
spring-cloud-gateway-server | spring-cloud-gateway-server-webflux | WebFlux 网关 |
spring-cloud-gateway-server-mvc | spring-cloud-gateway-server-webmvc | WebMVC 网关 |
spring-cloud-starter-gateway-server | spring-cloud-starter-gateway-server-webflux | WebFlux 启动器 |
3.2.2 网关核心配置
spring:
cloud:
gateway:
# 全局跨域配置
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods: "*"
allowedHeaders: "*"
# 路由配置
routes:
# 用户服务路由
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/user/**
- Method=GET,POST
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
key-resolver: "#{@ipKeyResolver}"
- name: CircuitBreaker
args:
name: userServiceCircuitBreaker
fallbackUri: forward:/fallback/user
# 订单服务路由
- id: order-service-route
uri: lb://order-service
predicates:
- Path=/api/order/**
filters:
- StripPrefix=1
- AddRequestHeader=X-Request-From, Gateway
# 2025 新增:Bucket4j 限流器
bucket4j:
enabled: true
filters:
- cache-name: buckets
url: /api/.*
rate-limits:
- bandwidths:
- capacity: 1000
time: 1
unit: minutes
# 安全代理配置(2025 新增)
server:
webflux:
trusted-proxies: "10\\.0\\.0\\..*|192\\.168\\..*"
3.2.3 自定义过滤器
/**
* 认证过滤器 - 统一鉴权
*/
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Autowired
private JwtTokenProvider tokenProvider;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
// 白名单放行
if (isWhiteList(path)) {
return chain.filter(exchange);
}
// 验证 Token
String token = extractToken(request);
if (!tokenProvider.validateToken(token)) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
String body = "{\"code\":401,\"message\":\"Unauthorized\"}";
DataBuffer buffer = response.bufferFactory().wrap(body.getBytes());
return response.writeWith(Mono.just(buffer));
}
// 透传用户信息到下游服务
ServerHttpRequest mutatedRequest = request.mutate()
.header("X-User-Id", tokenProvider.getUserId(token))
.header("X-User-Role", tokenProvider.getUserRole(token))
.build();
return chain.filter(exchange.mutate().request(mutatedRequest).build());
}
@Override
public int getOrder() {
return -100; // 最高优先级
}
}
3.3 服务间通信
3.3.1 OpenFeign 声明式调用
// 1. 定义 Feign 客户端
@FeignClient(
name = "order-service",
fallbackFactory = OrderClientFallbackFactory.class,
configuration = FeignConfig.class
)
public interface OrderClient {
@GetMapping("/orders/{userId}")
Result<List<OrderDTO>> getUserOrders(@PathVariable("userId") Long userId);
@PostMapping("/orders")
Result<Long> createOrder(@RequestBody OrderCreateRequest request);
// 批量查询,减少网络往返
@PostMapping("/orders/batch")
Result<Map<Long, List<OrderDTO>>> batchGetOrders(@RequestBody List<Long> userIds);
}
// 2. 降级工厂
@Component
@Slf4j
public class OrderClientFallbackFactory implements FallbackFactory<OrderClient> {
@Override
public OrderClient create(Throwable cause) {
log.error("订单服务调用失败", cause);
return new OrderClient() {
@Override
public Result<List<OrderDTO>> getUserOrders(Long userId) {
return Result.fail("订单服务暂不可用,请稍后重试");
}
@Override
public Result<Long> createOrder(OrderCreateRequest request) {
// 记录失败日志,后续补偿处理
return Result.fail("订单创建失败,请稍后重试");
}
@Override
public Result<Map<Long, List<OrderDTO>>> batchGetOrders(List<Long> userIds) {
return Result.success(Collections.emptyMap());
}
};
}
}
// 3. 配置类
public class FeignConfig {
@Bean
public Request.Options feignOptions() {
// 连接超时 5s,读取超时 30s
return new Request.Options(5, TimeUnit.SECONDS, 30, TimeUnit.SECONDS, true);
}
@Bean
public Retryer feignRetryer() {
// 初始间隔 100ms,最大间隔 1s,最多重试 3 次
return new Retryer.Default(100, TimeUnit.MILLISECONDS, 3);
}
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL; // 开发环境使用,生产建议 BASIC
}
}
3.3.2 Dubbo RPC 高性能调用
# Dubbo 配置
dubbo:
application:
name: ${spring.application.name}
qos-enable: false
protocol:
name: tri # Triple 协议,兼容 gRPC
port: -1 # 随机端口
registry:
address: nacos://${spring.cloud.nacos.discovery.server-addr}
group: DUBBO_GROUP
consumer:
check: false
timeout: 3000
retries: 2
loadbalance: roundrobin
// 服务提供者
@DubboService(version = "1.0.0", group = "prod", timeout = 3000)
public class UserServiceImpl implements UserService {
@Override
public UserDTO getById(Long id) {
// 业务逻辑
return userMapper.selectById(id);
}
}
// 服务消费者
@Service
public class OrderService {
@DubboReference(version = "1.0.0", group = "prod", check = false)
private UserService userService;
public OrderDTO createOrder(Long userId) {
UserDTO user = userService.getById(userId);
// 创建订单逻辑
}
}
第四章 流量控制与容错
4.1 Sentinel 1.8 流量治理
4.1.1 核心概念
| 概念 | 说明 | 典型场景 |
|---|---|---|
| 资源 | 被保护的方法或接口 | Controller 方法、Service 方法 |
| 规则 | 限流、降级、系统保护策略 | QPS 限制、响应时间阈值 |
| 流量控制 | 限制并发访问数或 QPS | 秒杀活动限流 |
| 熔断降级 | 失败率达到阈值时快速失败 | 下游服务故障时保护系统 |
| 系统保护 | 基于系统负载自适应保护 | CPU 过高时自动限流 |
| 热点参数 | 针对特定参数值限流 | 针对特定用户 ID 限流 |
4.1.2 流控规则配置
@Configuration
public class SentinelConfig {
@PostConstruct
public void initRules() {
List<FlowRule> rules = new ArrayList<>();
// 规则1:用户接口 QPS 限流
FlowRule userRule = new FlowRule();
userRule.setResource("GET:/api/user/{id}");
userRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
userRule.setCount(1000); // 每秒 1000 请求
userRule.setStrategy(RuleConstant.STRATEGY_DIRECT);
userRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
userRule.setWarmUpPeriodSec(10); // 预热 10 秒
rules.add(userRule);
// 规则2:订单创建并发线程数限流
FlowRule orderRule = new FlowRule();
orderRule.setResource("POST:/api/orders");
orderRule.setGrade(RuleConstant.FLOW_GRADE_THREAD);
orderRule.setCount(50); // 最多 50 并发线程
rules.add(orderRule);
// 规则3:热点参数限流(针对用户 ID)
ParamFlowRule hotRule = new ParamFlowRule();
hotRule.setResource("getUserOrders");
hotRule.setParamIdx(0); // 第 0 个参数
hotRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
hotRule.setCount(100);
// 特定用户 ID 单独限制
hotRule.setParamFlowItemList(Arrays.asList(
new ParamFlowItem("10086", 10, String.class), // VIP 用户限制更严
new ParamFlowItem("10010", 5, String.class)
));
ParamFlowRuleManager.loadRules(Collections.singletonList(hotRule));
FlowRuleManager.loadRules(rules);
}
}
4.1.3 熔断降级规则
// 熔断降级配置
@PostConstruct
public void initDegradeRules() {
List<DegradeRule> rules = new ArrayList<>();
// 慢调用比例熔断
DegradeRule slowRule = new DegradeRule();
slowRule.setResource("orderService");
slowRule.setGrade(CircuitBreakerStrategy.SLOW_REQUEST_RATIO.getType());
slowRule.setCount(0.5); // 慢调用比例阈值 50%
slowRule.setSlowRatioThreshold(0.3); // 慢调用比例超过 30%
slowRule.setTimeWindow(10); // 熔断时长 10s
slowRule.setMinRequestAmount(5); // 最小请求数
slowRule.setStatIntervalMs(1000); // 统计时长 1s
slowRule.setSlowRequestThreshold(500); // 响应时间超过 500ms 算慢调用
rules.add(slowRule);
// 异常比例熔断
DegradeRule errorRule = new DegradeRule();
errorRule.setResource("paymentService");
errorRule.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType());
errorRule.setCount(0.5); // 异常比例超过 50%
errorRule.setTimeWindow(30); // 熔断 30s
rules.add(errorRule);
DegradeRuleManager.loadRules(rules);
}
4.1.4 注解方式定义资源
@Service
public class OrderService {
/**
* 热点参数限流:value 是资源名,blockHandler 是限流处理方法
*/
@SentinelResource(
value = "createOrder",
blockHandler = "handleBlock",
fallback = "handleFallback"
)
public OrderDTO createOrder(Long userId, OrderCreateRequest request) {
// 业务逻辑
return orderMapper.insert(request);
}
// 限流处理(必须与原方法参数+BlockException 相同)
public OrderDTO handleBlock(Long userId, OrderCreateRequest request, BlockException ex) {
log.warn("创建订单被限流: userId={}", userId);
throw new BizException("系统繁忙,请稍后重试");
}
// 降级处理(异常时触发)
public OrderDTO handleFallback(Long userId, OrderCreateRequest request, Throwable ex) {
log.error("创建订单失败,进入降级: userId={}", userId, ex);
// 记录失败订单,后续补偿
saveFailedOrder(userId, request);
return null;
}
}
4.2 网关层统一限流
@Component
public class GatewaySentinelConfig {
@PostConstruct
public void doInit() {
// 网关流控规则
GatewayFlowRule rule = new GatewayFlowRule("user-service-route");
rule.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_ROUTE_ID);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(5000); // 路由级别限流
rule.setIntervalSec(1);
// 参数限流:针对特定用户
GatewayParamFlowItem paramItem = new GatewayParamFlowItem();
paramItem.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER);
paramItem.setFieldName("X-User-Id");
rule.setParamItem(paramItem);
GatewayRuleManager.loadRules(Collections.singletonList(rule));
}
}
第五章 分布式数据一致性
5.1 Seata 2.2 分布式事务
5.1.1 架构组件
┌─────────────────────────────────────────────────────────────┐
│ TC (Transaction Coordinator) │
│ 事务协调器(独立部署) │
│ 维护全局事务状态,协调分支事务提交/回滚 │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────┼─────────────────────┐
↓ ↓ ↓
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ TM │ │ RM │ │ RM │
│ 事务管理器 │ │ 资源管理器 │ │ 资源管理器 │
│ @GlobalTransactional │ │ 订单服务分支 │ │ 库存服务分支 │
└───────────────┘ └───────────────┘ └───────────────┘
5.1.2 四种事务模式对比
| 模式 | 侵入性 | 性能 | 适用场景 | 特点 |
|---|---|---|---|---|
| AT | 低 | 高 | 简单 CRUD | 自动补偿,无业务改造 |
| TCC | 高 | 高 | 复杂业务 | 手动实现 Try/Confirm/Cancel |
| SAGA | 中 | 高 | 长事务流程 | 状态机引擎,向前/向后恢复 |
| XA | 低 | 低 | 强一致性场景 | 两阶段提交,资源锁定长 |
5.1.3 AT 模式实战
# Seata 客户端配置
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: my_tx_group
service:
vgroup-mapping:
my_tx_group: default
registry:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
group: SEATA_GROUP
namespace: ${spring.cloud.nacos.discovery.namespace}
client:
rm:
async-commit-buffer-limit: 10000
tm:
default-global-transaction-timeout: 60000
data-source-proxy-mode: AT
@Service
@Slf4j
public class OrderBizService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private InventoryClient inventoryClient;
@Autowired
private AccountClient accountClient;
/**
* 创建订单(全局事务)
* 1. 创建订单(本地事务)
* 2. 扣减库存(RPC 调用)
* 3. 扣减账户余额(RPC 调用)
*/
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public OrderDTO createOrder(OrderCreateRequest request) {
log.info("全局事务开始,XID: {}", RootContext.getXID());
// 1. 创建订单
Order order = new Order();
order.setUserId(request.getUserId());
order.setProductId(request.getProductId());
order.setCount(request.getCount());
order.setMoney(request.getCount() * request.getPrice());
order.setStatus(OrderStatus.CREATING);
orderMapper.insert(order);
// 2. 扣减库存(远程调用)
Result<Void> inventoryResult = inventoryClient.decrease(
request.getProductId(),
request.getCount()
);
if (!inventoryResult.isSuccess()) {
throw new BizException("库存不足");
}
// 3. 扣减余额(远程调用)
Result<Void> accountResult = accountClient.debit(
request.getUserId(),
order.getMoney()
);
if (!accountResult.isSuccess()) {
throw new BizException("余额不足");
}
// 更新订单状态
order.setStatus(OrderStatus.SUCCESS);
orderMapper.updateById(order);
log.info("全局事务提交成功");
return convertToDTO(order);
}
}
5.1.4 TCC 模式实战(复杂业务场景)
/**
* TCC 模式:库存服务
*/
@LocalTCC
public interface InventoryTccService {
/**
* Try 阶段:预留库存
*/
@TwoPhaseBusinessAction(
name = "inventoryTccAction",
commitMethod = "commit",
rollbackMethod = "rollback",
useTCCFence = true // 防悬挂
)
boolean tryDecrease(@BusinessActionContextParameter(paramName = "productId") Long productId,
@BusinessActionContextParameter(paramName = "count") Integer count);
/**
* Confirm 阶段:确认扣减(实际扣减预留库存)
*/
boolean commit(BusinessActionContext context);
/**
* Cancel 阶段:取消预留(释放预留库存)
*/
boolean rollback(BusinessActionContext context);
}
@Service
@Slf4j
public class InventoryTccServiceImpl implements InventoryTccService {
@Autowired
private InventoryMapper inventoryMapper;
@Autowired
private InventoryFenceMapper fenceMapper;
@Override
public boolean tryDecrease(Long productId, Integer count) {
// 1. 检查库存是否充足
Inventory inventory = inventoryMapper.selectById(productId);
if (inventory.getAvailable() < count) {
return false;
}
// 2. 扣减可用库存,增加预留库存
int affected = inventoryMapper.decreaseAvailable(productId, count);
if (affected == 0) {
return false; // 库存不足或并发冲突
}
inventoryMapper.increaseReserved(productId, count);
log.info("Try 阶段:预留库存成功,productId={}, count={}", productId, count);
return true;
}
@Override
public boolean commit(BusinessActionContext context) {
Long productId = Long.parseLong(context.getActionContext("productId").toString());
Integer count = Integer.parseInt(context.getActionContext("count").toString());
// 将预留库存转为实际扣减
inventoryMapper.decreaseReserved(productId, count);
inventoryMapper.increaseSold(productId, count);
log.info("Confirm 阶段:确认扣减成功,productId={}, count={}", productId, count);
return true;
}
@Override
public boolean rollback(BusinessActionContext context) {
Long productId = Long.parseLong(context.getActionContext("productId").toString());
Integer count = Integer.parseInt(context.getActionContext("count").toString());
// 释放预留库存
inventoryMapper.increaseAvailable(productId, count);
inventoryMapper.decreaseReserved(productId, count);
log.info("Cancel 阶段:释放预留成功,productId={}, count={}", productId, count);
return true;
}
}
5.2 最终一致性方案:消息队列
/**
* 可靠消息最终一致性方案
*/
@Service
public class ReliableMessageService {
@Autowired
private RocketMQTemplate rocketMQTemplate;
@Autowired
private TransactionRecordMapper transactionRecordMapper;
/**
* 发送半消息(事务消息)
*/
public void sendHalfMessage(Order order) {
Message<Order> message = MessageBuilder
.withPayload(order)
.setHeader("KEYS", order.getId().toString())
.setHeader("TRANSACTION_ID", generateTxId())
.build();
// 发送事务消息
TransactionSendResult result = rocketMQTemplate.sendMessageInTransaction(
"order-topic",
message,
order // 本地事务参数
);
if (!result.getLocalTransactionState().equals(LocalTransactionState.COMMIT_MESSAGE)) {
throw new BizException("事务消息发送失败");
}
}
/**
* 本地事务执行
*/
@RocketMQTransactionListener
class OrderTxListener implements RocketMQLocalTransactionListener {
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
try {
Order order = (Order) arg;
// 执行本地事务:创建订单
orderService.createOrderLocal(order);
return RocketMQLocalTransactionState.COMMIT_MESSAGE;
} catch (Exception e) {
return RocketMQLocalTransactionState.ROLLBACK_MESSAGE;
}
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
// 回查本地事务状态
String orderId = msg.getHeaders().get("KEYS", String.class);
Order order = orderMapper.selectById(orderId);
if (order != null) {
return RocketMQLocalTransactionState.COMMIT_MESSAGE;
}
return RocketMQLocalTransactionState.ROLLBACK_MESSAGE;
}
}
}
第六章 可观测性与监控
6.1 链路追踪:SkyWalking
# SkyWalking Agent 配置
skywalking:
agent:
service_name: ${spring.application.name}
collector:
backend_service: ${SW_OAP_SERVER:localhost:11800}
plugin:
toolkit:
log:
transmit_formatted: true
spring-cloud-gateway:
enabled: true
/**
* 自定义链路标签
*/
@Service
public class OrderService {
@Trace(operationName = "createOrder")
@Tags({
@Tag(key = "userId", value = "arg[0]"),
@Tag(key = "orderId", value = "returned.orderId")
})
public Order createOrder(Long userId, OrderRequest request) {
// 业务逻辑
ActiveSpan.tag("productId", request.getProductId().toString());
ActiveSpan.info("开始创建订单");
// 关键步骤埋点
try (TraceScope scope = TracerManager.tracing("validateInventory")) {
validateInventory(request);
}
return order;
}
}
6.2 指标监控:Micrometer + Prometheus
@Configuration
public class MetricsConfig {
@Bean
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config()
.commonTags("application", "order-service")
.commonTags("region", "beijing");
}
/**
* 自定义业务指标
*/
@Component
public class OrderMetrics {
private final Counter createCounter;
private final Counter failCounter;
private final Timer processTimer;
private final DistributionSummary amountSummary;
public OrderMetrics(MeterRegistry registry) {
this.createCounter = Counter.builder("orders.created")
.description("订单创建总数")
.register(registry);
this.failCounter = Counter.builder("orders.failed")
.description("订单创建失败数")
.tag("reason", "inventory")
.register(registry);
this.processTimer = Timer.builder("orders.process.time")
.description("订单处理耗时")
.publishPercentiles(0.5, 0.95, 0.99)
.register(registry);
this.amountSummary = DistributionSummary.builder("orders.amount")
.description("订单金额分布")
.baseUnit("yuan")
.publishPercentiles(0.5, 0.9, 0.99)
.register(registry);
}
public void recordOrderCreated(BigDecimal amount) {
createCounter.increment();
amountSummary.record(amount.doubleValue());
}
public void recordProcessTime(Runnable operation) {
processTimer.record(operation);
}
}
}
6.3 日志聚合:ELK + 结构化日志
<!-- logback-spring.xml -->
<configuration>
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}] %logger{36} - %msg%n"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>true</includeContext>
<includeMdc>true</includeMdc>
<customFields>{"service":"${spring.application.name}"}</customFields>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/app/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/var/log/app/application.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxHistory>30</maxHistory>
<maxFileSize>100MB</maxFileSize>
</rollingPolicy>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
第七章 生产环境实践
7.1 容器化部署
Dockerfile 最佳实践
# 多阶段构建,减小镜像体积
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
# 先复制依赖配置,利用缓存层
COPY pom.xml mvnw ./
COPY .mvn .mvn
RUN ./mvnw dependency:go-offline -B
# 复制源码并构建
COPY src src
RUN ./mvnw clean package -DskipTests -B
# 运行阶段使用 JRE 而非 JDK
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# 安全:使用非 root 用户
RUN addgroup -g 1001 -S appgroup && \
adduser -u 1001 -S appuser -G appgroup
USER appuser
# 从构建阶段复制 JAR
COPY --from=builder /app/target/*.jar app.jar
# JVM 参数优化
ENV JAVA_OPTS="-XX:+UseG1GC \
-XX:MaxRAMPercentage=75.0 \
-XX:InitialRAMPercentage=50.0 \
-XX:+UseContainerSupport \
-Djava.security.egd=file:/dev/./urandom"
EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
Kubernetes 部署配置
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
labels:
app: order-service
version: v1.0.0
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 0
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/actuator/prometheus"
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- order-service
topologyKey: kubernetes.io/hostname
containers:
- name: order-service
image: registry.company.com/order-service:1.0.0
ports:
- containerPort: 8080
name: http
- containerPort: 9090
name: grpc
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: NACOS_SERVER
valueFrom:
configMapKeyRef:
name: common-config
key: nacos.server
- name: JVM_OPTS
value: "-XX:+UseG1GC -XX:MaxRAMPercentage=75.0"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "2Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 15"] # 优雅停机等待
---
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service
ports:
- port: 80
targetPort: 8080
name: http
- port: 9090
targetPort: 9090
name: grpc
type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-service-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 15
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
7.2 CI/CD 流水线
// Jenkinsfile
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'registry.company.com'
SERVICE_NAME = 'order-service'
}
stages {
stage('Build & Test') {
steps {
sh './mvnw clean verify -DskipITs=false'
}
post {
always {
junit 'target/surefire-reports/*.xml'
jacoco execPattern: 'target/jacoco.exec'
}
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('SonarQube') {
sh './mvnw sonar:sonar'
}
}
}
stage('Build Docker Image') {
steps {
script {
def image = docker.build("${DOCKER_REGISTRY}/${SERVICE_NAME}:${BUILD_NUMBER}")
image.push()
image.push('latest')
}
}
}
stage('Deploy to Dev') {
steps {
sh """
kubectl set image deployment/${SERVICE_NAME} \
${SERVICE_NAME}=${DOCKER_REGISTRY}/${SERVICE_NAME}:${BUILD_NUMBER} \
-n dev
kubectl rollout status deployment/${SERVICE_NAME} -n dev --timeout=300s
"""
}
}
stage('Integration Test') {
steps {
sh './mvnw verify -P integration-test -Denv=dev'
}
}
stage('Deploy to Production') {
when {
branch 'main'
}
steps {
input message: 'Deploy to Production?', ok: 'Deploy'
sh """
kubectl set image deployment/${SERVICE_NAME} \
${SERVICE_NAME}=${DOCKER_REGISTRY}/${SERVICE_NAME}:${BUILD_NUMBER} \
-n prod
kubectl rollout status deployment/${SERVICE_NAME} -n prod --timeout=600s
"""
}
}
}
post {
failure {
slackSend(color: 'danger', message: "Build Failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}")
}
success {
slackSend(color: 'good', message: "Build Success: ${env.JOB_NAME} #${env.BUILD_NUMBER}")
}
}
}
7.3 灰度发布方案
/**
* 基于 Nacos 元数据的灰度发布
*/
@Component
public class GrayReleaseFilter implements GlobalFilter, Ordered {
@Autowired
private NacosDiscoveryProperties nacosProperties;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// 从 Header 获取灰度标识
String grayTag = request.getHeaders().getFirst("X-Gray-Tag");
String userId = request.getHeaders().getFirst("X-User-Id");
// 根据规则判断是否需要灰度
boolean isGray = checkGrayRule(grayTag, userId);
// 设置元数据,影响负载均衡
if (isGray) {
ServerHttpRequest mutatedRequest = request.mutate()
.header("nacos.service.metadata.version", "v2.0.0-gray")
.build();
return chain.filter(exchange.mutate().request(mutatedRequest).build());
}
return chain.filter(exchange);
}
private boolean checkGrayRule(String grayTag, String userId) {
// 1. 特定标签强制灰度
if ("gray".equals(grayTag)) {
return true;
}
// 2. 用户 ID 取模灰度(5% 流量)
if (userId != null) {
long userIdHash = Math.abs(userId.hashCode());
return userIdHash % 100 < 5;
}
return false;
}
@Override
public int getOrder() {
return -50;
}
}
第八章 性能优化与调优
8.1 JVM 调优指南
| 场景 | 推荐配置 | 说明 |
|---|---|---|
| 通用 Web 应用 | -XX:+UseG1GC -XX:MaxRAMPercentage=75.0 | G1 收集器,自适应内存 |
| 低延迟要求 | -XX:+UseZGC -XX:+ZGenerational | ZGC,停顿时间 < 10ms |
| 大内存堆(>16G) | -XX:+UseShenandoahGC | Shenandoah,低延迟 |
| 容器环境 | -XX:+UseContainerSupport | 识别容器内存限制 |
# 生产环境推荐 JVM 参数
JAVA_OPTS="
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=16m
-XX:InitiatingHeapOccupancyPercent=45
-XX:MaxRAMPercentage=75.0
-XX:InitialRAMPercentage=50.0
-XX:+UseContainerSupport
-XX:+UseStringDeduplication
-XX:+OptimizeStringConcat
-Djava.security.egd=file:/dev/./urandom
-Dspring.backgroundpreinitializer.ignore=true
"
8.2 数据库优化
/**
* 连接池配置(HikariCP)
*/
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.hikari")
public HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
// 核心配置
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
// 性能优化
config.setAutoCommit(false);
config.setCachePrepStmts(true);
config.setPrepStmtCacheSize(250);
config.setPrepStmtCacheSqlLimit(2048);
config.setUseServerPrepStmts(true);
config.setUseLocalSessionState(true);
config.setRewriteBatchedStatements(true);
config.setCacheResultSetMetadata(true);
config.setCacheServerConfiguration(true);
config.setElideSetAutoCommits(true);
config.setMaintainTimeStats(false);
return config;
}
}
8.3 缓存策略
/**
* 多级缓存架构:Caffeine(本地)+ Redis(远程)
*/
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// Redis 缓存配置
RedisCacheConfiguration redisConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
// Caffeine 本地缓存配置
CaffeineCacheManager caffeineManager = new CaffeineCacheManager();
caffeineManager.setCaffeine(Caffeine.newBuilder()
.maximumSize(10000)
.expireAfterWrite(Duration.ofMinutes(5))
.recordStats());
// 组合缓存管理器
CompositeCacheManager compositeManager = new CompositeCacheManager();
compositeManager.setCacheManagers(Arrays.asList(caffeineManager,
new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(factory), redisConfig)));
compositeManager.setFallbackToNoOpCache(false);
return compositeManager;
}
}
@Service
public class ProductService {
@Cacheable(value = "product", key = "#id", cacheManager = "cacheManager")
public ProductDTO getById(Long id) {
return productMapper.selectById(id);
}
@CacheEvict(value = "product", key = "#product.id")
public void update(Product product) {
productMapper.updateById(product);
}
}
第九章 面试与常见问题
9.1 高频面试题
Q1: Nacos 的 CP 和 AP 模式有什么区别?如何选择?
答案:
- AP 模式(默认):使用 Distro 协议,优先保证可用性,注册中心宕机不影响已注册服务间调用。适用于大多数互联网场景
- CP 模式:使用 Raft 协议,保证强一致性,但牺牲一定可用性。适用于对数据一致性要求极高的金融场景
- 选择建议:默认使用 AP 模式,除非有强一致性要求
Q2: Sentinel 与 Hystrix 的熔断策略有何差异?
表格
| 特性 | Sentinel | Hystrix |
|---|---|---|
| 熔断策略 | 慢调用比例、异常比例、异常数 | 异常比例、异常数 |
| 限流能力 | 丰富(QPS、线程数、热点参数) | 有限 |
| 自适应保护 | 支持(系统负载保护) | 不支持 |
| 实时监控 | 完善 Dashboard | 需要额外集成 |
| 维护状态 | 活跃维护 | 已停止维护 |
Q3: Seata AT 模式的 undo_log 是如何实现的?
答案:
- 一阶段:业务 SQL 执行前,解析 SQL 生成前镜像(查询原数据);执行业务 SQL;生成后镜像(查询新数据);插入 undo_log(包含前后镜像)
- 二阶段提交:异步删除 undo_log
- 二阶段回滚:根据 undo_log 的前镜像生成回滚 SQL,执行回滚
9.2 生产环境问题排查
java
复制
/**
* 健康检查端点扩展
*/
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Autowired
private DataSource dataSource;
@Autowired
private RedisTemplate<String, String> redisTemplate;
@Override
public Health health() {
Map<String, Object> details = new HashMap<>();
// 数据库检查
try (Connection conn = dataSource.getConnection()) {
details.put("database", "UP");
details.put("databaseLatency", checkDbLatency());
} catch (Exception e) {
return Health.down()
.withDetail("database", "DOWN: " + e.getMessage())
.build();
}
// Redis 检查
try {
redisTemplate.opsForValue().get("health:check");
details.put("redis", "UP");
} catch (Exception e) {
return Health.down()
.withDetail("redis", "DOWN: " + e.getMessage())
.build();
}
// Nacos 连接检查
details.put("nacos", checkNacosConnection());
return Health.up()
.withDetails(details)
.build();
}
}
9.3 学习路径建议
plain
复制
第一阶段(2-3 周):基础夯实
├── Spring Boot 3.x 核心原理
├── Spring Cloud Gateway 基础路由
├── Nacos 服务注册与配置管理
└── OpenFeign 声明式调用
第二阶段(3-4 周):微服务进阶
├── Sentinel 流量控制与熔断
├── Seata 分布式事务(AT/TCC 模式)
├── RocketMQ 消息队列实战
└── SkyWalking 链路追踪
第三阶段(2-3 周):生产实践
├── Docker + Kubernetes 容器化部署
├── CI/CD 流水线搭建
├── 性能调优与监控告警
└── 灰度发布与故障演练
附录
A. 推荐版本组合(2025 年)
表格
| 组件 | 版本 | 备注 |
|---|---|---|
| JDK | 17 或 21 | LTS 版本,推荐 21(虚拟线程) |
| Spring Boot | 3.4.0+ | 最低 3.4.0 |
| Spring Cloud | 2025.0.0+ | 或 2025.1.x(兼容 Boot 4.0.1+) |
| Spring Cloud Alibaba | 2025.0.0+ | 适配最新 Spring Cloud |
| Nacos | 3.0+ | 支持 gRPC、智能心跳 |
| Sentinel | 1.8.8+ | 包含最新安全修复 |
| Seata | 2.2+ | 支持控制台、更多存储模式 |
| RocketMQ | 5.3+ | 支持 Proxy 模式 |