一、问题的由来在SpringCloud架构体系中,Eureka是一个至关重要的组件,它扮演着微服务注册中心的角色,所有的服务注册和服务发现都依赖于在尤里卡。很多刚接触SpringCloud的朋友在落地公司生产环境部署的时候经常会问:EurekaServer需要部署多少台机器?我们系统中有这么多的服务,对EurekaServer会有多大的访问压力呢?EurekaServer能否承受大型系统的访问压力?如果你也有这些疑问,别担心!一起来看看吧。Eureka作为微服务注册中心的核心原则是以下几个问题。我们先来看看,有个大概的印象。带着这些疑问,再看下面的内容会事半功倍。Eureka注册中心是用什么方法存储每个服务注册时发送的机器地址和端口号的?每个服务请求EurekaServer拉取注册中心的频率是多少?每个服务如何拉取注册表?一个拥有数百个服务、上千台机器的大型分布式系统部署在EurekaServer上会有多大的访问压力?EurekaServer如何从技术角度抗住数千万级的日访问量?先说一个基础知识点。默认情况下,每个服务中的EurekaClient组件会每隔30秒向EurekaServer发送一次请求,拉取最近发生变化的服务信息。例如:库存服务原来部署在1台机器上,现在扩容,部署到3台机器上,全部注册到EurekaServer。然后订单服务的EurekaClient会每隔30秒去EurekaServer拉取最新的注册表变化,看看其他服务的地址有没有变化。另外,Eureka还有心跳机制。每个EurekaClient都会每隔30秒向EurekaServer发送一次心跳,通知其他人,哥们,我的服务实例还活着!如果某个EurekaClient长时间没有向EurekaServer发送心跳,则说明该服务实例已经挂了。光看上面的文字,你可能没有太多印象。老规矩!来一张图,一起来直观感受一下这个过程吧。2.EurekaServer设计精巧的注册中心存储结构现在假设我们手头有一个大型的分布式系统,一共有100个服务,每个服务部署在20台标准配置为4核8G的机器上。也就是说,你总共部署了100*20=2000个服务实例和2000台机器。每台机器上的服务实例内部都有一个EurekaClient组件,它会每隔30秒请求EurekaServer拉取变化的registry。此外,每个服务实例上的EurekaClient会每隔30秒向EurekaServer发送一次心跳请求。那么我们算一算,作为微服务注册中心的EurekaServer每秒会被请求多少次呢?你一天要被要求多少次?按照标准算法,每个服务实例每分钟请求拉取注册中心两次,每分钟请求发送两次心跳。这样一个服务实例每分钟会请求4次,2000个服务实例每分钟会请求8000次。换算成每秒,大概是8000/60=133次,我们粗略估计EurekaServer每秒会被请求150次。那一天就是8000*60*24=1152万,也就是说每天有几千万的访问量。好的!经过这么一算,你发现这里的奥秘了吗?首先,对于微服务注册中心这样的组件,在设计它的拉取频率和心跳发送频率时,已经考虑了一个大系统每次服务请求的压力,每秒会承载多少请求。所以每个服务实例每30秒发起一次拉取变化的registry的请求,每30秒向EurekaServer发送一次心跳。其实这个时机是有目的的。根据我们的计算,一个有数百个服务、上千台机器的系统以这样的频率请求EurekaServer,每天的请求量在千万级别,每秒??的访问量在150次左右。即使算上其他一些额外的操作,我们也只是每秒询问EurekaServer200到300次。因此,通过设置合适的拉取注册中心和发送心跳的频率,可以保证在大型系统中EurekaServer的请求压力不会太大。关键问题是,EurekaServer如何保证能够轻松抵御每秒数百次请求和每天数千万次请求?要想搞清楚这个问题,我们首先要了解EurekaServer是用什么来存储注册表的?三个字,看源码。接下来我们进入Eureka源码一探究竟:如上图所示,图中名为registry的CocurrentHashMap是registry的核心结构。看完后,不禁先赞叹一下,精美的设计!从代码中可以看出,EurekaServer的注册中心是直接基于纯内存的,即在内存中维护了一个数据结构。每个服务的注册、服务下线、服务失败都会在内存中维护和更新这个注册表。当每个服务每30秒拉取注册表时,EurekaServer只是向它们提供存储在内存中的更改后的注册表数据。同样,当每30秒发起一次心跳时,心跳时间也会在这个纯内存的Map数据结构中更新。一句话总结:维护注册表,拉取注册表,更新心跳时间,都发生在内存中!这是EurekaServer非常核心的一点。搞清楚了这个,我们再分析一下registry的数据结构。不要被它复杂的外表所迷惑,静下心来一层层分析吧!首先这个ConcurrentHashMap的key就是服务名,比如“inventory-service”,就是一个服务名。值表示一个服务的多个服务实例。例子:比如“inventory-service”可以有3个服务实例,每个服务实例部署在一台机器上。我们看一下Mapasvalue:Map
