集群下EurekaClient连接EurekaServer节点的策略

eureka server集群部署的情况下,eureka-client通信的时候是如何选择的?

源码在这个类里边

com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient#execute

protected <R> EurekaHttpResponse<R> execute(RequestExecutor<R> requestExecutor) {
	List<EurekaEndpoint> candidateHosts = null;//注册中心地址列表
	int endpointIdx = 0;
	for (int retry = 0; retry < numberOfRetries; retry++) {
		EurekaHttpClient currentHttpClient = delegate.get();//获取上次保存的注册中心的地址
		EurekaEndpoint currentEndpoint = null;
		if (currentHttpClient == null) {
			if (candidateHosts == null) {
				candidateHosts = getHostCandidates();
				if (candidateHosts.isEmpty()) {
					throw new TransportException("There is no known eureka server; cluster server list is empty");
				}
			}
			if (endpointIdx >= candidateHosts.size()) {
				throw new TransportException("Cannot execute request on any known server");
			}
			currentEndpoint = candidateHosts.get(endpointIdx++);//获取第endpointIdx个注册中心的地址
			currentHttpClient = clientFactory.newClient(currentEndpoint);
		}
		try {
			EurekaHttpResponse<R> response = requestExecutor.execute(currentHttpClient);
			if (serverStatusEvaluator.accept(response.getStatusCode(), requestExecutor.getRequestType())) {
				delegate.set(currentHttpClient);//请求成功将这此次的通讯的注册中心存储到AtomicReference
				if (retry > 0) {
					logger.info("Request execution succeeded on retry #{}", retry);
				}
				return response;//返回
			}
			logger.warn("Request execution failure with status code {}; retrying on another server if available", response.getStatusCode());
		} catch (Exception e) {
			logger.warn("Request execution failed with message: {}", e.getMessage());  // just log message as the underlying client should log the 
		}
		// Connection error or 5xx from the server that must be retried on another server
		delegate.compareAndSet(currentHttpClient, null);//请求失败会通过cas将上次保存的注册中心地址给置null,然后进行重试
		if (currentEndpoint != null) {
			quarantineSet.add(currentEndpoint);
		}
	}
	throw new TransportException("Retry limit reached; giving up on completing the request");//达到重试上限还没有请求成功就抛出异常
}

1.从delegate里边获取上次保存的注册中心的地址
2.当获取不到是,从candidateHosts获取第endpointIdx个注册中心的地址(初始化默认是0号索引)
3.进行通信
4.请求成功会将此次通信的注册中心的地址保存到delegate里边,方便下次直接使用
5.完成后返回
6.如果再第4步的时候报错了,就会把delegate保存的数据置空,继续进行重试。继续走一下1,2,3,4,5。
7.达到重试上限就会抛出异常

你可能感兴趣的:(eureka,spring,cloud)