Eureka注册中心的设计思想基于满足CAP分布式理论中的AP,某一个service宕机,Eureka server有自我保护机制,不会实时踢掉service,默认会等到3个心跳周期也就是90秒,注册中心才会标记该service下线,所以该service的调用方才能被感知到。
以下方式可以解决客户端在调用某个服务的provider时实时踢掉该服务,并通知Eureka Server,避免LB机制在Hystirx断路器起作用前尽量避免调用已经宕机的服务提供方。
@Slf4j
@Aspect
@Component
public class AAAAspect {
@Autowired
SpringClientFactory springClientFactory;
@Around(value = "execution (* org.springframework.cloud.client.loadbalancer.LoadBalancerClient.reconstructURI(..)))")
public Object reconstructURIAround(final ProceedingJoinPoint joinPoint) throws Throwable {
// log.info(Thread.currentThread().getName()+"$$$$$$$$$$$reconstructURIAround");
Object[] objects = joinPoint.getArgs();
ServiceInstance instance = (ServiceInstance) objects[0];
Server server = new Server(instance.getHost(), instance.getPort());
if (objects != null) {
// iLoadBalancer.markServerDown(server);
}
// springClientFactory.getLoadBalancer(instance.getServiceId());
RibbonLoadBalancerContext context = springClientFactory.getLoadBalancerContext(instance.getServiceId());
ServerStats serverStats = context.getServerStats(server);
Object obj = joinPoint.proceed();
log.info("=======================================================================");
log.info(serverStats.toString());
log.info("=======================================================================");
/**
* 连续网络链接失败2次以上,迅速标记该provider下线
*/
int n = serverStats.getSuccessiveConnectionFailureCount();
if(n > 1){
context.getLoadBalancer().markServerDown(server);
}
return obj;
}
}