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
相关产品推荐
相关产品推荐

