在Eureka - Client服务启动我们看到,注册表获取的地方有两个,一个是EurekaClient构造函数,一个是定时器每隔30秒去获取。我们先看看定时器TimedSupervisorTask的run方法
定时器
这个方法有三个比较重要的参数,timeoutMillis、delay、maxDelay。比如频率是30s,那这个maxDelay就是30*10=300s(这个10的来源参考上一篇),delay在这里是每次都翻倍,但是不能比maxDelay大。
整个设计思路是,如果调用30s超时,那就用60秒,如果再超时,就一直翻,但是不能超过300s。如果在后面的调用中正常了,那delay就恢复到30s,下次超时继续翻倍。@Override
public void run() {
Future> future = null;
try {
// 执行任务
future = executor.submit(task);
threadPoolLevelGauge.set((long) executor.getActiveCount());
// 指定超时时间
future.get(timeoutMillis, TimeUnit.MILLISECONDS); // block until done or timeout
//设置delay
delay.set(timeoutMillis);
threadPoolLevelGauge.set((long) executor.getActiveCount());
successCounter.increment();
} catch (TimeoutException e) {
logger.warn("task supervisor timed out", e);
timeoutCounter.increment();
// 获取delay
long currentDelay = delay.get();
// maxDelay和currentDelay的2倍中取最小值
long newDelay = Math.min(maxDelay, currentDelay * 2);
// 设置为上面最小值
delay.compareAndSet(currentDelay, newDelay);
} catch (RejectedExecutionException e) {
// 其他的略
rejectedCounter.increment();
} catch (Throwable e) {
// 其他的略
throwableCounter.increment();
} finally {
if (future != null) {
future.cancel(true);
}
// 把任务放入定时器,时间是delay
if (