目录
1.SpringCloud简介
2. Eureka注册发现中心
2.1 Eureka简介
2.2 Eureka的处理机制
2.2.1 Register——服务注册
2.2.2 Renew——服务续约
2.2.3 Eviction——服务剔除
2.2.4 Cancle——服务下线
2.3 Eureka的配置文件
2.4 创建第一个Eureka项目
2.5 Eureka服务注册源码分析
2.6 Eureka服务部署
2.7 Eureka服务发现
3.总结
1.SpringCloud简介
SpringCloud是微服务技术的一种具体实现,它为开发者提供了即为简便的脚手架来快速的搭建分布式的应用系统。并且这些应用系统能够在大多数的环境下持续良久运行。完全可以说,SpringCloud在专注于为典型用例提供良好的开箱即用体验上,更提供了涵盖其他用例的扩展机制,在微服务项目、分布式系统中应用十分广泛。SpringCloud的概述图如下:
(由于Spring云的组件众多,因此我们修改了原有的博客编辑规则,之后将按照组件为单位进行博客的编辑总结。)
2. Eureka注册发现中心
2.1 Eureka简介
正如我们上面所说一样,SpingCloud的组件众多,Euraka就是其中的一种。那么这个组件究竟是用来干嘛的呢?为什么会出现呢?我们一起来研究下。
首先,Eureka是Spring云组件NetFlix中的一个分支,也是核心分支之一。它的架构采用了CS的架构方式,包括Eureka客户端和服务器,Eureka的客户端可以有多个并且可以向服务器注册信息。也可以抽象的理解为Eureka的服务器端维护了一张记录了所有client端注册信息的注册表。Eureka在实际生活中的例子就可以理解为下面的这张图:
2.2 Eureka的处理机制
为了能够更好的理解接下来的Eureka配置文件中配置项的含义,我们有必要了解一下Eureka的运行原理以及它的一些运行机制,这将会对我们熟练配置Eureka的配置项提供帮助。下面是Eureka的一些运行机制。
2.2.1 Register——服务注册
Eureka的服务器端在启动时,会将自身也当做客户端注册到服务当中。同样的,其他的Eureka客户端可以配置服务信息将自己的一些元数据注册到当前服务中,这些元数据包含例如Eureka客户端的IP信息、端口信息、URL链接信息、实例ID等等。Eureka的服务器会有一张服务表(具体的数据结构我们在下文阅读源码部分分析)来记录这些客户端的元数据信息,同样也能根据应用场景对维护的Eureka客户端元数据进行维护,充分发挥其自己注册中心的作用。如下图所示:
2.2.2 Renew——服务续约
在注册中心的运行过程中,可能会出现某些服务由于异常情况死亡或者休眠的情况,这个时候这些异常的服务就不能继续对外提供服务,那么Eureka服务怎么判断哪些应用正常来继续维护服务,或者哪些应用异常来剔除该服务呢?这就是此处的服务续约。服务续约值得是在Eureka客户端注册后,客户端会按照30秒的间隔向服务器传递一条消息来告诉Eureka服务器自己仍然存活,这条消息就是我们所指的心跳;如果某个服务在一端时间内没有向服务传递心跳,Eureka就认为该应用处于影长状态,就将其从服务列表中剔除。这就是所谓的服务续约。
2.2.3 Eviction——服务剔除
这就是我们在上面说的当某个客户端在一段时间内不再继续续约时即某个应用处于异常状态时,Eureka服务剔除当前客户端应用的机制。也称为被动剔除。
2.2.4 Cancle——服务下线
与Eviction被动剔除相对,这是指Eureka应用在正常下线时向Eureka服务发送通知,是的Eureka服务从维护的应用表中将其剔除的机制。由于是由Eureka客户端发起的,因此也称为主动剔除。
2.3 Eureka的配置文件
对上面Eureka运行机制进行了解后,我们再来看配置文件,想必这时对于其中的一些配置项的作用会更加清晰。Eureka配置文件的配置类别分为三个模块:
- Eureka-Server端的配置项
- Eureka-Client端的配置项
- Eureka-Instance实例配置项
其中,Server端的配置项主要配置Eureka服务器端某些机制的作用时间、作用范围等例如配置客户端的续约时间间隔、续约百分比等;Client端的配置项主要用来配置连接的Eureka服务的链接信息例如Eureka服务的URL以及是否拉去服务器维护的服务列表到本地以及拉取服务列表的间隔时间等;Instance实例端的配置项主要配置应用实例的相关信息例如实例的ID、IP地址显示的配置、实例的名称以及续约的时间间隔等等。
在这里我们记录Eureka常用的配置项:
# Eureka服务端的常用配置 server: port: 8761 # 配置Eureka服务的端口 spring: application: name: eureka-server # 配置Eureka服务的名称 eureka: server: # Eureka-Server配置项 eviction-interval-timer-in-ms: 10000 # 定期剔除没有续约的应用的时间间隔 renewal-percent-threshold: 0.85 # 配置服务器的续约百分比,当续约时间间隔内没有收到超过85%的应用的续约消息时,不会剔除任何一个服务 instance: #Eureka-Instance配置项 instance-id: ${spring.application.name}:${server.port}:${eureka.instance.hostname} # 显示在Eureka服务器上的应用实例的名称 hostname: 127.0.0.1 # 应用实例的主机名 prefer-ip-address: true # 以IP的形式显示具体的应用实例请求信息 lease-renewal-interval-in-seconds: 5 # 向Eureka服务器续约的时间间隔,应当小于服务器剔除服务的时间间隔
# Eureka客户端常用配置 server: port: 8762 # 服务的端口号 spring: application: name: server-client-r1 # eureka服务的应用实例名称 eureka: client: service-url: defaultZone: http://localhost:8761/eureka # 配置eureka服务的url连接信息 register-with-eureka: true # 配置实例是否向eureka服务中注册 fetch-registry: true # 是否拉取Eureka维护的服务列表到本地 registry-fetch-interval-seconds: 10 # 为了缓解拉取本地服务列表的脏读问题,这里可以配置拉取服务列表的间隔时间 instance: instance-id: ${spring.application.name}:${server.port}:${eureka.instance.hostname} hostname: localhost prefer-ip-address: true lease-renewal-interval-in-seconds: 5
2.4 创建第一个Eureka项目
2.5 Eureka服务注册源码分析
在上面,我们提到Eureka服务器维护的是一个应用服务列表来保存应用提供服务的信息。那么Eureka服务是怎么对外提供服务列表也就是应用的注册呢?这张“表”结构有事怎样的呢?欲知详情,就来看下源码中是怎么说的吧!
- Eureka客户端请求注册源码
- Eureka服务器端接收请求添加应用实例信息源码
2.6 Eureka服务部署
由于在今后使用的过程中我们都需要频繁的创建和启动Eureka项目,于是便决定将其部署在我们的服务器上来方便我们今后Eureka应用实例的注册。这里我们采用Docker部署的方式。
Docker部署应用程序的步骤:
- 打jar包。这里我们借助的是Maven项目构建工具来进行。
- 创建Dockerfile配置文件。
- 编写run.sh脚本。
- 在服务器创建目录并赋权指令文件,运行脚本。
2.7 Eureka服务发现
所谓Eureka服务发现指的就是Eureka的某个实例通过Eureka服务中的注册信息表来获取到其他Eureka实例的信息入ip地址和端口等的过程。那么,Eureka客户端改如何进行服务发现呢?
Eureka为我们提供了一个用于服务发现的一斤封装好的EurekaDiscoveryClient类,并且在Spring容器启动时完成了注入。我们借助这个帮手就可以完成服务发现:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.List; @RestController public class EurekaController { @Autowired private EurekaDiscoveryClient eurekaDiscoveryClient; @GetMapping("/dis_euclient") @ResponseBody public String doDiscovery(String serviceName) { if (serviceName == null) { return "参数错误"; } HashMap<String, Object> response = new HashMap<>(); List<ServiceInstance> instances = eurekaDiscoveryClient.getInstances(serviceName); //这里获取到的是一个列表是因为eureka客户端可能是一个集群 instances.forEach(System.out::println); //遍历输出服务列表实例信息 ServiceInstance serviceInstance = null; if (instances.size() > 0) { serviceInstance = instances.get(0); System.out.println(serviceInstance.getHost() + ":" + serviceInstance.getPort()); response.put("response", serviceInstance); } return response.toString(); } }
3.总结
Eureka是SpringCloud的组件之一,为微服务项目能够成功搭建起来并高效可靠运行起到了重要作用。它是一个基于BS架构搭建起来的注册和发现中心,Eureka的服务器在内存中维护了一个ConcurrentHashMap<String,Map<String,Lease<InstanceInfo>>>类型的实例对象来维护我们创建的Eureka客户端实例信息,也通常抽象的理解为Eureka服务器中维护的一张“应用注册表”。其中,第一层key值为应用实例的名称AppName,第二层key值为应用编码InstanceId,通过第二层key值获取到的Lease对象中就维护了对应Eureka应用的实例信息。
Eureka服务通过WEB协议提供接口供客户端来注册实例信息,同时为了能够保证维护的实例信息的有效性,于是引出了服务续约的机制;同时为了能够保证应用注册表中的实例信息的有效性,又有了服务剔除和服务下线这样的机制。正是这些诸多的服务处理机制,才能使得我们的Eureka注册发现中心高效可靠的运行着这也是Eureka能够担任其注册发现中心重任的一条重要原因!
ps.下一篇blog我们将会学习并总结:分布式数据一致性协议raft和Spring的restTemplate框架。