Day31 Spring Cloud 2
. OpenFeign 服务调用
4.1 OpenFeign 概述
OpenFeign 是声明式的 Web Service 客户端,它使得编写 Web Service 客户端变得更加简单。使用 Feign 创建接口加上对应的注解,就可以调用远程服务。
Feign 核心特性:
- 声明式调用:通过接口定义远程调用
- 集成 Ribbon:内置负载均衡
- 支持多种注解:Spring MVC、Feign 原生注解
- 可插拔编码器:支持多种序列化方式
- 请求拦截器:统一处理请求头等
4.2 OpenFeign 工作原理
▼mermaid复制代码graph TD A[Controller] --> B[Feign Client] B --> C[动态代理] C --> D[InvocationHandler] D --> E[RequestTemplate] E --> F[Encoder] F --> G[LoadBalancer] G --> H[Service Instance] H --> I[HTTP 调用] I --> J[Decoder] J --> K[返回结果]
Feign 调用流程:
- 接口定义:定义 Feign Client 接口
- 动态代理:JDK 动态代理生成代理对象
- 请求构建:根据注解构建 HTTP 请求
- 负载均衡:选择目标服务实例
- HTTP 调用:发送 HTTP 请求
- 响应解析:解析响应为对象
4.3 依赖配置
▼xml复制代码<dependencies> <!-- OpenFeign --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- LoadBalancer (Spring Cloud 2020+) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> </dependencies>
4.4 Feign Client 定义
▼java复制代码/** * 声明式 Feign 客户端 */ @FeignClient( name = "stock-service", // 服务名称 path = "/stock", // 路径前缀 fallbackFactory = StockFeignFallback.class // 降级工厂 ) public interface StockFeignClient { /** * 扣减库存 */ @PostMapping("/deduct") Result deductStock(@RequestBody StockDeductDTO dto); /** * 查询库存 */ @GetMapping("/query/{productId}") Result<StockVO> queryStock(@PathVariable("productId") Long productId); /** * 批量查询库存 */ @GetMapping("/batch") Result<List<StockVO>> batchQuery(@RequestParam("productIds") List<Long> productIds); }
@FeignClient 参数说明:
| 参数 | 说明 |
|---|---|
| name/value | 服务名称 |
| path | 路径前缀 |
| url | 直接指定 URL(不使用服务发现) |
| decode404 | 是否解码 404 |
| configuration | 自定义配置类 |
| fallback | 降级实现类 |
| fallbackFactory | 降级工厂类 |
4.5 启用 Feign
▼java复制代码@SpringBootApplication @EnableFeignClients // 启用 Feign 客户端 @EnableDiscoveryClient public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
4.6 负载均衡策略
Spring Cloud LoadBalancer 支持的负载均衡策略:
| 策略 | 说明 |
|---|---|
| RoundRobinLoadBalancer | 轮询 |
| RandomLoadBalancer | 随机 |
自定义负载均衡:
▼java复制代码public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer { @Override public Mono<Response<ServiceInstance>> choose(Request request) { // 自定义负载均衡逻辑 return Mono.just(Response.withServiceInstance(serviceInstance)); } }
4.7 请求拦截器
▼java复制代码/** * Feign 请求拦截器 - 添加认证信息 */ @Configuration public class FeignInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 添加认证 Token String token = getToken(); template.header("Authorization", "Bearer " + token); // 添加请求 ID template.header("X-Request-Id", UUID.randomUUID().toString()); // 添加调用链追踪 template.header("X-Trace-Id", MDC.get("traceId")); } private String getToken() { // 从上下文获取 Token return SecurityContextHolder.getContext().getToken(); } }
4.8 服务降级
▼java复制代码/** * Feign 降级工厂 */ @Component public class StockFeignFallback implements FallbackFactory<StockFeignClient> { @Override public StockFeignClient create(Throwable cause) { return new StockFeignClient() { @Override public Result deductStock(StockDeductDTO dto) { log.error("库存服务调用失败: {}", cause.getMessage()); return Result.fail("库存服务暂时不可用"); } @Override public Result<StockVO> queryStock(Long productId) { log.error("库存查询失败: {}", cause.getMessage()); return Result.fail("库存服务暂时不可用"); } @Override public Result<List<StockVO>> batchQuery(List<Long> productIds) { log.error("批量查询库存失败: {}", cause.getMessage()); return Result.fail("库存服务暂时不可用"); } }; } }
4.9 Feign 调用流程
▼mermaid复制代码sequenceDiagram participant C as Controller participant F as Feign Client participant L as LoadBalancer participant S as Stock Service C->>F: 调用 Feign 接口方法 F->>L: 获取服务实例 L-->>F: 返回实例地址 F->>S: 发送 HTTP 请求 S-->>F: 返回响应 F-->>C: 返回结果 alt 调用失败 F->>F: 触发降级逻辑 F-->>C: 返回降级结果 end
5. Sentinel 流量防护
5.1 Sentinel 概述
Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。
Sentinel 核心特性:
| 特性 | 说明 |
|---|---|
| 流量控制 | 限制 QPS、并发线程数 |
| 熔断降级 | 自动降级不稳定的调用 |
| 系统负载保护 | CPU 使用率、平均 RT 保护 |
| 热点限流 | 针对热点参数限流 |
| 实时监控 | 实时监控接口运行情况 |
5.2 Sentinel 架构
▼mermaid复制代码graph TB A[应用服务] --> B[Sentinel Dashboard] A --> C[FlowSlot 流控] A --> D[DegradeSlot 降级] A --> E[AuthoritySlot 授权] A --> F[SystemSlot 系统保护] subgraph 规则管理 G[流控规则] H[熔断降级规则] I[热点参数规则] J[系统规则] end B --> G B --> H B --> I B --> J
5.3 核心概念
| 概念 | 说明 |
|---|---|
| 资源 | Sentinel 要保护的目标,可以是代码中的任意方法 |
| 规则 | 围绕资源的实时状态设定的策略 |
| 检测结果 | 根据规则判断是放行还是拒绝 |
5.4 流控规则
流控模式:
| 模式 | 说明 |
|---|---|
| 直接拒绝 | 超过阈值直接拒绝 |
| 关联 | 关联资源达到阈值时限流 |
| 链路 | 针对从入口资源进入的流量进行统计 |
流控效果:
| 效果 | 说明 |
|---|---|
| 快速失败 | 直接抛出 FlowException |
| Warm Up | 预热,缓慢增加阈值 |
| 排队等待 | 匀速排队,阈值设为排队时间 |
5.5 熔断降级
熔断策略:
| 策略 | 说明 |
|---|---|
| 慢调用比例 | 慢调用比例超过阈值触发熔断 |
| 异常比例 | 异常比例超过阈值触发熔断 |
| 异常数 | 异常数超过阈值触发熔断 |
5.6 Sentinel 熔断机制
▼mermaid复制代码stateDiagram-v2 [*] --> Closed: 正常状态 Closed --> Open: 慢调用/异常比例达到阈值 Open --> HalfOpen: 熔断时长结束,进入探活 HalfOpen --> Closed: 探活成功,恢复闭合 HalfOpen --> Open: 探活失败,重新熔断 note right of Closed 正常通过请求 统计慢调用和异常 end note note right of Open 直接拒绝所有请求 持续 timeWindow 时长 end note note right of HalfOpen 放行部分请求 成功则恢复 失败则继续熔断 end note
熔断状态说明:
| 状态 | 说明 |
|---|---|
| Closed | 正常状态,请求正常通过 |
| Open | 熔断状态,直接拒绝所有请求 |
| HalfOpen | 探活状态,放行部分请求进行试探 |
5.7 配置示例
▼java复制代码@RestController @RequestMapping("/order") public class OrderController { /** * 注解方式定义资源 + 流控 */ @GetMapping("/create") @SentinelResource( value = "createOrder", blockHandler = "createOrderBlockHandler", fallback = "createOrderFallback" ) public Result createOrder(@RequestBody CreateOrderDTO dto) { // 业务逻辑 Order order = orderService.create(dto); return Result.success(order); } /** * 流控处理方法 */ public Result createOrderBlockHandler(CreateOrderDTO dto, BlockException ex) { log.warn("订单创建被限流: {}", ex.getMessage()); return Result.fail("系统繁忙,请稍后重试"); } /** * 降级处理方法 */ public Result createOrderFallback(CreateOrderDTO dto, Throwable ex) { log.error("订单创建失败: {}", ex.getMessage()); return Result.fail("订单创建失败,请稍后重试"); } }
6. Gateway 网关
6.1 Gateway 概述
Spring Cloud Gateway 是 Spring Cloud 官方推出的第二代网关框架,基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 等技术开发,旨在为微服务架构提供一种简单有效的、统一的 API 路由管理方式。
Gateway 核心特性:
| 特性 | 说明 |
|---|---|
| 动态路由 | 根据请求匹配路由 |
| 负载均衡 | 内置负载均衡 |
| 限流 | 支持多种限流策略 |
| 熔断降级 | 集成 Resilience4j |
| 监控 | 集成 Actuator |
| 安全 | 集成 Security |
6.2 Gateway 工作原理
▼mermaid复制代码graph TD A[客户端请求] --> B[Handler Mapping] B --> C[Web Handler] C --> D[Filter Chain 前置处理] D --> E[微服务] E --> F[Filter Chain 后置处理] F --> G[返回客户端] subgraph 过滤器链 D1[全局过滤器] D2[网关过滤器] D3[自定义过滤器] end D --> D1 D1 --> D2 D2 --> D3
6.3 核心概念
| 概念 | 说明 |
|---|---|
| Route | 路由,网关的基本构建块,由 ID、目标 URI、断言和过滤器组成 |
| Predicate | 断言,Java 8 的 Predicate,用于匹配 HTTP 请求 |
| Filter | 过滤器,在请求被发送到下游服务之前或之后修改请求和响应 |
6.4 断言工厂
| 断言 | 说明 |
|---|---|
| After | 在指定时间之后 |
| Before | 在指定时间之前 |
| Between | 在两个时间之间 |
| Cookie | 基于 Cookie 匹配 |
| Header | 基于 Header 匹配 |
| Host | 基于 Host 匹配 |
| Method | 基于 HTTP 方法匹配 |
| Path | 基于路径匹配 |
| Query | 基于查询参数匹配 |
| RemoteAddr | 基于远程地址匹配 |
6.5 配置示例
▼yaml复制代码spring: application: name: gateway-service cloud: nacos: discovery: server-addr: 127.0.0.1:8848 gateway: discovery: locator: enabled:true lower-case-service-id:true routes: # 订单服务路由 -id: order-service uri: lb://order-service predicates: - Path=/api/order/** - Method=POST,GET - Header=X-Request-Id, \d+ filters: - StripPrefix=1 - AddRequestHeader=X-Gateway, gateway-service
6.6 自定义过滤器
▼java复制代码/** * 自定义全局过滤器 */ @Component @Slf4j public class LogFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ServerHttpRequest request = exchange.getRequest(); String path = request.getPath().value(); String method = request.getMethod().name(); log.info("请求: {} {}", method, path); return chain.filter(exchange).then(Mono.fromRunnable(() -> { log.info("响应: {} {}", method, path); })); } @Override public int getOrder() { return -100; } }
7. Seata 分布式事务
7.1 分布式事务场景
▼mermaid复制代码sequenceDiagram participant U as 用户 participant O as 订单服务 participant S as 库存服务 participant P as 支付服务 participant DB1 as 订单库 participant DB2 as 库存库 participant DB3 as 支付库 U->>O: 创建订单 O->>DB1: 创建订单(本地事务) O->>S: 扣减库存 S->>DB2: 扣减库存(本地事务) S-->>O: 扣减成功 O->>P: 扣减余额 P->>DB3: 扣减余额(本地事务) P->>P: 异常!余额不足 P-->>O: 扣减失败 O->>O: 回滚订单 O->>S: 恢复库存 Note over S,DB2: 需要跨库事务回滚!
7.2 Seata 架构
▼mermaid复制代码graph TB TC[Seata TC 事务协调器] --> TM1[TM 事务管理器] TC --> TM2 TC --> TM3 TM1 --> RM1[RM 资源管理器] TM2 --> RM2 TM3 --> RM3 RM1 --> DB1[数据库1] RM2 --> DB2[数据库2] RM3 --> DB3[数据库3] subgraph 订单服务 TM1 RM1 end subgraph 库存服务 TM2 RM2 end subgraph 支付服务 TM3 RM3 end
Seata 核心角色:
| 角色 | 说明 |
|---|---|
| TC | 事务协调器,维护全局事务和分支事务的状态 |
| TM | 事务管理器,定义全局事务的范围 |
| RM | 资源管理器,管理分支事务 |
7.3 Seata 三种模式
| 模式 | 特点 | 适用场景 |
|---|---|---|
| AT | 无侵入,自动回滚 | 大多数业务场景 |
| TCC | 需编写三个接口,强一致性 | 核心业务、资金类 |
| Saga | 长事务、状态机 | 复杂业务流程 |
7.4 AT 模式原理
AT 模式特点:
- 无侵入:业务代码无需修改
- 自动回滚:基于 Undo Log 自动回滚
- 两阶段提交:第一阶段提交本地事务,第二阶段提交或回滚
AT 模式工作流程:
▼mermaid复制代码sequenceDiagram participant TM as TM(事务管理器) participant TC as TC(事务协调器) participant RM1 as RM1(资源管理器) participant RM2 as RM2(资源管理器) participant DB1 as 数据库1 participant DB2 as 数据库2 Note over TM,DB2: 一阶段:提交本地事务 TM->>TC: 开启全局事务 TC-->>TM: 返回 XID TM->>RM1: 分支注册,携带 XID RM1->>DB1: 执行业务SQL RM1->>DB1: 查询前镜像 RM1->>DB1: 执行更新 RM1->>DB1: 查询后镜像 RM1->>RM1: 生成Undo Log RM1->>DB1: 提交本地事务 RM1-->>TM: 提交成功 TM->>RM2: 分支注册 RM2->>DB2: 执行业务SQL RM2->>RM2: 生成Undo Log RM2->>DB2: 提交本地事务 RM2-->>TM: 提交成功 Note over TM,DB2: 二阶段:提交/回滚 alt 提交 TM->>TC: 全局提交 TC->>RM1: 分支提交 TC->>RM2: 分支提交 RM1->>DB1: 删除Undo Log RM2->>DB2: 删除Undo Log else 回滚 TM->>TC: 全局回滚 TC->>RM1: 分支回滚 TC->>RM2: 分支回滚 RM1->>RM1: 解析Undo Log RM1->>DB1: 执行反向SQL RM2->>RM2: 解析Undo Log RM2->>DB2: 执行反向SQL end
7.5 配置示例
▼yaml复制代码seata: enabled:true application-id: order-service tx-service-group: my_tx_group service: vgroup-mapping: my_tx_group: default grouplist: default: 127.0.0.1:8091 registry: type: nacos nacos: server-addr: 127.0.0.1:8848 namespace: seata group: SEATA_GROUP config: type: nacos nacos: server-addr: 127.0.0.1:8848 namespace: seata group: SEATA_GROUP
7.6 全局事务使用
▼java复制代码@Service public class OrderServiceImpl implements OrderService { @Autowired private OrderMapper orderMapper; @Autowired private StockFeignClient stockFeignClient; /** * 使用 @GlobalTransactional 开启全局事务 */ @Override @GlobalTransactional( name = "create-order-tx", rollbackFor = Exception.class ) public void createOrder(OrderDTO dto) { // 1. 创建订单 Order order = new Order(); order.setOrderNo(generateOrderNo()); order.setProductId(dto.getProductId()); order.setQuantity(dto.getQuantity()); orderMapper.insert(order); // 2. 扣减库存(调用其他服务) StockDeductDTO stockDTO = new StockDeductDTO(); stockDTO.setProductId(dto.getProductId()); stockDTO.setQuantity(dto.getQuantity()); stockFeignClient.deductStock(stockDTO); // 3. 如果发生异常,Seata 会自动回滚所有操作 } }
7.7 TCC 模式
TCC 模式特点:
- 强一致性:保证数据强一致性
- 高侵入:需要编写三个接口
- 适用于核心业务
TCC 三个阶段:
| 阶段 | 说明 |
|---|---|
| Try | 资源预留,检查并冻结资源 |
| Confirm | 确认提交,使用预留资源 |
| Cancel | 取消回滚,释放预留资源 |
8. 最佳实践
8.1 服务治理建议
| 方面 | 建议 |
|---|---|
| 服务拆分 | 按业务领域拆分,避免循环依赖 |
| 服务发现 | 使用 Nacos 命名空间隔离环境 |
| 配置管理 | 敏感配置使用加密存储 |
| 限流熔断 | 核心接口设置降级策略 |
8.2 分布式事务选择
| 场景 | 推荐模式 |
|---|---|
| 一般业务 | AT 模式 |
| 高并发核心业务 | TCC 模式 |
| 长流程业务 | Saga 模式 |
8.3 监控告警
▼mermaid复制代码graph LR A[应用监控] --> B[Prometheus] C[链路追踪] --> D[Jaeger/Skywalking] E[日志收集] --> F[ELK/Loki] G[业务指标] --> H[Grafana] B --> H D --> H F --> H
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
