zuul是被spring集成在spring-cloud項(xiàng)目下的鬓照,一般都會(huì)配合eureak使用
eureka-client包中藕赞,在DiscoveryClient初始化的時(shí)候,默認(rèn)會(huì)開(kāi)啟一個(gè)定時(shí)器亿遂,每隔30秒發(fā)布一個(gè)HeartbeatEvent事件浓若,而ZuulRefreshListener會(huì)監(jiān)聽(tīng)這個(gè)事件,然后調(diào)用ZuulHandlerMapping.setDirty(true);
所以蛇数,RouteLocator的refresh時(shí)間不能太長(zhǎng)挪钓,不然后果很?chē)?yán)重
如果refresh結(jié)束之前,dirty值已經(jīng)被改成false耳舅,當(dāng)時(shí)確實(shí)更新的route不會(huì)生效碌上,但是會(huì)在下一個(gè)HeartbeatEvent事件發(fā)布后生效
如果,需要在refresh之后浦徊,立刻生效馏予,也可以通過(guò)aop+反射來(lái)解決這個(gè)問(wèn)題
private Logger logger = LoggerFactory.getLogger(CompositeRouteAop.class);
@Resource
private ZuulHandlerMapping handlerMapping;
@Pointcut("execution(* org.springframework.cloud.netflix.zuul.filters.CompositeRouteLocator.refresh(..))")
public void pointCut() {
}
@Around("pointCut()")
public Object resetDirty(ProceedingJoinPoint joinPoint) throws Throwable {
Object proceed = joinPoint.proceed(joinPoint.getArgs());
try {
Field dirty = ZuulHandlerMapping.class.getDeclaredField("dirty");
dirty.setAccessible(true);
dirty.setBoolean(handlerMapping, true);
} catch (Throwable e) {
logger.error("reset zuulHandlerMapping dirty value error after refresh route", e);
}
return proceed;
}