文章目录
Eureka服务注册与发现
总体概括思维导图
Eureka基础知识
什么是服务治理
Spring Cloud封装了Netflix公司开发的Eureka模块来实现服务治理。在传统的rpc远程调用框架中,管理每个服务与每个服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用,负载均衡,容错等,实现服务发现与注册。
什么是服务注册与发现
Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其它微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息,比如服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务于服务之间的一个依赖关系(服务治理概念)。在任何RPC远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))。
Eureka两组件
单机Eureka构建步骤
IDEA生成eurekaServer端服务注册中心
这个子模块主要是我们的服务注册中心,主要干的活是注册,因此不用写业务逻辑类。
建Module
写POM
写YML
主启动
测试
首先启动启动类如下图:
然后去浏览器浏览效果,如下图:
这个时候里面是没有服务的,因为当前还没有服务被注册进来。
易错点
假如在启动类上没有加@EnableEurekaServer注解,那么会出错,如下图:
将之前写的付费模块这个提供者服务模块改一下
改POM
这样在主启动类上才能够加上EnableEurekaClient注解。
改YML
改主启动类
测试
CLOUD-PAYMENT_SERVICE这个服务的名字是根据什么生成的呢?
就是根据提供者服务中的配置文件中的配置生成的,如下图:
将之前写的订单模块这个消费者服务模块改一下
改POM
在消费者服务模块里面也加上springcloud提供的eureka-client依赖,如下图:
改YML
改主启动类
测试
首先要开启三个服务,Eureka服务器服务,Payment提供者服务和Order消费者服务如下图:
在Eureka注册中心服务器里面查看注册进去的消费者服务和提供者服务,如下图:
Eureka集群
为什么需要使用Eureka集群?
因为,想你的注册中心只有一个only one,如果Eureka注册中心这个服务器它出故障了那就呵呵了,会导致整个微服务环境不可用,所以解决的办法就是:搭建Eureka注册中心集群,实现负载均衡+故障容错。集群的配置其实也就是高可用。问题:微服务RPC远程服务调用最核心的是什么?高可用。
从上面的集群可以看出,提供者服务可能有多个,但是消费者服务只有一个。
集群Eureka构建步骤
新建cloud-eureka-server7002
改POM
修改映射配置
首先找到hosts文件如下图:
然后往这个配置文件中加入一下代码
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
如下图:
但是当保存的时候会显示没有权限保存,如下图:
写YML(以前单机)
改之前的7001的eureka服务,如下图:
写7002的eureka服务,如下图:
主启动类
分别在eureka的服务器中测试
查看端口号是7001的eureka服务端,如下图:
查看端口号是7002的eureka服务端,如下图:
出现上面的情况就证明测试成功了。
将订单,支付两微服务注册进Eureka集群
修改两个微服务的配置文件
首先将提供者服务也即是payment这个支付模块微服务发布到Eureka集群中,如下图,只需要在提供者服务的配置文件中把单机版的eureka注册修改成集群版的eureka注册即可,如下图:
接着将消费者服务也即是order这个订单模块微服务发布到Eureka集群中,如下图,只需要在消费者服务的配置文件中把单机版的eureka注册修改成集群版的eureka注册即可,如下图:
测试
首先启动Eureka7001,然后启动Eureka7002,然后启动payment8001,最后启动order80,如下图:
然后去Eureka7001服务端和Eureka7002服务端查看eureka注册中心里面已经注册的服务,如下图:
这就说明已经测试成功了。
支付服务提供者8001集群环境构建
新建cloud-provider-payment8002
改POM
把8001的pom配置文件中的依赖直接复制到8002即可,如下图:
写YML
把8001服务中的配置文件中的内容复制到8002服务中,但是需要注意的是中间的端口号一定要记得更改一下,如下图:
主启动类
业务类
8002的业务类可以直接从8001中粘贴过来如下图:
修改8001/8002的Controller
目的:调用不同端口号的提供者服务通过提供者服务的名字是不能区分的,因为他们的名字都相同,我们要通过他们的端口号来区分。
那现在就会出现一个问题,如下图:
我们可以发现在微服务架构里面,Eureka Server注册中心集群有多个,并且提供者服务也有多个,这多个提供这服务会同时发布到不同的Eureka Server集群中,并且对于Payment这个提供者服务来说,虽然有多个提供者服务,这多个提供者服务都在Eureka Server注册中心服务器上,但是它们的名字是相同的,什么意思呢?如下图:
那现在的问题就是,我们消费者调用提供者服务,这些提供者服务的功能都是一样的,那么我们怎么样能知道我们调用的是哪个端口号下的提供者服务呢?方法是:可以在调用服务的时候输出服务的端口号如下图:
8002端口号的提供者服务中修改方法相同,如下图:
测试
首先启动eureka7001和eureka7002这两个集群eureka注册中心,然后启动payment8001和payment8002这两个提供者服务,最后启动order80这个消费者服务,如下图:
然后分别取eureka7001注册中心和eureka7002注册中心查看它们里面被注册的服务,eureka7001注册中心如下图:
eureka7002注册中心如下图:
测试成功如下图:
负载均衡
中间存在的一个小bug
当我们通过order80消费者调用payment提供者服务的时候,发现无论怎么刷新,一直调用的都是端口号为8001的payment提供者服务,如下图:
这个原因是因为:我们在order80消费者服务中把提供者服务的地址写死了,我们不能写死,需要改正一下,如下图:
但是把url的固定地址换成提供者服务的名字之后,会出现下面的异常,如下图:
为什么会出现上面的异常呢?
因为CLOUD-PAYMENT-SERVICE这个提供者服务名字里面对应着多个微服务,我们不知道具体使用哪一个,那具体该怎么解决呢?可以加上一个@LoadBalanced注解,加上一个负载均衡的能力就行了。
使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
给IOC容器里面的RestTemplate对象加上一个负载均衡的能力,可以直接在它的上面加上一个@LoadBalanced注解,如下图:
这样就可以成功的使用消费者调用提供者的服务了,如下图:
actuator微服务信息完善
使用actuator进行微服务信息完善有两个标配的依赖,如下图:
修改微服务的名字
在Payment8001和Payment8002这两个提供者服务的配置文件中,配置提供者服务在Eureka注册中心的实例的名字,如下图:
修改Payment8001提供者服务的配置文件,如下图:
修改Payment8002提供者服务的配置文件,如下图:
重新启动后去Eureka注册中心查看,如下图:
让微服务显示出对应的主机地址和端口号
但现在仍有一个问题,就是鼠标箭头放到微服务名称的上面左下角没有显示微服务对应的主机地址和端口号?
如下图:
那么我们需要怎么更改呢?分别在Payment8001和Payment8002这两个微服务的配置文件中加上个东西,如下图:
测试能否显示出微服务的ip地址和端口号,如下图:
服务发现Discovery
什么叫做服务发现?
服务发现就是说对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息
修改cloud-provider-payment8001的Controller
从IOC容器中引入当前的Eureka注册中心对应的DiscoveryClient对象如下图:
通过DiscoveryClient对象获取微服务的名字和某个微服务下面的服务,如下图:
8001主启动类
在8001主启动类上一定要加上@EnableDiscoveryClient注解,如下图:
自测
先来看一下当前的Eureka注册中心已经注册进来的微服务,如下图:
访问控制器中对应的服务发现的控制器方法,查看访问结果,如下图:
eureka自我保护
概述
保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务。
如果在Eureka Server的首页看到以下这段提示,则说明Eureka进入了保护模式,如下图:
什么是自我保护模式?
默认情况下,如果EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90秒)。但是当网络分区故障发生(延时,卡顿,拥挤)时,微服务与EurekaServer之间无法正常通信,以上行为可能变得非常危险了,因为微服务本身其实是健康的,此时本不该注销这个微服务。Eureka通过"自我保护模式"来解决这个问题,当EurekaServer节点在短时间内丢失过多客户端时(可能发生了网络分区故障),那么这个节点就会进入自我保护模式。
在自我保护模式中,Eureka Server会保护服务注册表中的信息,不再注销任何服务实例。它的设计哲学就是宁可保留错误的服务注册信息,也不盲目注销任何可能健康的服务实例。一句话讲解:好死不如赖活着。
综上,自我保护模式是一种应对网络异常的安全保护措施。它的架构哲学是宁可同时保留所有的微服务(健康的微服务和不健康的微服务都会保留)也不盲目注销任何健康的微服务。使用自我保护模式,可以让Eureka集群更加的健壮,稳定。
为什么会产生Eureka自我保护机制?
为了防止EurekaClient可以正常运行,但是与EurekaServer网络不通情况下,EurekaServer不会立刻将EurekaClient服务剔除。
怎么禁止自我保护
注册中心eurekaServer端7001
首先需要在注册中心EurekaServer的服务端,在配置文件中进行一些配置,从而关闭自我eureka的自我保护机制,如下图:
生产者客户端eurekaClient端8001
在提供者服务的配置文件中配置心跳检测时间和最大允许的心跳时间间隔,如下图:
测试
启动7001/7002Eureka集群服务器,启动8001/8002提供者集群服务,启动80消费者服务,如下图:
去Eureka7001注册中心中查看注册进来的服务,如下图:
关闭8001提供者服务,如下图:
再去Eureka7001注册中心中查看注册进来的微服务,如下图:
但是如果我们开启了eureka的自我保护机制的话,像刚才的那种情况,虽然你关闭了8001服务,但是8001服务仍然不会被Eureka7001注册中心剔除掉。如下图:
注意开启eureka的自我保护机制需要设置两个地方,第一个地方是把eureka.server.enable-replicated-request-compression的值设置成true,第二个地方是需要把eureka.server.eviction-interval-timer-in-ms的值设置的大一点,这个值什么意思呢?就是虽然你开启了自我保护机制,但也不能说让检测不到心跳的服务一直存在,你要有一个最大限度值,这里是指:如果eureka服务端在两秒内都检测不到提供者服务的心跳,那么eureka注册中心会剔除掉这个提供者服务。