Eureka
流程图
Eureka Server
三级缓存结构
缓存(类的成员变量) | 变量类型 | 类名称 | 说明 |
---|---|---|---|
registry | ConcurrentHashMap | AbstractInstanceRegistry | 实时更新 |
readWriteCacheMap | Guava Cache/LoadingCache | ResponseCacheImpl | 实时更新 |
readOnlyCacheMap | ConcurrentHashMap | ResponseCacheImpl | 周期更新 |
三级缓存尽可能保证了内存注册表数据 registry 不会出现频繁的读写冲突问题
但同时也会使得服务注册信息有一定的时间延迟,但对于读多写少的场景下,这种结构是十分合适的
说明
- 当服务变更时(服务注册/下线),直接变更 registry,然后使 readWriteCacheMap 失效,30s 后当查询到 readWriteCacheMap 已经失效后,使 readOnlyCacheMap 失效,有服务信息读取时,会以 readOnlyCacheMap->readWriteCacheMap->registry 的顺序查询未失效的数据,并依次填充已经失效的数据
- readOnlyCacheMap默认每隔 30s 从readWriteCacheMap 更新
- EurekaClient 默认从readOnlyCacheMap更新,可以设置为从readWriteCacheMap 直接更新,小规模系统直接从 readWriteCacheMap 更高效
- EurekaServer 集群间从registry 同步数据
Eureka Client
二级缓存结构
缓存(类的成员变量) | 变量类型 | 类名称 | 说明 |
---|---|---|---|
localRegionApps | AtomicReference | DiscoveryClient | 周期更新 |
upServerListZoneMap | ConcurrentHashMap | LoadBalancerStats | 周期更新 |
- localRegionApps 为 EurekaClient 保存服务注册信息,启动后立即向 Server 全量更新,默认每 30s 增量更新
- upServerListZoneMap 为 Ribbon 保存使用且状态为 UP 的服务注册信息,启动后延时 1s 向 Client 更新,默认每 30s 更新
感知延迟时间计算
正常上线和下线
readWrite -> readOnly -> Client -> Ribbon 各 30s
30(readOnly)+30(Client)+30(Ribbon)=90s
非正常的上下线
90s(正常延时)+180s(注册中心服务剔除机制)=270s
优化点
EurekaServer
- 缩短 readOnlyCacheMap 到readWriteCacheMap 的同步周期时间
- 小规模系统可以设置为直接从readWriteCacheMap 同步服务信息
EurekaClient
- 服务通过接口正常下线或者 kill/kill -15 下线,不要通过 kill -9 下线服务
- 缩短 EurekaClient 缓存的同步周期时间
- 服务提供者延迟下线,先通过接口修改 EurekaServer 中服务的状态为 Down,90s 后停止服务,可以做到几乎无延时
- 修改心跳频率有可能会使 Eureka 自我保护模式失效
优化经验
一个上百个服务,几千台机器的系统,按照 30s 频率请求 Eureka Server,日请求量在千万级,每秒的访问量在 150 次左右
由于 Eureka 基于内存,一个 Eureka 实例每秒应付几百的并发没有问题
相关文档
详解 Eureka 缓存机制-infoQ
Eureka 四篇文章解析-oschina
Simple is Awesome