rpc-cloud 是 EasyFK 框架中基于 Spring Cloud OpenFeign 的远程服务调用组件。该模块封装了 Feign 客户端的自动配置,提供统一的错误解码和链路追踪 TraceId 透传能力,使微服务间的 HTTP 调用像本地方法一样简单,同时保障异常信息准确传递和分布式链路的完整性。
<dependency>
<groupId>com.mcst</groupId>
<artifactId>rpc-cloud</artifactId>
</dependency>dependencies {
implementation 'com.mcst:rpc-cloud'
}> 版本号由框架统一 BOM 管理,无需手动指定。
该模块会自动传递引入以下依赖:
> 注意:模块已排除 jackson、spring-boot-starter-logging、spring-cloud-starter-netflix-ribbon 等冲突依赖,避免与框架其他组件产生版本冲突。
rpc-cloud 基于 Spring Cloud OpenFeign 的声明式调用模型,并在此基础上增强了两项能力:
Feign 客户端接口调用
│
▼
FeignClientInterceptor(请求拦截器)
→ 自动注入 TraceId 到请求头
│
▼
Spring Cloud LoadBalancer(负载均衡)
→ 从注册中心选择服务实例
│
▼
HTTP 请求发送到目标服务
│
▼
FeignErrorDecoder(错误解码器)
→ 非 200 响应时解析业务异常
→ 业务异常透传,系统异常国际化模块通过 Spring Boot 自动配置机制(AutoConfiguration.imports)自动注册以下 Bean:
| `FeignErrorDecoder` | `ErrorDecoder` | `@ConditionalOnMissingBean` | 可被业务自定义实现覆盖 |
|---|
> 自定义 ErrorDecoder:如需自定义错误解码逻辑,只需在业务项目中声明一个 FeignErrorDecoder 类型的 Bean,框架默认实现将自动失效。
在 Spring Boot 启动类或配置类上添加 @EnableFeignClients 注解:
@SpringBootApplication
@EnableFeignClients(basePackages = "com.example.client")
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}@FeignClient(name = "user-service", path = "/api/user")
public interface UserServiceClient {
@GetMapping("/{id}")
UserDTO getUserById(@PathVariable("id") Long id);
@PostMapping("/list")
List<UserDTO> queryUsers(@RequestBody UserQueryDTO query);
@PutMapping("/{id}")
UserDTO updateUser(@PathVariable("id") Long id, @RequestBody UserUpdateDTO dto);
@DeleteMapping("/{id}")
void deleteUser(@PathVariable("id") Long id);
}@Service
public class OrderService {
@Autowired
private UserServiceClient userServiceClient;
public OrderDTO createOrder(OrderCreateDTO dto) {
// 像调用本地方法一样调用远程服务
UserDTO user = userServiceClient.getUserById(dto.getUserId());
// ... 业务逻辑
}
}当远程服务返回异常时,FeignErrorDecoder 会自动解析:
@Service
public class OrderService {
@Autowired
private UserServiceClient userServiceClient;
public UserDTO getUser(Long userId) {
try {
return userServiceClient.getUserById(userId);
} catch (BusinessException e) {
// 捕获远程服务的业务异常,code 和 msg 原样保留
log.warn("远程调用业务异常: code={}, msg={}", e.getCode(), e.getMessage());
throw e;
} catch (RuntimeException e) {
// 系统级异常
log.error("远程调用系统异常", e);
throw e;
}
}
}spring:
cloud:
nacos:
discovery:
server-addr: 192.168.1.100:8848
namespace: devspring:
cloud:
openfeign:
client:
config:
default:
connect-timeout: 5000
read-timeout: 10000
user-service: # 针对特定服务的配置
connect-timeout: 3000
read-timeout: 5000logging:
level:
com.example.client: DEBUG # Feign 客户端接口所在包
spring:
cloud:
openfeign:
client:
config:
default:
logger-level: FULL # NONE / BASIC / HEADERS / FULL模块默认使用 Spring Cloud LoadBalancer 进行客户端负载均衡:
spring:
cloud:
loadbalancer:
retry:
enabled: true
cache:
enabled: true
ttl: 30sspring:
cloud:
openfeign:
compression:
request:
enabled: true
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
response:
enabled: truerpc-cloud 通过 FeignClientInterceptor 自动实现 TraceId 的跨服务透传:
1. 上游服务处理请求时,TraceIdContext 中会存储当前请求的 TraceId
2. 通过 Feign 调用下游服务时,拦截器自动将 TraceId 注入到 HTTP 请求头
3. 下游服务通过请求头获取 TraceId,实现完整的调用链追踪
服务A (TraceId: abc123)
→ FeignClientInterceptor 注入 Header: traceId=abc123
→ 服务B 接收到 traceId=abc123
→ FeignClientInterceptor 注入 Header: traceId=abc123
→ 服务C 接收到 traceId=abc123> TraceId 在整个调用链中保持一致,便于日志排查和链路分析。
@FeignClient(name = "user-service", path = "/api/user", fallback = UserServiceFallback.class)
public interface UserServiceClient {
@GetMapping("/{id}")
UserDTO getUserById(@PathVariable("id") Long id);
}
@Component
public class UserServiceFallback implements UserServiceClient {
@Override
public UserDTO getUserById(Long id) {
// 降级逻辑:返回默认值或缓存数据
return new UserDTO();
}
}如需在请求头中传递更多信息(如用户 Token),可添加自定义拦截器:
@Component
public class AuthFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
requestTemplate.header("Authorization", request.getHeader("Authorization"));
}
}
}覆盖默认的 FeignErrorDecoder:
@Component
public class CustomFeignErrorDecoder extends FeignErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
// 自定义错误处理逻辑
if (response.status() == 404) {
return new ResourceNotFoundException("资源不存在");
}
return super.decode(methodKey, response);
}
}1. 接口独立模块:将 Feign 客户端接口定义在独立的 API 模块中,服务提供者和消费者共同引用,保证接口一致性。
2. 合理设置超时:根据接口的实际响应时间设置 connect-timeout 和 read-timeout,避免使用过长的全局超时。
3. 降级容错:核心调用链路建议配置 fallback 降级,避免下游服务故障导致级联失败。
4. 日志级别:生产环境使用 BASIC 或 NONE 级别,开发/测试环境可使用 FULL 级别排查问题。
5. 请求压缩:大报文场景开启 Gzip 压缩,减少网络传输开销。
6. 链路追踪:确保所有微服务都引入 rpc-cloud 组件,保证 TraceId 在整个调用链中完整传递。
7. 异常透传:利用 FeignErrorDecoder 的业务异常透传能力,避免在调用方重复定义相同的错误码。
8. 负载均衡:默认使用 Spring Cloud LoadBalancer 轮询策略,如需自定义可实现 ReactorServiceInstanceLoadBalancer 接口。
9. 避免循环依赖:微服务间避免双向 Feign 调用,如有需要可通过消息队列解耦。
easyfk-rpc-cloud — Spring Cloud 微服务治理框架集成。