Spring Cloud 组件与配置实践
Spring Cloud 是微服务开发的标准框架,提供了一套开箱即用的分布式系统解决方案。本文档从实战角度出发,讲解 Spring Cloud 核心组件的使用与配置。
一、Spring Cloud 组件全景
1.1 Spring Cloud 全家桶
┌─────────────┐
│ Gateway │ ← 网关(统一入口、路由转发、限流)
└──────┬──────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Service │ │ Service │ │ Service │ ← 微服务集群
│ A │ │ B │ │ C │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
└────────────┼────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Nacos │ │ Sentinel │ │ Sleuth │ ← 基础设施
│ 注册配置 │ │ 熔断限流 │ │ 链路追踪 │
└──────────┘ └──────────┘ └──────────┘
1.2 组件职责速查
| 组件 | 职责 | 一句话 |
|---|---|---|
| Nacos | 服务注册发现 + 配置中心 | 服务在哪、配置是什么 |
| OpenFeign | 声明式 HTTP 客户端 | 写接口就能调远程服务 |
| Spring Cloud LoadBalancer | 客户端负载均衡 | 自动选一个健康的实例 |
| Gateway | API 网关 | 统一入口、路由、鉴权、限流 |
| Sentinel | 流量控制 + 熔断降级 | 保护自己不被流量打垮 |
| Sleuth + Zipkin | 分布式链路追踪 | 一个请求经过哪些服务 |
1.3 版本对应关系(Spring Cloud Alibaba)
| Spring Cloud | Spring Cloud Alibaba | Spring Boot | Nacos |
|---|---|---|---|
| 2022.0.x | 2022.0.0.x | 3.0.x | 2.x |
| 2021.0.x | 2021.0.5.x | 2.6.x / 2.7.x | 2.x |
| 2020.0.x | 2021.1 | 2.4.x / 2.5.x | 1.4.x |
| Hoxton.SR12 | 2.2.10 | 2.3.x | 1.4.x |
二、服务注册与发现(Nacos)
2.1 引入依赖
<!-- Nacos 服务发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2.2 基本配置
# bootstrap.yml(Spring Cloud 2.4+ 用 application.yml)
spring:
application:
name: order-service # 服务名,注册到 Nacos 的名称
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 # Nacos 服务地址
namespace: dev # 命名空间 ID(不是名称)
group: DEFAULT_GROUP # 分组
cluster-name: HZ # 集群名称(用于就近路由)
ephemeral: true # true=临时实例(AP模式),false=持久实例(CP模式)
2.3 启动类注解
@SpringBootApplication
@EnableDiscoveryClient // 开启服务发现(Spring Cloud 2.x 可省略,自动启用)
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
2.4 验证服务注册
启动后访问 Nacos 控制台 http://127.0.0.1:8848/nacos,在"服务管理 → 服务列表"中能看到 order-service。
# 命令行验证
curl http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=order-service
2.5 服务分级(机房就近路由)
# 订单服务(杭州集群)
spring:
cloud:
nacos:
discovery:
cluster-name: HZ # 杭州集群
# 用户服务(北京集群)
spring:
cloud:
nacos:
discovery:
cluster-name: BJ # 北京集群
// Ribbon 配置:优先调用同集群的服务
// application.yml 全局配置
spring:
cloud:
nacos:
discovery:
cluster-name: HZ
# 负载均衡策略
order-service:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule
三、远程调用(OpenFeign + LoadBalancer)
3.1 引入依赖
<!-- OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Spring Cloud LoadBalancer(Spring Cloud 2.x 默认,替代 Ribbon) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
3.2 声明 Feign 客户端
// 1. 定义 Feign 接口
// name = 目标服务在 Nacos 中的服务名
@FeignClient(name = "user-service", // Nacos 中的服务名
path = "/users", // 公共路径前缀
fallbackFactory = UserFeignFallback.class) // 降级处理
public interface UserFeignClient {
@GetMapping("/{id}")
// @PathVariable 必须显式指定 value
Result<UserVO> getUserById(@PathVariable("id") Long id);
@GetMapping("/batch")
Result<List<UserVO>> getUserByIds(@RequestParam("ids") List<Long> ids);
@PostMapping
Result<Void> createUser(@RequestBody UserDTO user);
}
// 2. 服务降级工厂(用于 Sentinel 熔断降级)
@Component
public class UserFeignFallback implements FallbackFactory<UserFeignClient> {
@Override
public UserFeignClient create(Throwable cause) {
log.error("调用 user-service 失败", cause);
return new UserFeignClient() {
@Override
public Result<UserVO> getUserById(Long id) {
return Result.error("用户服务暂时不可用");
}
@Override
public Result<List<UserVO>> getUserByIds(List<Long> ids) {
return Result.error("用户服务暂时不可用");
}
@Override
public Result<Void> createUser(UserDTO user) {
return Result.error("用户服务暂时不可用");
}
};
}
}
3.3 启用 Feign
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.example.feign") // 扫描 Feign 接口
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
3.4 调用方式
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/{id}")
public Result<OrderVO> getOrder(@PathVariable Long id) {
// 1. 查订单
Order order = orderService.getById(id);
// 2. 通过 Feign 调用用户服务,获取用户信息
// Feign 内部:从 Nacos 获取 user-service 的实例列表
// → LoadBalancer 选一个实例
// → 发送 HTTP 请求
Result<UserVO> userResult = userFeignClient.getUserById(order.getUserId());
// 3. 组装返回
OrderVO vo = new OrderVO();
vo.setOrder(order);
if (userResult.isSuccess()) {
vo.setUser(userResult.getData());
}
return Result.ok(vo);
}
}
3.5 Feign 配置优化
spring:
cloud:
openfeign:
client:
config:
default: # 全局默认配置
connect-timeout: 3000 # 连接超时(毫秒)
read-timeout: 5000 # 读取超时(毫秒)
logger-level: BASIC # 日志级别:NONE / BASIC / HEADERS / FULL
user-service: # 针对特定服务的配置(覆盖全局)
connect-timeout: 2000
read-timeout: 4000
compression:
request:
enabled: true # 开启请求 Gzip 压缩
min-request-size: 2048 # 超过 2KB 才压缩
response:
enabled: true # 开启响应 Gzip 解压
// Feign 拦截器:统一传递请求头(如 Token)
@Component
public class FeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// 从当前请求上下文获取 Token,透传给下游服务
String token = RequestContextHolder.getRequestAttributes()
.getHeader("Authorization");
if (token != null) {
template.header("Authorization", token);
}
}
}
3.6 Feign 日志配置
logging:
level:
com.example.feign.UserFeignClient: DEBUG # 打印 Feign 请求详情
3.7 Feign 常见问题
问题1:GET 请求传对象数组
// ❌ 错误:GET 请求不能传 body
@GetMapping("/users")
Result<List<UserVO>> getUsers(@RequestBody List<Long> ids);
// ✅ 正确:拆分为 @RequestParam
@GetMapping("/users")
Result<List<UserVO>> getUsers(@RequestParam("ids") List<Long> ids);
问题2:Feign 调用超时
# 默认超时 1 秒太短,必须放大
spring:
cloud:
openfeign:
client:
config:
default:
read-timeout: 10000 # 放大到 10 秒
问题3:Feign 调用时丢失请求头(Token 透传)
// 见上方 FeignRequestInterceptor 示例
// 本质:Feign 发起新请求时不会自动携带原始请求的 Header
// 解决:Feign 拦截器中手动设置
四、API 网关(Spring Cloud Gateway)
4.1 引入依赖
<!-- Gateway 依赖(不包含 spring-boot-starter-web,两者冲突) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 需要 Nacos 服务发现,结合使用 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
4.2 基本路由配置
spring:
cloud:
gateway:
routes:
# 路由1:订单服务
- id: order-service-route # 路由 ID(唯一)
uri: lb://order-service # lb:// = 通过负载均衡转发
predicates:
- Path=/api/orders/** # 匹配 /api/orders/** 的请求
filters:
- StripPrefix=1 # 去掉第一段路径 /api,转发到 /orders/**
# 路由2:用户服务
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
# 路由3:后台管理(需要鉴权)
- id: admin-service-route
uri: lb://admin-service
predicates:
- Path=/api/admin/**
filters:
- StripPrefix=1
- AuthFilter # 自定义鉴权过滤器
# 全局默认过滤器
default-filters:
- AddRequestHeader=X-Request-Id, ${random.uuid} # 添加请求追踪 ID
4.3 断言(Predicate)常用写法
| 断言 | 说明 | 示例 |
|---|---|---|
Path=/api/** |
路径匹配 | 匹配 /api/users |
Header=X-Request-Id, \d+ |
必须包含某请求头 | Header 中有数字 |
Method=GET,POST |
请求方法 | 只允许 GET/POST |
Query=name, zh.* |
必须有某查询参数 | ?name=zhang |
Before=2025-01-01T00:00:00+08:00[Asia/Shanghai] |
指定时间之前 | 活动时段控制 |
Host=**.example.com |
根据域名路由 | 多域名场景 |
4.4 过滤器(Filter)实战
内置过滤器:
filters:
- StripPrefix=1 # 去掉路径前缀
- AddRequestHeader=X-Header, value # 添加请求头
- AddResponseHeader=X-Resp, value # 添加响应头
- RewritePath=/api/(?<seg>.*), /$\{seg} # 路径重写
- PrefixPath=/api # 添加路径前缀
- RequestRateLimiter=..., redis-rate-limiter # 限流
- Retry=3 # 请求失败重试 3 次
- CircuitBreaker=..., ... # 断路器
自定义全局过滤器:鉴权
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getURI().getPath();
// 1. 白名单路径放行
if (path.startsWith("/api/public/") || path.startsWith("/api/auth/login")) {
return chain.filter(exchange);
}
// 2. 获取 Token
String token = exchange.getRequest().getHeaders().getFirst("Authorization");
if (token == null || token.isEmpty()) {
// 返回 401
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 3. 验证 Token(简化示例)
try {
// 解析 Token 获取用户 ID,存入 Header 传递给下游
Long userId = JwtUtil.parseToken(token);
exchange.getRequest().mutate()
.header("X-User-Id", userId.toString())
.build();
} catch (Exception e) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
// 4. 放行
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1; // 值越小越先执行
}
}
4.5 跨域配置(CORS)
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "http://localhost:3000" # 允许的前端地址
allowedMethods:
- GET
- POST
- PUT
- DELETE
allowedHeaders: "*"
allowCredentials: true
maxAge: 3600 # 预检请求缓存时间
五、配置中心(Nacos Config)
5.1 引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
5.2 基本配置
# bootstrap.yml(优先于 application.yml 加载)
spring:
application:
name: order-service
cloud:
nacos:
# 服务发现配置
discovery:
server-addr: 127.0.0.1:8848
namespace: dev
# 配置中心配置
config:
server-addr: 127.0.0.1:8848
namespace: dev # 命名空间 ID
group: DEFAULT_GROUP # 分组
file-extension: yaml # 配置文件格式
refresh-enabled: true # 开启自动刷新
# 多环境配置
profiles:
active: dev
5.3 Nacos 配置文件命名规则
${prefix}-${spring.profiles.active}.${file-extension}
示例:
order-service.yaml → 默认配置
order-service-dev.yaml → dev 环境配置
order-service-prod.yaml → prod 环境配置
5.4 动态刷新配置
// 方式1:@Value(需要 @RefreshScope)
@RestController
@RefreshScope // 关键:配置变更时自动刷新
public class OrderController {
@Value("${order.page-size:10}") // 默认值 10
private int pageSize;
@Value("${order.welcome-msg:欢迎}")
private String welcomeMsg;
@GetMapping("/config")
public Map<String, Object> getConfig() {
return Map.of("pageSize", pageSize, "welcomeMsg", welcomeMsg);
}
}
// 方式2:@ConfigurationProperties(推荐,类型安全,无需 @RefreshScope)
@Component
@ConfigurationProperties(prefix = "order")
@RefreshScope
@Data
public class OrderProperties {
private int pageSize = 10;
private String welcomeMsg = "欢迎";
private Map<String, String> cache = new HashMap<>(); // order.cache[key]=value
}
// 使用
@Autowired
private OrderProperties orderProperties;
5.5 多配置优先级
应用本身配置 > 扩展配置 > 共享配置
优先级从高到低:
application-profile.yml (应用-环境配置)
↓
application.yml (应用公共配置)
↓
extension-config[N].yml (扩展配置)
↓
shared-config[N].yml (共享配置)
5.6 共享配置实践
# bootstrap.yml
spring:
cloud:
nacos:
config:
# 共享配置:多个服务共享同一份配置
shared-configs:
- data-id: common-datasource.yaml # 公共数据源配置
group: DEFAULT_GROUP
refresh: true
- data-id: common-redis.yaml # 公共 Redis 配置
group: DEFAULT_GROUP
refresh: true
# 扩展配置:按需加载
extension-configs:
- data-id: order-extra.yaml # 订单服务专属扩展配置
group: DEFAULT_GROUP
refresh: true
六、熔断降级(Sentinel)
6.1 引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Sentinel 控制台(可视化规则管理) -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</dependency>
6.2 基本配置
spring:
cloud:
sentinel:
transport:
dashboard: 127.0.0.1:8080 # Sentinel 控制台地址
port: 8719 # 本机与控制台通信端口
eager: true # 启动时立即初始化(false=懒加载)
datasource:
# 规则持久化到 Nacos
ds1:
nacos:
server-addr: 127.0.0.1:8848
data-id: order-service-sentinel-rules
group-id: DEFAULT_GROUP
data-type: json
rule-type: flow
6.3 流量控制(限流)
// @SentinelResource 定义资源,配置限流规则
@RestController
public class OrderController {
@GetMapping("/orders/{id}")
@SentinelResource(
value = "getOrder", // 资源名称
blockHandler = "getOrderBlockHandler", // 被限流时的降级方法
fallback = "getOrderFallback" // 业务异常时的降级方法
)
public Result<OrderVO> getOrder(@PathVariable Long id) {
// 业务逻辑
return Result.ok(orderService.getById(id));
}
// 被限流时的处理方法(参数必须包含原方法参数 + BlockException)
public Result<OrderVO> getOrderBlockHandler(Long id, BlockException e) {
return Result.error("请求人数太多,请稍后再试");
}
// 业务异常时的降级方法(参数必须包含原方法参数 + Throwable)
public Result<OrderVO> getOrderFallback(Long id, Throwable e) {
log.error("查询订单失败,orderId: {}", id, e);
return Result.error("服务暂不可用");
}
}
6.4 Sentinel 控制台规则
| 规则类型 | 说明 | 示例 |
|---|---|---|
| 流量控制(Flow) | 超过阈值时限流 | QPS > 100 时限流 |
| 降级(Degrade) | 响应慢/异常率高时降级 | RT > 200ms 时熔断 |
| 热点参数(ParamFlow) | 针对特定参数限流 | 热点商品 ID 限流 |
| 系统规则(System) | 系统级别保护 | CPU > 80% 时限流 |
| 授权规则(Auth) | 黑白名单控制 | 某 IP 禁止访问 |
6.5 代码中定义规则(替代控制台)
@Component
public class SentinelRuleConfig {
@PostConstruct
public void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
// 规则1:getOrder 接口 QPS 限制
FlowRule rule1 = new FlowRule();
rule1.setResource("getOrder"); // 资源名
rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); // QPS 模式
rule1.setCount(100); // QPS 上限
rules.add(rule1);
// 规则2:createOrder 接口并发线程数限制
FlowRule rule2 = new FlowRule();
rule2.setResource("createOrder");
rule2.setGrade(RuleConstant.FLOW_GRADE_THREAD); // 并发线程模式
rule2.setCount(20); // 最大并发线程数
rules.add(rule2);
FlowRuleManager.loadRules(rules);
}
}
6.6 Sentinel 与 OpenFeign 集成
# 开启 Sentinel 对 Feign 的支持
feign:
sentinel:
enabled: true # 开启后 fallbackFactory 才生效
// Feign 接口中指定 fallbackFactory
@FeignClient(
name = "user-service",
fallbackFactory = UserFeignFallback.class // Sentinel 限流后走这里
)
public interface UserFeignClient {
@GetMapping("/users/{id}")
Result<UserVO> getUserById(@PathVariable("id") Long id);
}
6.7 对比:Sentinel vs Hystrix
| 维度 | Sentinel | Hystrix |
|---|---|---|
| 维护状态 | 活跃维护(阿里) | 已停更(Netflix) |
| 隔离策略 | 信号量隔离 | 线程池隔离 |
| 熔断降级 | 支持(慢调用/异常) | 支持(超时/异常) |
| 限流 | 支持(QPS/线程) | 不支持 |
| 控制台 | 功能完善 | 基础 |
| 规则动态生效 | 支持 | 不支持 |
| 选择 | ✅ 推荐 | ❌ 已停更 |
七、链路追踪(Sleuth + Zipkin 或 Micrometer Tracing)
7.1 引入依赖(Spring Cloud 2.x 传统方案)
<!-- Sleuth:生成 TraceId + SpanId -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- Zipkin:上报链路数据到 Zipkin Server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
7.2 配置
spring:
sleuth:
sampler:
probability: 0.1 # 采样率 10%(生产环境避免全部采样)
zipkin:
base-url: http://127.0.0.1:9411 # Zipkin Server 地址
sender:
type: web # 通过 HTTP 上报
7.3 Spring Boot 3.x 替代方案(Micrometer Tracing)
Spring Cloud 2022.x+ 已弃用 Sleuth:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-reporter-brave-zipkin</artifactId>
</dependency>
management:
tracing:
sampling:
probability: 0.1 # 采样率 10%
zipkin:
tracing:
endpoint: http://127.0.0.1:9411/api/v2/spans
八、完整项目配置示例
8.1 父工程 pom.xml
<properties>
<java.version>17</java.version>
<spring-boot.version>3.2.0</spring-boot.version>
<spring-cloud.version>2023.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<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 -->
<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 -->
<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>
8.2 微服务模块 pom.xml
<dependencies>
<!-- Nacos 服务发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Nacos 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- LoadBalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
8.3 微服务 bootstrap.yml(完整配置)
# bootstrap.yml
spring:
application:
name: order-service
# 指定环境
profiles:
active: ${SPRING_PROFILES_ACTIVE:dev}
cloud:
# Nacos 服务发现 + 配置中心
nacos:
discovery:
server-addr: ${NACOS_ADDR:127.0.0.1:8848}
namespace: ${NACOS_NAMESPACE:dev}
group: DEFAULT_GROUP
config:
server-addr: ${NACOS_ADDR:127.0.0.1:8848}
namespace: ${NACOS_NAMESPACE:dev}
group: DEFAULT_GROUP
file-extension: yaml
refresh-enabled: true
shared-configs: # 共享配置
- data-id: common-log.yaml
group: DEFAULT_GROUP
refresh: true
- data-id: common-datasource.yaml
group: DEFAULT_GROUP
refresh: true
# Sentinel
sentinel:
transport:
dashboard: ${SENTINEL_DASHBOARD:127.0.0.1:8080}
port: 8719
eager: true # 立即初始化
datasource:
flow:
nacos:
server-addr: ${NACOS_ADDR:127.0.0.1:8848}
data-id: order-service-flow-rules
group-id: DEFAULT_GROUP
rule-type: flow
# OpenFeign 全局超时
openfeign:
client:
config:
default:
connect-timeout: 5000
read-timeout: 10000
compression:
request:
enabled: true
response:
enabled: true
# 日志级别
logging:
level:
com.example: DEBUG
com.alibaba.nacos.client: WARN # Nacos 客户端日志不要太多
8.4 启动类完整注解
@SpringBootApplication
@EnableDiscoveryClient // 服务发现
@EnableFeignClients(basePackages = "com.example.feign") // Feign
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
九、常见问题排查
9.1 服务注册上了但 Feign 调用报 404
可能原因:
- 目标服务的 context-path 不一致 → 检查
server.servlet.context-path - Feign 接口路径写错了 → 检查
@RequestMapping或@GetMapping路径 - 目标服务有多个实例,但只有一个对外 → 检查健康状态
# 排查步骤
# 1. 确认服务已注册
curl http://nacos:8848/nacos/v1/ns/instance/list?serviceName=user-service
# 2. 手动调用验证
curl http://user-service:8080/users/1
# 3. Feign 开启 FULL 日志
logging:
level:
com.example.feign: FULL
9.2 配置刷新不生效
# 排查步骤
# 1. 确认 Nacos 控制台配置确实改了
# 2. 确认类上有 @RefreshScope
# 3. 确认不是 static 字段
# 4. 开启 Nacos 日志
logging.level.com.alibaba.nacos.client.config: DEBUG
# 5. 日志中查找 "received config change notification"
9.3 Gateway 路由不生效
# 开启 Gateway 路由日志
logging:
level:
org.springframework.cloud.gateway: TRACE
org.springframework.cloud.gateway.handler.RoutePredicateHandlerMapping: DEBUG
9.4 Sentinel 规则不生效
# 1. 确认 Sentinel 控制台能看到应用
# 2. 确认应用中对应资源有访问流量
# 3. 确认规则类型和数据正确
# 4. 检查 Nacos 持久化配置是否同步
十、总结
10.1 Spring Cloud 组件选型
| 组件 | 推荐 | 已弃用 |
|---|---|---|
| 注册中心 | Nacos | Eureka(停更) |
| 配置中心 | Nacos | Spring Cloud Config(不支持推送) |
| 远程调用 | OpenFeign | RestTemplate |
| 负载均衡 | Spring Cloud LoadBalancer | Ribbon(停更) |
| 网关 | Gateway | Zuul(停更) |
| 熔断限流 | Sentinel | Hystrix(停更) |
| 链路追踪 | Micrometer Tracing | Sleuth(3.x 弃用) |
10.2 版本选择速查
Spring Boot 2.x → Spring Cloud 2021.0.x → Spring Cloud Alibaba 2021.0.5.x
Spring Boot 3.x → Spring Cloud 2022.0.x+ → Spring Cloud Alibaba 2022.0.x+