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

Istio服务网格下,如何从Spring Boot过滤器提取请求源服务名称

在Istio服务网格中获取Spring Boot应用的源服务名称

一、Istio自动注入的源服务标识头

Istio的Envoy代理会在转发跨服务请求时,自动注入几个HTTP头,可直接用于提取源服务信息:

  • X-Envoy-Source-Service:格式为{服务名}.{命名空间}.svc.cluster.local,包含完整的源服务FQDN,能直接提取出服务名
  • X-Envoy-Service-Cluster:格式一般为outbound|{端口}|{服务名}|{服务名}.{命名空间}.svc.cluster.local,也可从中解析出服务名

优先使用X-Envoy-Source-Service,格式更规整,提取逻辑更简单。

二、Spring Boot Servlet过滤器实现提取

你可以自定义Servlet过滤器,在请求进入业务逻辑前提取源服务名称,方便后续上报Datadog指标。示例代码如下:

自定义过滤器类

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;

public class IstioSourceServiceFilter implements Filter {

    private static final String ISTIO_SOURCE_HEADER = "X-Envoy-Source-Service";
    public static final String SOURCE_SERVICE_ATTR = "istio.source.service";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) request;
        String sourceHeader = httpReq.getHeader(ISTIO_SOURCE_HEADER);
        
        if (sourceHeader != null && !sourceHeader.isBlank()) {
            // 分割FQDN,取第一个点号前的部分作为服务名
            String sourceServiceName = sourceHeader.split("\\.")[0];
            // 将服务名存入请求属性,供后续代码取用
            httpReq.setAttribute(SOURCE_SERVICE_ATTR, sourceServiceName);
        }
        
        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void destroy() {}
}

注册过滤器

通过Spring配置类将过滤器注册到应用中:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterRegistrationConfig {

    @Bean
    public FilterRegistrationBean<IstioSourceServiceFilter> istioSourceFilter() {
        FilterRegistrationBean<IstioSourceServiceFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new IstioSourceServiceFilter());
        // 拦截所有请求
        registration.addUrlPatterns("/*");
        // 设置优先级,确保在业务过滤器前执行
        registration.setOrder(1);
        return registration;
    }
}

之后,你可以在Controller、切面或者Datadog指标上报代码中,通过request.getAttribute(IstioSourceServiceFilter.SOURCE_SERVICE_ATTR)获取源服务名称,结合当前请求的端点路径,统计不同服务对该端点的调用次数。

三、关于source.principal的说明

source.principal是Istio提供的身份凭证,格式通常为spiffe://cluster.local/ns/{命名空间}/sa/{服务账号},它指向的是服务账号而非直接的服务名称。虽然部分场景下服务账号名称可能和服务名一致,但这种关联并不强制,依赖它获取服务名风险较高。因此更推荐直接使用Istio注入的X-Envoy-Source-Service头来获取源服务名称。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:22:38