本文已参与「新人创作礼」活动,一起开启掘金创作之路。
-
eureka server启动以及初始化
-
eureka client启动以及初始化
-
eureka client发送服务实例的注册
-
eureka server接收服务实例的注册
-
eureka client抓取全量注册表
eureka client抓取全量注册表
全量注册表
eureka client启动,从eureka server端抓取全量注册表信息,在本地进行缓存。
增量注册表
每隔30秒从eureka server抓取增量注册表信息,与本地缓存的全量注册表合并
如果配置抓取注册表eureka.shouldFetchRegistry,就会在启动的时候抓取一次全量注册表。
抓取全量注册表
(1)EurekaClient初始化的时候,就会自动抓取全量注册表
(2)先获取本地的Applications缓存(此时是空的)
Applications:就是所有的服务,Applicaiton是一个服务,Applications是所有的服务
Application:包含服务自己的所有的服务实例(InstanceInfo)
application是{appName:[instanceId]}的关系,applications就是[application]的关系
(3)本地的Application缓存是空,调用getAndStoreFullRegistry方法,拉取并缓存全量注册表
(4)调用jersey client(eurekaTransport.queryClient.getApplications()),发送http请求(http://localhost:8080/v2/apps ),GET请求,调用eureka server的getApplications restful接口,获取全量注册表,缓存在自己的本地
eureka server注册表多级缓存机制
eureka server调用ApplicationsResource的getContainers()方法,处理抓取全量注册表的请求。
Accept-Encoding: gzip, deflate ,表示这个请求的响应内容希望被压缩, 如果服务器不支持压缩或者没有开启压缩,则不能起到作用。
Content-Encoding: 如果服务器也是支持压缩或者开启压缩,则会在响应头中加入Content-Encoding: gzip 头部
X-Eureka-Accept:通过调用EurekaAccept.fromString(eurekaAccept)获得客户端接收的是full还是compact
构造Key
cacheKey:全量注册表的缓存key
entityType:缓存值的数据类型(Application, VIP, SVIP)
entityName:缓存值的名称(ALL_APPS, ALL_APPS_DELTA)
requestType:缓存值的序列化类型(json、xml)
requestVersion:缓存值的版本号
eurekaAccept:响应类型
regions:远程服务域
eureka client发送请求读取全量注册表,从多级缓存里去读取注册表的数据
ResponseCache
ResponseCache,就是eureka server端的缓存机制
ApplicationResource构造函数内初始化ResponseCache responseCache = registry.getResponseCache();
responseCache.getGZIP(cacheKey) 或 responseCache.get(cacheKey) 从多级缓存里查询Applications返回。
多级缓存机制(ResponseCache)
只读缓存
ConcurrentMap<Key, Value> readOnlyCacheMap
读写缓存
LoadingCache<Key, Value> readWriteCacheMap;
多级缓存机制:用两个map做两级缓存,只读缓存map,读写缓存map。
先从只读缓存里去读,如果没有的话,会从读写缓存里去读,如果还是没有,会从eureka server的注册表中去读取
为什么使用多级缓存?
避免同时读写内存数据结构造成的并发冲突问题,使写操作不阻塞读操作
当存在大规模的服务注册和更新时,如果只是修改一个ConcurrentHashMap数据,那么势必因为锁的存在导致竞争,影响性能。
而Eureka又是AP模型,只需要满足最终可用就行。所以它在这里用到多级缓存来实现读写分离。注册方法写的时候直接写内存注册表,写完表之后主动失效读写缓存。
获取注册信息接口先从只读缓存取,只读缓存没有再去读写缓存取,读写缓存没有再去内存注册表里取(不只是取,此处较复杂)。并且,读写缓存会更新回写只读缓存