SpringCloud服务注册中心——Eureka
创始人
2024-06-02 21:10:45
0

Eureka

本专栏学习内容来自尚硅谷周阳老师的视频

有兴趣的小伙伴可以点击视频地址观看

简介

Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。

SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。

Eureka现已停更,但停更不停用

基础知识

Eureka包含两个组件:Eureka ServerEureka Client

Eureka Server提供服务注册服务

各个微服务节点通过配置启动后,会在EurekaServer中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。

EurekaClient通过注册中心进行访问

是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳(默认周期为30秒)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中把这个服务节点移除(默认90秒)

单机Eureka

单机Eureka是通过将服务注册到一个Eureka服务中心去,如下图所示

在这里插入图片描述

Eureka服务注册中心

此服务只是一个注册服务,只需要一个启动类+配置文件即可

首先得引入Eureka服务端的依赖

org.springframework.cloudspring-cloud-starter-netflix-eureka-server

接着修改配置文件,因为本身就是注册中心,所以不需要向注册中心去注册自己

server.port=7001#eureka服务端的实例名称
eureka.instance.hostname=localhost
#false表示不向注册中心注册自己。
eureka.client.register-with-eureka=false
#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
eureka.client.fetch-registry=false
#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

最后只需要在启动类上加如下注解

@EnableEurekaServer

启动服务,可以看到Eureka的交互式页面,此处表示还没有服务注册进来

在这里插入图片描述

消费者

在微服务中,经常会有一个服务调用另外一个服务的情况,在这里我们将前者称之为消费者,后者称之为提供者。现在我们需要把消费者也注册到服务中心

首先引入Eureka客户端依赖

org.springframework.cloudspring-cloud-starter-netflix-eureka-client

修改配置文件

server.port=80
spring.application.name=cloud-order-service#eureka
#true表示向注册中心注册自己。
eureka.client.register-with-eureka=true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
eureka.client.fetch-registry=true
#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
eureka.client.service-url.defaultZone=http://localhost:7001/eureka

在启动类上加上如下注解

@EnableEurekaClient

到这一步我们就已经修改完毕,这时候启动消费者,发现此服务已经被注册到服务中心

需要注意的是注册名与spring.application.name相关,一旦定下来,轻易不要修改

在这里插入图片描述

提供者

提供者修改与消费者完全相同,这里就不再赘述,现在我们的工程目录就变成了这个样子

commons是我们的公共包

7001是Eureka服务注册中心

80是消费者

8001是提供者

在这里插入图片描述

集群Eureka

在开发中,我们常常会使用到集群,为了防止Eureka服务注册中心挂掉,会对Eureka进行集群处理。

Eureka集群

以下是我们需要实现的图示,实现集群的关键点在于,两个服务相互注册

在这里插入图片描述

我们根据cloud-eureka-server7001复制一个cloud-eureka-server7002

因为是测试环境在本地,所有的ip都是localhost,为了区分两个服务,可以修改映射配置添加进hosts文件

127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com

接下来我们需要分别修改7001配置文件和7002配置文件,将7001注册进7002的服务中心,反之亦然

#eureka服务端的实例名称
eureka.instance.hostname=eureka7001.com  #修改
#false表示不向注册中心注册自己。
eureka.client.register-with-eureka=false
#false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
eureka.client.fetch-registry=false
#设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
eureka.client.service-url.defaultZone=http://eureka7002.com:7002/eureka/   #修改

分别启动两个注册中心服务,会发现他们已经相互注册成功

在这里插入图片描述

此时,集群已经配置完毕,我们还需要将消费者和提供者分别注册到集群的服务中心

修改两个服务的配置文件即可

eureka.client.service-url.defaultZone=http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka  

至此,我们就完成了Eureka集群的搭建

在这里插入图片描述

多个提供者

在实际开发过程中,为了降低服务压力,还需要实现多个提供者的集群,如下图所示

在这里插入图片描述

现在我们需要根据cloud-provider-payment8001复制一个cloud-provider-payment8002服务,此时Eureka页面中加载了两个CLOUD-PAYMENT-SERVICE

在这里插入图片描述

调用消费者接口,发现无论如何调用的都是8001的服务,那是因为消费者接口是如下的

@RestController
@Slf4j
public class OrderController {public static final String PaymentSrv_URL = "http://localhost:8001";@ResourceRestTemplate restTemplate;@GetMapping("/consumer/payment/create")public CommonResult createPayment(Payment payment){return restTemplate.postForObject(PaymentSrv_URL + "/payment/create",payment,CommonResult.class);}@GetMapping("/consumer/payment/get/{id}")public CommonResult createPayment(@PathVariable Integer id){return restTemplate.getForObject(PaymentSrv_URL + "/payment/get/" + id,CommonResult.class);}
}

在配置URL时,写死了访问地址,现在需要把地址改成服务注册中心中application的服务名

public static final String PaymentSrv_URL = "http://CLOUD-PAYMENT-SERVICE";

这时候我们调用服务还会报错,这是因为服务注册中心有两个CLOUD-PAYMENT-SERVICE,消费者不知道需要去调用哪个

在这里插入图片描述

这时候要使用@LoadBalanced注解赋予RestTemplate负载均衡的能力,此时在测试可以发现8001、8002服务交替被调用

@Configuration
public class ApplicationContextConfig {@Bean@LoadBalancedpublic RestTemplate getRestTemplate(){return new RestTemplate();}
}

actuator微服务信息完善

服务名称修改

如下图所示,我们注册的服务含有主机名称

在这里插入图片描述

这个名称可以通过配置文件自定义

#服务主机名称
eureka.instance.instance-id=payment8002

在这里插入图片描述

访问信息有ip提示信息

只需要添加如下配置

#访问信息有ip提示
eureka.instance.prefer-ip-address=true

在这里插入图片描述

服务发现Discovery

对于注册进Eureka里的微服务,可以通过服务发现来获得该服务的信息

需要在主启动类上加入@EnableDiscoveryClient,这个注解我们将会经常使用,使用方法如下

    @Resourceprivate DiscoveryClient discoveryClient;    @GetMapping(value = "/discovery")public Object discovery(){// 获取服务名称List services = discoveryClient.getServices();for (String element : services) {System.out.println(element);}// 获取服务的实例List instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");for (ServiceInstance element : instances) {System.out.println(element.getServiceId() + "\t" + element.getHost() + "\t" + element.getPort() + "\t"+ element.getUri());}return this.discoveryClient;}

Eureka自我保护

为什么会产生Eureka自我保护机制?

为了防止EurekaClient可以正常运行,但是 与 EurekaServer网络不通情况下,EurekaServer不会立刻将EurekaClient服务剔除

什么是自我保护模式?

默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时、卡顿、拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了——因为微服务本身其实是健康的,此时本不应该注销这个微服务。Eureka通过“自我保护模式”来解决这个问题——当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。

在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。

它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着

综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有微服务(健康的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮、稳定。

默认情况下,Eureka是开启自我保护,可以使用eureka.server.enable-self-preservation = false 可以禁用自我保护模式

相关内容

热门资讯

122.(leaflet篇)l... 听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行...
育碧GDC2018程序化大世界... 1.传统手动绘制森林的问题 采用手动绘制的方法的话,每次迭代地形都要手动再绘制森林。这...
育碧GDC2018程序化大世界... 1.传统手动绘制森林的问题 采用手动绘制的方法的话,每次迭代地形都要手动再绘制森林。这...
Vue使用pdf-lib为文件... 之前也写过两篇预览pdf的,但是没有加水印,这是链接:Vu...
PyQt5数据库开发1 4.1... 文章目录 前言 步骤/方法 1 使用windows身份登录 2 启用混合登录模式 3 允许远程连接服...
Android studio ... 解决 Android studio 出现“The emulator process for AVD ...
Linux基础命令大全(上) ♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维...
再谈解决“因为文件包含病毒或潜... 前面出了一篇博文专门来解决“因为文件包含病毒或潜在的垃圾软件”的问题,其中第二种方法有...
南京邮电大学通达学院2023c... 题目展示 一.问题描述 实验题目1 定义一个学生类,其中包括如下内容: (1)私有数据成员 ①年龄 ...
PageObject 六大原则 PageObject六大原则: 1.封装服务的方法 2.不要暴露页面的细节 3.通过r...
【Linux网络编程】01:S... Socket多进程 OVERVIEWSocket多进程1.Server2.Client3.bug&...
数据结构刷题(二十五):122... 1.122. 买卖股票的最佳时机 II思路:贪心。把利润分解为每天为单位的维度,然后收...
浏览器事件循环 事件循环 浏览器的进程模型 何为进程? 程序运行需要有它自己专属的内存空间࿰...
8个免费图片/照片压缩工具帮您... 继续查看一些最好的图像压缩工具,以提升用户体验和存储空间以及网站使用支持。 无数图像压...
计算机二级Python备考(2... 目录  一、选择题 1.在Python语言中: 2.知识点 二、基本操作题 1. j...
端电压 相电压 线电压 记得刚接触矢量控制的时候,拿到板子,就赶紧去测各种波形,结...
如何使用Python检测和识别... 车牌检测与识别技术用途广泛,可以用于道路系统、无票停车场、车辆门禁等。这项技术结合了计...
带环链表详解 目录 一、什么是环形链表 二、判断是否为环形链表 2.1 具体题目 2.2 具体思路 2.3 思路的...
【C语言进阶:刨根究底字符串函... 本节重点内容: 深入理解strcpy函数的使用学会strcpy函数的模拟实现⚡strc...
Django web开发(一)... 文章目录前端开发1.快速开发网站2.标签2.1 编码2.2 title2.3 标题2.4 div和s...