背景
项目中有很多微服务,当一个 http 请求A服务并且带了一些header信息,而A服务需要调用B、C服务,B、C服务也需要获取这些header信息,这种场景在项目中非常常见,为了再调用其它服务时让这些header自动传递到下一个服务,我们写了一个全局的feign RequestInterceptor,在拦截器中通过RequestContextHolder去获取当前请求的header信息,并将这些header信息设置到调用下游服务的接口的header头中。
@Bean
RequestInterceptor globalRequestInterceptor() {
return (template) -> {
WHITE_LIST_HEADER_FIELDS.forEach((headerField) -> {
String headerValue = this.getHeader(headerField);
if (!template.headers().containsKey(headerField) && Objects.nonNull(headerValue)) {
template.header(headerField, new String[]{headerValue});
}
});
};
}
private String getHeader(String header) {
HttpServletRequest request = this.getHttpServletRequest();
return request == null ? null : request.getHeader(header);
}
private HttpServletRequest getHttpServletRequest() {
ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
return attributes == null ? null : attributes.getRequest();
}
问题
一个 http 请求过来A服务的a1接口,a1接口有一部分代码逻辑a2是异步的,在异步的a2方法中需要调用B服务。当通过feign调用B服务,走到RequestInterceptor之时,线上环境却偶现获取不到header了。
@Service
public class Service1 {
@Autowired
private Service2 service2;
public void a1() {
// some sync code
service2.a2();
//some sync code
}
}
@Service
public class Service2 {
@