六、Eureka 注册中心架构原理
1、Eureka 架构图
![a4ef0f7acb81983b4eab8d9867ebb18c.png](https://i-blog.csdnimg.cn/blog_migrate/c4b2f0d77623c6bd4cebb1f96aeb2ab3.jpeg)
1)Register(服务注册):把自己的 IP 和端口注册给 Eureka。
2)Renew(服务续约):发送心跳包,每 30 秒发送一次。告诉 Eureka 自己还活着。
3)Cancel(服务下线):当 provider 关闭时会向 Eureka 发送消息,把自己从服务列表中删除;防止 consumer 调用到不存在的服务。
4)Get Registry(获取服务注册列表):获取其他服务列表。
5)Replicate(集群中数据同步):eureka 集群中的数据复制与同步。
6)Make Remote Call(远程调用):完成服务的远程调用。
七、 基于分布式 CAP 定理,分析注册中心两大主流框架:Eureka 与 Zookeeper 的区别
1、什么是 CAP 原则
1)CAP 原则又称 CAP 定理,指的是在一个分布式系统中,Consistency(一致性)、
Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。
2)CAP 由 Eric Brewer 在 2000 年 PODC 会议上提出。该猜想在提出两年后被证明成
立,成为我们熟知的 CAP 定理。
2、分布式系统 CAP 定理:
1)C 数据一致性 (Consistency)
也叫做数据原子性 。
系统在执行某项操作后仍然处于一致的状态。在分布式系统 中,更新操作执行成功后所有的用户都应该读到最新的值, 这样的系统被认为是具有强一致性的。等同于所有节点访问同一份最新的数据副本。
2)A 服务可用性 (Availablity)
每一个操作总是能够在一定的时间内返回结果,这里需要注意的是"一定时间内"和"返回结果"。一定时间内指的是,在可以容忍的范围内返回结果,结果可以是成功或者是失败。
3)P 分区容错性 (Partition-torlerance)
在网络分区的情况下,被分隔的节点仍能正常对外提供服务(分布式集群,数据被分布存储在不同的服务器上,无论什么情况,服务器都能正常被访问)。
3、定律:任何分布式系统只可同时满足二点,没法三者兼顾。
1)CA,放弃 P :
如果想避免分区容错性问题的发生,一种做法是将所有 的数据(与事务相关的)都放在一台机器上。虽然无法 100%保 证系统不会出错,单不会碰到由分区带来的负面效果。当然这个选择会严重的影响系统的扩展性。
2)CP,放弃 A :
相对于放弃"分区容错性"来说,其反面就是放弃可用性。 一旦遇到分区容错故障,那么受到影响的服务需要等待一定时间,因此在等待时间内系统无法对外提供服务。
3)AP,放弃 C :
这里所说的放弃一致性,并不是完全放弃数据一致性, 而是放弃数据的强一致性,而保留数据的最终一致性。以网络购物为例,对只剩下一件库存的商品,如果同时接受了两个订单,那么较晚的订单将被告知商品告罄(售空)。
3、Zookeeper 与 Eureka 的区别
![a1263db15afe817b76c13e0733d8eede.png](https://i-blog.csdnimg.cn/blog_migrate/e4b592619bbc8bc9fcd64d65a56f259f.jpeg)
八、 Eureka 优雅停服
1、在什么条件下,Eureka 会启动自我保护?
什么是自我保护模式
![831448210f48d4feda709b594016944b.png](https://i-blog.csdnimg.cn/blog_migrate/e416dd5469c6d882553f9656a2799528.jpeg)
1)自我保护的条件一般情况下,微服务在 Eureka 上注册后,会每 30 秒发送心跳包,Eureka 通过心跳来判断服务时候健康,同时会定期删除超过 90 秒没有发送心跳服务。
2)有两种情况会导致 Eureka Server 收不到微服务的心跳
a)是微服务自身的原因 。
b)是微服务与 Eureka 之间的网络故障。
通常(微服务的自身的故障关闭)只会导致个别服务出现故障,一般不会出现大面积故障,而(网络故障)通常会导致 Eureka Server 在短时间内无法收到大批心跳。
考虑到这个区别,Eureka 设置了一个阀值,当判断挂掉的服务的数量超过阀值时,
Eureka Server 认为很大程度上出现了网络故障,将不再删除心跳过期的服务。
3、那么这个阀值是多少呢?
15 分钟之内是否低于 85%;
Eureka Server 在运行期间,会统计心跳失败的比例在 15 分钟内是否低于 85% 这种算法叫做 Eureka Server 的自我保护模式。
2、为什么要启动自我保护
为什么要自我保护
1)因为同时保留"好数据"与"坏数据"总比丢掉任何数据要更好,当网络故障恢复后, 这个Eureka 节点会退出"自我保护模式"。
2)Eureka 还有客户端缓存功能(也就是微服务的缓存功能)。即便 Eureka 集群中所有节点都宕机失效,微服务的 Provider 和 Consumer 都能正常通信。
3)微服务的负载均衡策略会自动剔除死亡的微服务节点。
3、如何关闭自我保护
1)修改 Eureka Server 配置文件
#关闭自我保护:true 为开启自我保护,false 为关闭自我保护
eureka.server.enableSelfPreservation=false
#清理间隔(单位:毫秒,默认是 60*1000)
eureka.server.eviction.interval-timer-in-ms=60000
2)修改注册中心集群项目的全局配置文件
![d63f27ca7df5d4dab8afd8fd62b4ebef.png](https://i-blog.csdnimg.cn/blog_migrate/1576fc2a48742cd8123dc4cf7011f6b3.jpeg)
a)application-eureka1.properties全局配置文件
#给当前应用起个名称
spring.application.name=eureka-server
#修改端口号默认为8080
server.port=8761
#是否将自己注册到Eureka-Server中,默认为true
#eureka.client.registerWithEureka=false
#是否从Eureka-Server中获取注册信息,默认为true
#eureka.client.fetchRegistry=false
#设置eureka实例名称,与配置文件变量为主
eureka.instance.hostname=eureka1
#设置服务中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://eureka2:8761/eureka/
#关闭自我保护:true 为开启自我保护,false 为关闭自我保护
eureka.server.enableSelfPreservation=false
#清理间隔(单位:毫秒,默认是 60*1000)
eureka.server.eviction.interval-timer-in-ms=60000
b)application-eureka2.properties全局配置文件
#给当前应用起个名称
spring.application.name=eureka-server
#修改端口号默认为8080
server.port=8761
#设置eureka实例名称,与配置文件变量为主
eureka.instance.hostname=eureka2
#设置服务中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/
#关闭自我保护:true 为开启自我保护,false 为关闭自我保护
eureka.server.enableSelfPreservation=false
#清理间隔(单位:毫秒,默认是 60*1000)
eureka.server.eviction.interval-timer-in-ms=60000
3)修改配置文件后,清除jar包,重新打包,把jar包重新导入linux虚拟机中,重新部署。
![1e55d71853bd121913f1a83ab4afbbf4.png](https://i-blog.csdnimg.cn/blog_migrate/21a9cabe7cf2399b3b347ca06aefe69f.jpeg)
4)重新部署eureka集群版注册中心后,运行,在页面访问,提示关闭了自我保护机制。
![f05c6ee3f63e6a0df619bde827854350.png](https://i-blog.csdnimg.cn/blog_migrate/3720aff4e271d4fff8803f1882d1563f.jpeg)
4、如何优雅停服
以建好的provider项目为实例
![f09fd310628f55ae275f696fc0740252.png](https://i-blog.csdnimg.cn/blog_migrate/7990f911031cde991d35ca7d65bf0cc9.jpeg)
1)不需要再 Eureka Server 中配置关闭自我保护 ,即在标题3中的注册中心集群中的配置文件可以删除 关闭自我保护 的配置。
2)需要再服务中添加 actuator.jar 包
即在pom.xml文件中eureka坐标中添加 -server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka -server</artifactId>
</dependency>
添加后便可在pom.xml文件中找到坐标下的actuator.jar 包
![7659c3a080fdbec238c834ce9803324d.png](https://i-blog.csdnimg.cn/blog_migrate/a093cb5d2452f2a2640be620a3f6bd5f.jpeg)
3)修改全局配置文件
添加以下两行 #启用 shutdown endpoints.shutdown.enabled=true #禁用密码验证 endpoints.shutdown.sensitive=false
#给当前应用起个名称
spring.application.name=eureka-provider
#修改端口号默认为8080
server.port=9090
#设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://eureka1:8761/eureka/,http://eureka2:8761/eureka/
#启用 shutdown命令来关闭服务
endpoints.shutdown.enabled=true
#禁用密码验证
endpoints.shutdown.sensitive=false
4)发送一个关闭服务的 URL 请求
添加工具类HttpClientUtil.java到测试类同级目录中
对main方法内容做修改
String url ="http://127.0.0.1:9090/shutdown"; //该url必须使用dopost方式来发送 HttpClientUtil.doPost(url);
作用:
String url ="http://127.0.0.1:9090/shutdown"; --->是对当前做优雅停服的服务发出的请求
HttpClientUtil.doPost(url); --->该url请求只能使用post方式来发送
package
5)操作优雅停服
先在provider启动服务(启动器),然后进入工具类HttpClientUtil.java 直接右击 Run As运行,
![6ccc06c4e3238a92ac9f42f116ec9017.png](https://i-blog.csdnimg.cn/blog_migrate/6a8d2bdda1b543bf3df42e7e51eeb827.jpeg)
优雅停服后注册中心管理界面,警告信息(自我保护机制警告信息)消失;provider的注册信息立即被删除。
![af961fcddeb556297c54f3a4f0c4bfc0.png](https://i-blog.csdnimg.cn/blog_migrate/3f9e504a77835e5ade7d07367a169b11.jpeg)
九、如何加强 Eureka 注册中心的安全认证
注意:
下面所有配置都是对注册中心集群版项目做配置,配置完成后,要重新打jar包,并且要在linux虚拟机中重新部署。
修改项目--->Eureka注册中心集群版
![c0c3c96938b3bdacd54a54e3d0ca90c8.png](https://i-blog.csdnimg.cn/blog_migrate/9b13908a4ee955e3dbe841d03f97dad1.png)
1、在 Eureka Server(pom.xml) 中添加 security 包
添加的坐标为
<dependency>
2、修改 Eureka Server 配置文件
添加安全认证:
#开启 http basic 的安全认证 security.basic.enabled=true security.user.name=user security.user.password=123456
作用-----> 开启安全认证,设置用户名密码
3、修改访问集群节点的 url
#设置服务中心地址,指向另一个注册中心 eureka.client.serviceUrl.defaultZone=http:// user:123456@eureka2:8761/eureka/
作用----->让集群中的节点在相互访问时自带用户名密码
对以下两节点的具体修改:
application-eureka1.properties全局配置文件
#给当前应用起个名称
spring.application.name=eureka-server
#修改端口号默认为8080
server.port=8761
#设置eureka实例名称,与配置文件变量为主
eureka.instance.hostname=eureka1
#设置服务中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka2:8761/eureka/
#开启 http basic 的安全认证
security.basic.enabled=true
security.user.name=user
security.user.password=123456
application-eureka2.properties全局配置文件
#给当前应用起个名称
spring.application.name=eureka-server
#修改端口号默认为8080
server.port=8761
#设置eureka实例名称,与配置文件变量为主
eureka.instance.hostname=eureka1
#设置服务中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka2:8761/eureka/
#开启 http basic 的安全认证
security.basic.enabled=true
security.user.name=user
security.user.password=123456
4、修改好后,重新对项目做打包处理,重新在linux中部署好后,在网页访问如下,Eureka 注册中心出现安全验证。
![48e0e19c934211873ef5670e6f5f9d2c.png](https://i-blog.csdnimg.cn/blog_migrate/b0448461bb1444e823a8ba91e4e4ef7c.jpeg)
5、如果其他服务想在加强安全验证的Eureka 注册中心中注册,需要在全局配置文件中做一下修改。
1)修改前注册
![236afc8b176bf276e25a479b8bce1af1.png](https://i-blog.csdnimg.cn/blog_migrate/1fad215f0f08b11495df76e790d74610.jpeg)
2)修改后注册
修改provider的全局配置文件
在服务注册中心地址添加密码-----> user:123456@
application.properties文件
#给当前应用起个名称
spring.application.name=eureka-provider
#修改端口号默认为8080
server.port=9090
#设置服务注册中心地址,指向另一个注册中心
eureka.client.serviceUrl.defaultZone=http://user:123456@eureka1:8761/eureka/,http://user:123456@eureka2:8761/eureka/
#启用 shutdown命令来关闭服务
endpoints.shutdown.enabled=true
#禁用密码验证
endpoints.shutdown.sensitive=false
![c9e2ecf507ea1dc9c53c28f0e8b58974.png](https://i-blog.csdnimg.cn/blog_migrate/d89792f75fa7351db5414c8266002b08.jpeg)
负载均衡 Ribbon
一、 Ribbon 在微服务中的作用
1、什么是 Ribbon
1)Ribbon 是一个基于 Http 和 TCP 的客服端负载均衡工具,它是基于 Netflix Ribbon 实现的。
2)它不像 spring cloud 服务注册中心、配置中心、API 网关那样独立部署,但是它几乎
存在于每个 spring cloud 微服务中。包括 feign 提供的声明式服务调用也是基于该 Ribbon
实现的。
3)ribbon 默认提供很多种负载均衡算法,例如 轮询、随机 等等。甚至包含自定义的负
载均衡算法。
2、Ribbon 解决了什么问题
他解决并提供了微服务的负载均衡问题。
二、 集中式与进程内负载均衡的区别
1、负载均衡解决方案的分类
目前业界主流的负载均衡方案可分成两类:
1)第一类:集中式负载均衡, 即在 consumer 和 provider 之间使用独立的负载均衡设施(可
以是硬件,如 F5, 也可以是软件,如 nginx), 由该设施负责把 访问请求 通过某种策略转发
至 provider;
2)第二类:进程内负载均衡,将负载均衡逻辑集成到 consumer,consumer 从服务注册中
心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的 provider。
Ribbon 就属于后者,它只是一个类库,集成于 consumer 进程,consumer 通过它来获取
到 provider 的地址。