eureka是SpingCloud中服务注册与发现的组件,有server端和client端。
eureka server是有管理界面的,当client向server注册时,会提供一些元数据,例如主机和端口、url、主页等,eureka server从每个client实例接收心跳信息,如果心跳超时,则通常将该实例从注册server中删除。
1 eureka server
server有一个注册表,保存了各个服务所在的机器和端口号,注册表采用Map数据结构。
在启动类上添加注解@EnableEurekaServer
,并配置eureka server application.yml
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegister: false
serviceUrl:
defaultZone:http://${eureka.instance.hostname}:${server.port}/eureka
通过registerWithEureka: false
和 fetchRegister: false
表明自己是一个eureka server。
2 eureka client
负责将这个服务的信息注册到eureka server中。
在启动类上添加注解@EnableEurekaClient
,并配置application.yml
server:
port: 8762
spring:
application:
name:server-hi
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
3 eureka源码
- eureka采用什么方式来存储各个服务发送过来的元数据
- 各服务找eureka server拉取注册表的时候,频率是怎样的
- 一个几百服务,部署上千台机器的大型分布式系统,会对eureka server造成多大的访问压力?
public abstract class AbstractInstanceRegistry implements InstanceRegistry{
private final ConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>();
}
- map的key就是服务实例的id
- lease里面维护者每个服务最近一次发送心跳的时间
- InstanceInfo代表了服务实例的具体信息
各个服务内的eureka client默认情况下,每隔30秒会发送一个请求到eureka server,来拉取最近有变化的服务信息,除此之外,eureka client每隔30秒会发送一次心跳到eureka server,假设有100个服务,部署在20台机器上,则100个服务 * 20台机器 * 4次/分(2次注册表+2次心跳) * 60 * 24 = 1152万访问量/日
。eureka server是如何抗住日千万级的访问量的?
4 多级缓存机制
eureka server为了避免同时读写内存数据结构造成的并发冲突问题,采用了多级缓存机制来提升服务请求的相应速度。
- 在拉取注册表时
- 先从ReadOnlyCacheMap里查缓存的注册表
- 若没有,就找ReadWriteCacheMap里的缓存表
- 如果还没有,就从内存中获取实际的注册表数据
- 在注册表发生变更的时候
- 会从内存中更新变更的注册表数据,同时过期掉ReadWriteCacheMap
- 此过程不会影响ReadOnlyCacheMap查询注册表
- 一段时间内(默认30秒),各服务拉取注册表直接读ReadOnlyCacheMap
- 30秒后,eureka server的后台线程发现ReadWriteCacheMap已经清空了,也会清空ReadOnlyCacheMap中的缓存
- 下次有服务拉取注册表,又会从内存中获取最新的数据了,同时填充各个缓存。
注:上图来自大佬 石杉的架构笔记。
【优点】
- 尽可能保证了内存注册表数据不会出现频繁的读写冲突问题
- 并且进一步保证了eureka server的大量请求,都是快速走纯内存,性能极高
参考文章
结语
本人所有博客仅用于学习记录,不做任何商业用途,如涉及侵权,还请联系删除,感谢阅读,欢迎留言,一起进步~