自定义灰度IRule
远程调用的灰度发布
当请求过来,如果有服务间的调用,不管是使用Feign
还是RestTemplate
,都面临版本问题。所以可以将其加在请求头中,提供给下一个服务使用判断
/**
* 版本参数
*/
@Slf4j
public class ReqVersionContext {
/**
* metadata 里的应用version
*/
public static final String SERVER_VERSION_HEADER_PARAM_NAME = "SERVER_VERSION";
/**
* 当前请求version版本
*/
public static ThreadLocal<String> reqVersionThreadLocal = new ThreadLocal<>();
}
外部请求进入应用,用HandlerInterceptor
设置version
/**
* 这里获取进入的http请求的version,放入线程私有变量,以供后面对外进行feign以及 RestTemplate请求时使用(将version放入请求头中),可以在拦截器干,也可在aop干,
*/
public class ReqVersionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String version = request.getHeader(ReqVersionContext.SERVER_VERSION_HEADER_PARAM_NAME);
ReqVersionContext.reqVersionThreadLocal.set(version);
return true;
}
}
对外请求设置拦截器,设置version
Feign
对外调用设置version
public class CoreFeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
template.header(ReqVersionContext.SERVER_VERSION_HEADER_PARAM_NAME, ReqVersionContext.reqVersionThreadLocal.get());
}
}
RestTemplate
设置对外请求的拦截器,以设置version
/**
* restTemplate请求拦截器
*/
public class GrayRuleInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
// 这里设置一系列请求前要执行的操作。
//设置请求版本,
request.getHeaders().add(ReqVersionContext.SERVER_VERSION_HEADER_PARAM_NAME, ReqVersionContext.reqVersionThreadLocal.get());
}
}
/**
* RestTemplate
* @param weightRuleInterceptor 要注入的拦截器
* @return
*/
@Bean
@LoadBalanced
public RestTemplate getRestTemplage(@Nullable GrayRuleInterceptor grayRuleInterceptor) {
RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> list = new ArrayList<>();
if (null != grayRuleInterceptor) {
list.add(grayRuleInterceptor);
}
restTemplate.setInterceptors(list);
return restTemplate;
}