女主宣言
本文出自于 ADDOPS 团队,该文章的作者李东主要负责 Wonder 监控平台和 Furion 代码发布平台的开发。之前我们已经在公众号里介绍了 Spring Cloud 和微服务架构,接下来我们就跟随作者具体看看如何使用 Spring Cloud Eureka 实现服务治理。本文最先发布于 opsdev,转载已获取作者授权。
PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!
前言
众所周知,服务发现必须同时具备高可用性和高弹性。
先举个例子,当调用 API 或者发起网络通信的时候,我们需要知道被调用方的服务IP和端口或者通过域名和端口,事实上这种方法就是基于 DNS 的服务发现。但由于 DNS 缓存、无法自治和其它不利因素的存在,目前该机制还存在很多问题和缺陷。传统的 DNS 方式都是通过 Nginx 或者其它代理来实现,物理机的 IP 和 port 都是固定的,所以 Nginx 中配置的 IP 和 port 也就是固定的,此时服务列表更新只能通过人工来做。但如果后端服务很多,手动更新不仅效率很低,而且还容易出错。并且在后端发生故障时,服务不可用时间就可能加长。甚至在一些服务中 (如 Docker ),IP、port 和服务实例数都是动态变化的,所以就需要精细而准确的服务发现机制。
Eureka 就是为服务发现所设计的。
1
Eureka 是什么
Eureka 是 Netflix 开源的一个 RESTful (代表性状态传输) 服务,主要用于服务注册与发现。Eureka由两个组件组成:Eureka 服务器和 Eureka 客户端。Eureka 服务器用作服务注册服务器;Eureka 客户端是一个 Java 客户端,用来简化与服务器的交互、作为轮询负载均衡器,并提供服务的故障切换支持。其主要特点如下:
开源
可靠
功能齐全
基于 Java
Spring Cloud 集成
2
Eureka 的几个重要概念
Register (服务注册)
当 Eureka 客户端向 Eureka Server 注册时,它提供自身的元数据,如 IP、port、运行状况、URL 和主页等。
Renew (服务续约)
Eureka Client 每隔30秒发送一次心跳来完成续约。 Eureka Client 通过续约来告知 Eureka Server 自己仍然存在,没有任何问题。正常情况下,如果 Eureka Server 在90秒内没有收到 Eureka Client 的续约,那么它会将实例从其注册表中删除。 此间隔时间建议用户不要更改。
Get Registry (获取注册表信息)
Eureka Client 从 Eureka Server 获取注册表信息,并将其缓存到本地。Eureka Client 和 Eureka Server 间支持 JSON/XML 格式进行通讯。默认压缩 JSON 格式。
Cancel (服务下线)
Eureka Client 在程序关闭时向 Eureka 服务器发送取消请求。发送请求后,该客户端实例信息将从服务器的实例注册表中删除。
3
Eureka 高可用架构
下图是 Eureka 官方提供的架构图:
由图可以看出,架构中主要3种角色:
Eureka Server:通过 Register、Get、Renew 等接口提供服务注册和发现功能
Application Service:服务提供方,把自身服务实例注册到 Eureka Server
Application Client:服务调用方,通过 Eureka Server 获取服务实例,并调用 Application Service
处理流程
每个区域有一个 Eureka Cluster,每个区域的可用区中至少有一个 Eureka Server。
Application Service 作为 Eureka Client,通过register 注册到 Eureka Server,并通过发送心跳的方式进行续约,如果90秒内没有进行续约,Eureka Server 将会移除该 service 实例。
当一个 Eureka Server 收到数据或数据发生改变后,会将自己的数据同步到其它 Eureka Server中。
Application Client 也作为 Eureka Client 通过get 接口从 Eureka Server 中获取 Application Service 实例信息。
Application Client 通过模块内的负载均衡机制调用 Application Service,同时可以跨区域调用。
Application Client 可以从 Eureka Server 获取到 Application Service 的注册信息表,并缓存到本地。之后,客户端使用该信息查找其它 Application service, 这些信息通过获取最后一次读取周期和当前读取周期之间的增量信息来进行每30秒一次的定期更新,增量信息在 Eureka Server 中保存较长时间,约3分钟。因此,增量获取可能会再次返回相同的实例,Eureka Client 会自动处理重复的信息。获得增量信息后,Eureka Client 通过比较 Eureka Server 返回的实例数来与 Eureka Server 进行协调,如果信息由于某种原因不匹配,则会重新提取整个注册表信息。来自 Eureka Client 客户端的所有操作可能都需要一段时间才能反映在 Eureka Server 中,随后在其他 Eureka Server 中反映。这是因为 Eureka Server 上的有效载荷的缓存,它定期刷新以反映新的信息。而 Eureka Client 也会定期获取增量信息,因此可能需要2分钟才能将更改传播给所有的 Eureka Client. 由于 Eureka Client 已将有关可用服务的信息缓存在本地,因此程序可以灵活地选择经过负载均衡处理的终端,虽然该机制会占用少量内存,但却拥有了更好的弹性。
模式介绍
Eureka Server 采用的是对等通信 (P2P),一种无中心化架构,没有 master/slave 之分,每一个 server 都是对等的,既是 Server 又是 Client,所以其集群方式可以自由发挥,可以各点互连,也可以接力互连。例如,Eureka Server 间的架构可以设计如下:
Eureka Server 通过运行多个实例以及彼此之间互相注册来提高可用性,每个节点需要添加一个或多个有效的 serviceUrl 指向另一个节点。
Eureka 采用的是客户端发现模式,其优点是服务调用、负载均衡都不需要和 Eureka Server 进行通信,直接使用本地注册表副本,因此 Eureka Server 不可用时是不会影响正常的服务调用,性能也不会因为网络延迟和服务端延迟受到影响。但该机制也有其缺点,即当某个 Application Service 不可用时,Eureka Client 不能及时获悉,可能需要1到3个心跳周期才能知晓。针对该问题,我们可以根据实际使用情况采用相应的熔断和降级机制进行弥补。如 Netflix 就是服务端使用 Hystrix 来容错和降级。
4
Eureka搭建和部署
环境准备
VMWare虚拟机
CentOS 7
Git
Grade
Tomcat
步骤
1. 安装 Git、Grade 和 Tomcat
2. 构建 Eureka
git clone https://github.com/Netflix/eureka.git
cd eureka/
./gradlew clean build
3. 部署 Eureka Server
/usr/local/tomcat/bin/shutdown.sh
cp eureka-server-1.1.134.war /usr/local/tomcat/webapps/eureka.war
/usr/local/tomcat/bin/startup.sh
4. 通过 URL 即可进行访问和查看相应信息。
5
总结
目前,在实际工作中使用 Eureka 的例子很少,其在微服务和 Spring cloud 中应用较为广泛。因为 Spring Cloud 集成了 Eureka,并提供开箱即用的支持。
扫描下方二维码了解更多内容