eureka源码分析-DiscoveryClient
2019-03-31 本文已影响0人
leiwingqueen
一、概要
上一篇文章大致分析了eureka的整体流程。eureka client通过一个定时器定时上报心跳信息到eureka server。并且会定时拉取eureka server的服务列表到本地。
这里存在几个问题。
- eureka server之间的数据一致性如何保证?
eureka server是要cp,还是ap? - eureka client和eureka server之间的一致性如何保证?
获取服务列表存在时延,有可能一个已经失效的结点还会在client中保留一段时间,或者一个新加入的结点还没有同步到client。如何解决这种问题?
这篇文章先对eureka client的源码做了解。
二、源码分析
客户端核心的代码在DiscoveryClient。
类关系图
eureka实例在初始化的时候会调用initScheduledTasks的方法,初始化定时任务,这里面就包含定时向eureka server上报心跳的任务。
/**
* Initializes all scheduled tasks.
*/
private void initScheduledTasks() {
...
// Heartbeat timer
scheduler.schedule(
new TimedSupervisorTask(
"heartbeat",
scheduler,
heartbeatExecutor,
renewalIntervalInSecs,
TimeUnit.SECONDS,
expBackOffBound,
new HeartbeatThread()
),
renewalIntervalInSecs, TimeUnit.SECONDS);
...
我们接下来看下心跳告警线程的代码
/**
* The heartbeat task that renews the lease in the given intervals.
*/
private class HeartbeatThread implements Runnable {
public void run() {
if (renew()) {
lastSuccessfulHeartbeatTimestamp = System.currentTimeMillis();
}
}
}
/**
* Renew with the eureka service by making the appropriate REST call
*/
boolean renew() {
EurekaHttpResponse<InstanceInfo> httpResponse;
try {
httpResponse = eurekaTransport.registrationClient.sendHeartBeat(instanceInfo.getAppName(), instanceInfo.getId(), instanceInfo, null);
logger.info("{} - Heartbeat status: {}", PREFIX + appPathIdentifier, httpResponse.getStatusCode());
if (httpResponse.getStatusCode() == 404) {
REREGISTER_COUNTER.increment();
logger.info("{} - Re-registering apps/{}", PREFIX + appPathIdentifier, instanceInfo.getAppName());
return register();
}
return httpResponse.getStatusCode() == 200;
} catch (Throwable e) {
logger.error("{} - was unable to send heartbeat!", PREFIX + appPathIdentifier, e);
return false;
}
}
eureka采用的也是http协议,如果返回404返回码,客户端会选择重新注册信息到eureka server。
http协议报文如下:
Hypertext Transfer Protocol
PUT /eureka/v2/apps/SAMPLEREGISTERINGSERVICE/201709-07262?status=UP&lastDirtyTimestamp=1552742035025 HTTP/1.1\r\n
DiscoveryIdentity-Name: DefaultClient\r\n
DiscoveryIdentity-Version: 1.4\r\n
DiscoveryIdentity-Id: 172.19.10.230\r\n
Accept-Encoding: gzip\r\n
Content-Length: 0\r\n
Host: localhost:8080\r\n
Connection: Keep-Alive\r\n
User-Agent: Java-EurekaClient/v<version_unknown>\r\n
\r\n
[Full request URI: http://localhost:8080/eureka/v2/apps/SAMPLEREGISTERINGSERVICE/201709-07262?status=UP&lastDirtyTimestamp=1552742035025]
[HTTP request 1/1]
[Response in frame: 7296]
。。。to be continued