You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Cloud Sleuth中新增client_ip等自定义标签并透传至下游微服务

实现步骤

1. API网关(Spring Cloud Gateway)侧配置

1.1 新增Sleuth Baggage配置

在网关的application.yml中添加如下配置,声明要传递的自定义字段:

spring:
  sleuth:
    baggage:
      # 允许跨服务传递的自定义字段
      remote-fields: client_ip
      # 自动将该字段加入MDC,输出到日志标签
      tag-fields: client_ip

注:如果使用Sleuth 2.x版本,配置改为spring.sleuth.propagation-keys: client_ip即可

1.2 编写全局过滤器采集客户端IP

实现优先级高于路由转发的全局过滤器,获取真实客户端IP后注入Sleuth链路上下文:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE + 1) // 优先级低于Sleuth链路创建过滤器,高于路由转发
public class ClientIpInjectFilter implements GlobalFilter {

    private final Tracer tracer;

    public ClientIpInjectFilter(Tracer tracer) {
        this.tracer = tracer;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取真实客户端IP,处理反向代理场景
        String clientIp = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
        if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = exchange.getRequest().getHeaders().getFirst("Proxy-Client-IP");
        }
        if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = exchange.getRequest().getHeaders().getFirst("WL-Proxy-Client-IP");
        }
        if (clientIp == null || clientIp.isEmpty() || "unknown".equalsIgnoreCase(clientIp)) {
            clientIp = Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getAddress().getHostAddress();
        }
        // 多个代理场景取第一个IP为真实客户端IP
        if (clientIp != null && clientIp.contains(",")) {
            clientIp = clientIp.split(",")[0].trim();
        }

        // 将client_ip注入Sleuth Baggage上下文
        tracer.createBaggageInScope(tracer.currentSpan().context(), "client_ip", clientIp);
        return chain.filter(exchange);
    }
}

2. 下游微服务配置

所有需要获取client_ip标签的下游微服务,都需要添加和网关一致的Baggage配置:

spring:
  sleuth:
    baggage:
      remote-fields: client_ip
      tag-fields: client_ip

配置完成后Sleuth会自动从请求头中解析上游传递的client_ip,自动注入MDC上下文,不需要额外编码。

3. 日志格式适配

在你的日志输出pattern中添加%X{client_ip}占位符即可将client_ip输出到日志中,示例logback pattern:

<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} [%X{traceId},%X{spanId},%X{client_ip}] - %msg%n</pattern>

注意事项

  • Feign、Spring管理的RestTemplate默认会自动携带Baggage字段传递到下游,不需要额外配置
  • 如果你的网关是Zuul,逻辑和上述方案一致,只需要将全局过滤器替换为Zuul的前置过滤器即可
  • 生产环境建议对采集到的client_ip做合法性校验,避免恶意构造的请求头导致IP异常

内容的提问来源于stack exchange,提问作者chuanguojinbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:36:05