如何在特定条件下禁用Spring Sleuth/Feign的请求头传播?
Spring Sleuth + Feign 指定调用移除请求头解决方案
Spring Cloud生态完全支持该需求,不需要修改默认的全局传播规则,可通过以下两种轻量方式实现针对指定调用的请求头过滤:
方式一:指定Feign客户端绑定专属拦截器(推荐)
Feign本身的客户端级拦截器优先级高于全局传播逻辑,仅对绑定的Feign客户端生效,不会影响其他下游调用,侵入性最低。
- 自定义请求头移除拦截器
import feign.RequestInterceptor; import feign.RequestTemplate; import java.util.Arrays; import java.util.List; public class SpecifiedHeaderRemoveInterceptor implements RequestInterceptor { // 定义需要移除的请求头列表 private static final List<String> FORBIDDEN_HEADERS = Arrays.asList("custom-header-1", "custom-header-2"); @Override public void apply(RequestTemplate template) { FORBIDDEN_HEADERS.forEach(template::removeHeader); } }
- 将拦截器绑定到目标Feign客户端
import org.springframework.cloud.openfeign.FeignClient; // 仅当前Feign客户端会执行头移除逻辑 @FeignClient(name = "target-downstream-service", configuration = SpecifiedHeaderRemoveInterceptor.class) public interface TargetServiceFeignApi { // 你的接口定义 }
方式二:自定义Feign请求注入逻辑(适合细粒度控制场景)
如果需要同个Feign客户端下不同接口执行不同的过滤规则,可自定义Sleuth的Feign请求注入器覆盖默认逻辑:
import brave.Span; import org.springframework.cloud.sleuth.instrument.web.client.feign.DefaultFeignRequestInjector; import org.springframework.cloud.sleuth.instrument.web.client.feign.FeignRequestInjector; import org.springframework.stereotype.Component; @Component public class CustomFeignRequestInjector implements FeignRequestInjector { private final DefaultFeignRequestInjector defaultInjector = new DefaultFeignRequestInjector(); @Override public void inject(Span span, RequestTemplate template) { // 先保留Sleuth默认的trace链路相关头注入 defaultInjector.inject(span, template); // 自定义细粒度过滤规则,例:仅指定路径的请求移除特定头 if ("/api/sensitive/operation".equals(template.path())) { template.removeHeader("custom-header-1"); } } }
注意事项
- 不要修改全局配置
spring.sleuth.propagation-keys,该配置会影响所有服务间调用的请求头传播,不符合仅调整单个调用的需求 - 若存在全局Feign拦截器,可通过
@Order注解调整自定义拦截器的执行顺序,确保头移除逻辑在所有头注入逻辑之后执行
内容的提问来源于stack exchange,提问作者Augusto
相关产品推荐
相关产品推荐

