代码拉取完成,页面将自动刷新
解决eureka缓存以及ribbon缓存服务注册表导致本地缓存刷新延迟从而在服务切换过程中多次请求已下线服务问题
实现原理:ribbon可以根据客户端注册在eureka是的tag实现动态路由
核心类:RibbonFilterContextHolder
// 在zuul转发或者feign调用前写入动态路由策略,指定转发到有该tag-value的服务
RibbonFilterContextHolder.getCurrentContext()
.add("${tagName}", ${tagValue});
// 客户端服务配置
eureka:
instance:
metadata-map:
tagName1: tagValue1
tagName2: tagValue2
public abstract class ServiceLancherHandler {
protected boolean handle(String serviceId) {
String serviceLancher = getServiceLancher(serviceId);
if (StringUtils.isEmpty(serviceLancher)){
return false;
}
RibbonFilterContextHolder.clearCurrentContext();
RibbonFilterContextHolder.getCurrentContext()
.add("lancher", serviceLancher);
return true;
}
/**
子类通过实现该方法可自定义访问策略
*/
abstract String getServiceLancher(String serviceId);
}
// 配置指定tag的职责链,
// 例如可定义先从header中寻找,
// 再从redis中寻找,再从数据库中寻找,
//可自行实现ServiceLancherHandler,本demo只实现了从header中寻找
@Bean
ServiceLancherHandlerChain serviceLancherHandlerChain(){
ServiceLancherHandlerChain chain = new ServiceLancherHandlerChain();
chain.addHandler(new RequestHeaderServiceLancherHandler());
return chain;
}
// AbFilter extends ZuulFilter
// 继承zuulfilter,实现自定义zuul前置拦截器,在服务转发前指定路由策略
// 在自定义的zuulfilter中,获取到第一层转发服务id后,调用指定tag的职责链方法
public Object run() throws ZuulException {
String serviceId = getServiceId();
if(StringUtils.isBlank(serviceId)){
return null;
}
serviceLancherHandlerChain.handle(serviceId);
return null;
}
FeignRibbonFilterInterceptor.class
// 拦截 FeignClient 在feign远程调用前指定调用指定tag的职责链方法,调用后清除
@Pointcut("@within(org.springframework.cloud.openfeign.FeignClient)")
// PS 需实现 RequestInterceptor,将需要的requestHead在feign进行服务间调用时转发到下一级服务,否则服务间调用将损失前端过来的header
FeignHeadersInterceptor.class
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
Map<String, String> headers = HeaderUtil.getHeaders(request);
if (headers!=null && headers.size() > 0) {
Iterator<Entry<String, String>> iterator = headers.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, String> entry = iterator.next();
template.header(entry.getKey(), entry.getValue());
}
}
// 可根据实际业务需求对转发的header进行增减
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。