SpringCloud五大神兽之Eureka
注册中心概述
什么是注册中心?
相当于服务之间的‘通讯录’,记录了服务和服务地址之间的映射关系。在分布式架构中服务会注册到这里。当服务需要调用其他服务时,就在注册中心找到其他服务的地址,进行调用
注册中心的主要作用?
注册中心一般有以下的功能:
- 服务发现
- 服务注册/反注册:保存服务提供者和调用者的关系
- 服务订阅/取消订阅:服务调用者订阅服务提供者的信息
- 服务路由:筛选整合服务提供者
- 服务配置
- 配置订阅:服务提供者和消费者订阅微服务相关的配置
- 配置下发:主动将配置推送给提供者和消费者
- 服务健康检测
- 检测服务提供者的健康情况
Eureka
Eureka是SpringCloud微服务架构中常用的注册中心,其架构图如下:
由其架构图可以看出,Eureka可以分为三部分:Eureka服务端,Eureka服务提供者,Eureka服务消费者。
其中Eureka服务端需要作为独立的服务运行,而服务提供者、消费者则是需要使用EurekaClient嵌入我们自己的服务中。
其运行原理是这样的:
- 当服务提供者启动时,会向注册中心发送请求,在注册中心注册实例。并且每隔一段时间向注册中心发送心跳,注册中心会保存实例和地址的映射关系
- 当服务消费者启动时,会从注册中心拉去所有的注册信息,并缓存起来。当需要调用某一个服务时。根据缓存的注册信息直接调用服务
聪明的你这个时候会察觉到。既然消费者使用的是缓存的注册信息。那么一定会存在一种情况就是服务提供者这边已经宕机。这个时候消费者根据缓存的信息没有及时更新就会导致调用失败,Eureka是怎么解决这个问题的呢?且往下看。
服务端的搭建
- 创建工程,导入坐标
这里推荐使用 Spring Initializer 直接创建。选择 web 和 euraka 即可。主要引入的依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
- 配置 application.yml ,说明见注释
server:
port: 9000
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false # 是否将自己注册到注册中心
fetch-registry: false # 是否从Eureka中获取注册信息
service-url: # Eureka Client 的请求地址
defaultZone: http://#{eureka.instance.hostname}:#{server.port}/eureka/
- 配置启动类
启动类除了常规的 @SpringBootApplication 外,还要添加 @EnableEurekaServer 表示开启 Eureka 服务
- 启动项目,浏览器访问 localhost:9000 出现以下页面即表示服务搭建成功
注册服务到Eureka
- 在要注册的工程中导入Eureka Client的坐标
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 在 application.yml 中配置Eureka服务端的地址:
这里需要特别注意:Eureka客户端配置的服务端地址使用的key是 defaultZone,不是 default_zone 如果写错会导致客户端无法注册服务,进而导致客户端无法启动
server:
port: 9001
spring:
application:
name: SERVICE_PROVIDER # 服务名称
datasource:
url: jdbc:mysql://192.168.25.128:3306/mysql?characterEncoding=UTF-8&useSSL=false&serverTimezone=CTT
driver-class-name: com.mysql.cj.jdbc.Driver
password: 521
username: keats
eureka:
client:
service-url:
defaultZone: http://localhost:9000/eureka/ # 刚刚在Eureka Server 配置的请求地址
register-with-eureka: true # 注册到注册中心
fetch-registry: false # 作为服务提供者,可以不用从Eureka获取注册信息。视实际情况而定
instance:
prefer-ip-address: true # 使用IP地址注册
- 在启动类加上 @EnableEurekaClient 注解(SpringCloud Finchley.RELEASE 版本及之后的版本会在项目中引入EurekaClient依赖后自动开启,我们使用的是最新版。因此也可以不用添加)
Euraka 客户端默认每隔 30 S向服务端发送一次心跳请求,如果服务端 90 S没有收到某客户端发送的请求将视为客户端宕机。会将其从服务列表剔除
消费者获取和使用服务
搭建服务消费者和提供者的步骤类似,首先是添加 eureka-client 依赖
之后配置 application.yml 如下:
server:
port: 9002
spring:
application:
name: SERVICE_CONSUMER # 服务名称
eureka:
client:
service-url: # 刚刚在Eureka Server 配置的请求地址
defaultZone: http://localhost:9000/eureka/
fetch-registry: true
register-with-eureka: false
这样该服务就具备了从Eureka获取服务的能力,那具体怎么使用呢?
Spring 为我们提供了一个Bean:DiscoveryClient (注意需要导入:org.springframework.cloud.client.discovery 包下的DiscoveryClient 而不是 netflix 包下的类)
我们在需要获取服务的类里面注入该类
@Autowired
private DiscoveryClient discoveryClient;
接着调用其 getInstances(String instancdName) 方法,通过服务的名称获取服务列表。我们这里只注册了一个服务提供方没有搭集群所以直接使用列表第0位的服务实体。而实体提供了 getUri() 方法用于获取服务提供者的 url。接着我们用该方法替换硬编码的 url 即可完成 Eureka 的使用。核心代码如下:
网上的很多其他教程在这里使用的都是 getHost() + ":" + getPort() 拼接,推测可能是版本比较老旧。新API既然已经提供了 getUri() 方法我们就要积极使用。这里建议读者们在使用某Bean的方法时通过打点的方式阅读一下其开放的API,大概了解一下
@GetMapping("teacher/users")
public List<User> getAllUser(){
List<ServiceInstance> service_provider = discoveryClient.getInstances("SERVICE_PROVIDER");
ServiceInstance serviceInstance = service_provider.get(0);
return restTemplate.getForObject(serviceInstance.getUri() + "/api/v1/users", List.class);
}
Eureka的自我保护
如上图提示,表示Eureka进入了自我保护模式。自我保护模式的介绍如下:
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否高于 85%,如果高于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期。在我看来可以用一句古成语来形容这种模式---“三人成虎” 即当越来越多的服务提供者心跳不能到达时。Eureka开始不在怀疑是提供者GG,而怀疑自己了!
在开发环境中,我们往往启动一个Eureka服务 + 一个 Eureka 提供者,如果此时提供者正好出了问题。90S未发送心跳。但由于满足自我保护条件(这段时间失败比例为100%),Eureka不会将服务剔除。会直接导致服务消费者无法正确获取服务。因此开发环境中建议关闭其自我保护机制,而在生产环境打开之, yml 配置如下:
eureka:
server:
enable-self-preservation: false # 关闭自我保护
Eureka集群
我给项目搭建了Eureka注册中心,和配套的服务提供方与服务消费方。完成了服务的灵活调用。从此我们可以将项目中的各个模块都拆分成微服务,注册到注册中心相互调用。但此做法在带来便利性的同时,也为我们带来的隐患:如果Eureka宕掉,怎么办?
解决办法就是搭建Eureka集群,一个Eureka倒下了,还有另一个Eureka兄弟顶着。那如何搭建Eureka集群呢?
这个问题Spring已经帮我们解决了。通过 Eureka 服务端之间相互注册的方式,Eureka 服务端就会互相同步注册信息,好兄弟嘛,你的就是我的,我的也是你的。
我在项目中用 SpringProfile 来模拟 Eureka 集群的运行,具体的操作方法见SpringProfile轻松切换多环境配置文件:
- 首先在修改两个 yml 文件的端口,避免端口冲突
- 打开 Eureka 服务将自己注册到服务的开关、打开 Eureka 服务从服务获取注册信息的开关
- 配置对方的服务地址
- 启动两个 Eureka 服务端
这样就完成了两个Eureka服务端的搭建。此时有任何一个服务端收到服务注册,都会同步到另一个。所以理论上我们可以将服务端注册到其中任何一个,但是为了保险起见。我们还是将服务注册到每个Eureka上。实现方法就是将 defaultZone 的值填写多个Eureka的地址,用逗号隔开
其他优化项目
在控制台显示服务的IP
eureka:
instance:
prefer-ip-address: true # 使用IP地址注册
instance-id: ${spring.cloud.client.ip-address}:${server.port} # 自定义注册ID为ip:端口的格式
修改服务剔除时间
默认情况下,服务提供者每隔30S会发送一次心跳到Eureka服务端,且在90S内未接收心跳才会剔除服务。开发阶段来说这个优点长了。可通过以下配置修改
eureka:
instance:
prefer-ip-address: true # 使用IP地址注册
instance-id: ${spring.cloud.client.ip-address}:${server.port} # 自定义注册ID为ip:端口的格式
lease-renewal-interval-in-seconds: 5 #发送心跳的间隔
lease-expiration-duration-in-seconds: 10 #续约到期时间
SpringCloud五大神兽之Eureka的更多相关文章
- Spring Cloud中五大神兽总结(Eureka/Ribbon/Feign/Hystrix/zuul)
Spring Cloud中五大神兽总结(Eureka/Ribbon/Feign/Hystrix/zuul) 1.Eureka Eureka是Netflix的一个子模块,也是核心模块之一.Eureka是 ...
- SpringCloud分布式开发五大神兽
SpringCloud分布式开发五大神兽 服务发现——Netflix Eureka 客服端负载均衡——Netflix Ribbon 断路器——Netflix Hystrix 服务网关——Netflix ...
- SpringCloud初体验之Eureka
Eureka简介 SpringBoot简化了Spring工程的复杂度,之前复杂的Spring工程被拆分成了一个个小的SpringBoot工程.那么SpringBoot之间如何通讯,相互获取信息呢?这就 ...
- springcloud微服务实战:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin
相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...
- SpringCloud服务发现(Eureka)简介
Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能. 为什么要使用Eure ...
- springcloud微服务实战:Eureka+Zuul+Ribbon+Hystrix+SpringConfig
原文地址:http://blog.csdn.net/yp090416/article/details/78017552 springcloud微服务实战:Eureka+Zuul+Ribbon+Hyst ...
- 小D课堂 - 新版本微服务springcloud+Docker教程_3-04 SpringCloud微服务核心组件Eureka介绍和闭源后影响
笔记 4.SpringCloud微服务核心组件Eureka介绍和闭源后影响 简介: SpringCloud体系介绍 官方地址:http://projec ...
- SpringCloud基础概念学习笔记(Eureka、Ribbon、Feign、Zuul)
SpringCloud基础概念学习笔记(Eureka.Ribbon.Feign.Zuul) SpringCloud入门 参考: https://springcloud.cc/spring-cloud- ...
- Spring-Cloud(三)Eureka注册中心实现高可用
前言: spring-cloud为基础的微服务架构,所有的微服务都需要注册到注册中心,如果这个注册中心阻塞或者崩了,那么整个系统都无法继续正常提供服务,所以,这里就需要对注册中心进行集群,换言之,高可 ...
随机推荐
- Linux下Docker的安装与使用
yum安装Docker最新版和docker-compose(超级简单的安装方法) Install Docker 首先安装依赖 yum install -y yum-utils device-mappe ...
- 【linux学习笔记】
网上看一个两小时突击linux的教程,就想补充一下linux的知识.想着一天抽出俩小时立马就能学完呢,结果乱七八糟的事情拖了四五天,实际完成某项任务的时间超出预期完成任务的两部不止.好了," ...
- .NET 在云原生时代的蜕变,让我在云时代脱颖而出
.NET 生态系统是一个不断变化的生态圈,我相信它正在朝着一个伟大的方向发展.有了开源和跨平台这两个关键优先事项,我们就可以放心了.云原生对应用运行时的不同需求,说明一个.NET Core 在云原生时 ...
- P1850 换教室 期望dp
P1850 换教室 题目描述 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程. 在可以选择的课程中,有 2n2n 节课程安排在 nn 个时间段上.在第 ii(1 \leq ...
- go slice与函数传值的理解
go语言中所有的传值方式都是传值操作. 今天遇到了以下代码: func main(){ slice := make([],) fmt.Println(slice) change(s) fmt.Prin ...
- Java入门 - 导读
原文地址:http://www.work100.net/training/java 更多教程:光束云 - 免费课程 Java入门 Java 是由 Sun Microsystems 公司于1995年5月 ...
- Java单体应用 - Markdown - 02.基础语法
原文地址:http://www.work100.net/training/monolithic-markdown-basic.html 更多教程:光束云 - 免费课程 基础语法 序号 文内章节 视频 ...
- NOI2.5 4980:拯救行动
描述 公主被恶人抓走,被关押在牢房的某个地方.牢房用N*M (N, M <= 200)的矩阵来表示.矩阵中的每项可以代表道路(@).墙壁(#).和守卫(x). 英勇的骑士(r)决定孤身一人去拯 ...
- Java Swing图形界面开发
本文转自xietansheng的CSDN博客内容,这是自己见过的最通俗易懂.最适合快速上手做Java GUI开发的教程了,这里整合一下作为自己以后复习的笔记: 原文地址:https://blog.cs ...
- requests快速构造请求头的方法
上图请求头内容,内容多不说,也不确认哪些数据是必须的,网上找到一个懒办法 快速一键生成 Python 爬虫请求头 实战演练 抓取网站:https://developer.mozilla.org... ...