首页 > 解决方案 > Eureka 注册表未记录相关 ID

问题描述

我在 Eureka 服务器注册表中注册的 zuul 网关后面设置了一些微服务。在网关中,我创建了一个过滤器,它在每次发出请求时创建一个关联 ID,然后这个 ID 被发送到微服务,微服务也记录它。问题是我无法让注册表记录它。这是网关过滤器的代码:

import com.netflix.zuul.context.RequestContext;
import org.apache.commons.lang.StringUtils;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

@Component
public class Slf4jMDCFilter extends OncePerRequestFilter {
    public static final String RESPONSE_TOKEN_HEADER = "Correlation_ID";
    public static final String MDC_UUID_TOKEN_KEY = "Slf4jMDCFilter.UUID";

    @Override
    protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain)
        throws IOException, ServletException {
        final RequestContext context = RequestContext.getCurrentContext();
        try {
            String token = UUID.randomUUID().toString();
            if (!StringUtils.isEmpty(request.getHeader(RESPONSE_TOKEN_HEADER))) {
                token = request.getHeader(RESPONSE_TOKEN_HEADER);
            }

            MDC.put(MDC_UUID_TOKEN_KEY, token);
            context.addZuulRequestHeader(RESPONSE_TOKEN_HEADER, token);
            chain.doFilter(request, response);
        } finally {
            MDC.remove(MDC_UUID_TOKEN_KEY);
        }
    }
}

//配置类

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

@Configuration
@ConfigurationProperties(prefix = "config.slf4jfilter")
public class Slf4jMDCFilterConfiguration {
    @Bean
    public FilterRegistrationBean<Slf4jMDCFilter> servletRegistrationBean() {
        final FilterRegistrationBean<Slf4jMDCFilter> registrationBean = new FilterRegistrationBean<>();
        final Slf4jMDCFilter log4jMDCFilterFilter = new Slf4jMDCFilter();
        registrationBean.setFilter(log4jMDCFilterFilter);
        registrationBean.setOrder(2);
        return registrationBean;
    }
}

这是用于微服务的过滤器:

@Component
public class Slf4jMDCFilter extends OncePerRequestFilter {
    public static final String RESPONSE_TOKEN_HEADER = "Correlation_ID";
    public static final String MDC_UUID_TOKEN_KEY = "Slf4jMDCFilter.UUID";

    @Override
    protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain)
        throws java.io.IOException, ServletException {
        try {
            if (!StringUtils.isEmpty(request.getHeader(RESPONSE_TOKEN_HEADER))) {
                String token = request.getHeader(RESPONSE_TOKEN_HEADER);
                MDC.put(MDC_UUID_TOKEN_KEY, token);
                response.addHeader(RESPONSE_TOKEN_HEADER, token);
                chain.doFilter(request, response);
            }
        } finally {
            MDC.remove(MDC_UUID_TOKEN_KEY);
        }
    }
}

配置与用于网关的配置相同。如果此过滤器未应用于注册表,则所有其他服务都可以正常工作并记录它们的 ID。一旦我应用它,注册表将不会转发任何请求。如果我做错了什么或者我错过了什么,请告诉我。

标签: springservlet-filtersnetflix-eurekanetflix-zuulmdc

解决方案


推荐阅读