前言
微服务的注册中心
在没有注册中心之前,服务与服务之间的通讯可以走基于HTTP通信的RPC框架,直白一点的说就是:一个服务内部直接往一个线上的URL发起请求。像这种简单的直连方式,性能是不错的,但为此给拓展和维护带来不便。
比如一个A服务要向B服务发起请求,部署在服务器上的B服务不止有一个,如何分流会是一个问题,按照业务划分A服务只做A服务该做的事情,可现在就负载这一块上要交给A服务去处理,这不是被期望的。
如果类似的情况发生在A服务去请求C服务呢?要知道复杂的服务之间的调用往往不是一两个这么简单,而且服务还有可能出现类似“宕机”这种情况,这时候,作为服务的调用方如何去规避这些已经挂掉的服务,也是要考虑的一点。
我们希望的是服务与服务的调用就只有业务上的往来,而不应该过多的去考虑功能性的问题,所以注册中心应运而生,它必须要帮我们解决类似上面的问题,比如服务管理(高可用),心跳机制维护等等
CAP的选择
CAP原则,指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性),不能同时成立。
关于CAP
C: 一致性
它要求在同一时刻点,分布式系统中的所有数据备份都处于同一状态。
换句话说:在分布式系统中的所有数据备份,在同一时刻是否同样的值。这就意味着:所有节点在同一时间的数据完全一致,越多节点,数据同步越耗时
A: 可用性
在系统集群的一部分节点宕机后,系统依然能够响应用户的请求。
换句话说:负载过大后,集群整体是否还能响应客户端的读写请求。也就是说:服务一直可用,而且是正常响应时间
P: 分区容错性
在网络区间通信出现失败,系统能够容忍。
换句话说:分区容忍性,就是高可用性,一个节点崩了,并不影响其它的节点。可以这么说:100个节点,挂了几个,不影响服务,越多机器越好
如何选择
一般来讲,基于网络的不稳定性,分布容错是不可避免的,所以我们默认CAP中的P总是成立的。
一致性的强制数据统一要求,必然会导致在更新数据时部分节点处于被锁定状态,此时不可对外提供服务,影响了服务的可用性,反之亦然。因此一致性和可用性不能同时满足。
简而言之,选择的最终结果:要么是CP,要么是AP,没有最好,有的只是取舍
Eureka 如何保证高可用(A)和分区容错性( P)
1 服务注册相对要快,因为不需要等注册信息replicate到其他节点,也不保证注册信息是否replicate成功
2 当数据出现不一致时,虽然A, B上的注册信息不完全相同,但每个Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时如果请求A查不到,但请求B就能查到。如此保证了可用性但牺牲了一致性
搭建环境
IDEA windows 本地
Eureka入门
单机版Eureka
单机版的Eureka是指只有单一的Eureka Server端和多个Eureka Client端,在SpringCloud官方文档把这种情况称为Standalone Mode(译:单一模式)
Eureka Server搭建
Eureka作为SpringCloud的组件,那么可遵循“三板斧”(依赖,配置,注解)的方式完成集成
步骤1:新建eureka项目,引入依赖
步骤2: 启动类上添加@EnableEurekaServer
步骤3:修改application.yml
将IDEA创建的application.properties更改为为application.yml,并添加如下官方推荐配置
步骤4: 启动项目,访问http://localhost:8761/
思考
1 配置文件(即:apapplication.yml)为空白的情况下,能否启动成功?
2 这种情况下,可否访问的了eureka的页面?请求地址还是http://localhost:8761/?
3 在这种情况下,控制台是否有报错,倘若有,报错的原因是什么?
Eureka Client搭建
步骤1: 新建client项目,引入依赖
步骤2: 修改application.yml
将IDEA创建的application.properties更改为为application.yml,并添加如下配置
步骤3: 启动项目,访问http://localhost:8761/
思考
1 这里的启动类为什么不用加@EnableDiscoveryClient或者@EnableEurekaClient?
2 为什么不用给client配置Eureka Server端的地址?
集群版Eureka
在真实的生产环境中,部署在线上的Eureka Server往往不止一个,这是为了防止某个Eureka Server挂掉后,依然不影响线上的Eureka Client的注册和服务调用
搭建
集群版的Eureka Server端的搭建基于单机版上改造,所以像引入依赖和加注解这两个步骤可忽略
步骤1: 修改application.yml
根据官方文档的推荐,我们将本地的application.yml更改为两个不同名文件,如下
步骤2: IDEA里配置单启动类对应多配置文件分别映射
步骤3:启动项目,分别访问本机8761和8762端口地址
依次启动 Server peer1 、client 和 Server peer2,分别访问 http://localhost:8761/和http://localhost:8762/
思考
1 client是默认往哪个地址注册的,为什么访问另外一台Server也可以看到client的注册信息?
2 如果我改变启动顺序,如果是先启动服务端peer1,然后启动服务端peer2,最后再启动client服务,client还会出现在两台Server端注册列表里吗?为什么呢?
3 目前这种搭建模式能否确保服务的高可用?应该如何改进呢?如果是3台Eureka Server应该如何搭建?
Eureka进阶
基于java11搭建
在JDK 11中删除了Eureka服务器所依赖的JAXB模块。如果您打算在运行Eureka服务器时使用JDK 11,则必须在POM或Gradle文件中包含这些依赖项
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
</dependency>
关于思考的源码探究
在如上的思考题中,部分答案出现在我简书的地址上:https://www.jianshu.com/u/6f7b36de79de 有兴趣的小伙伴就自行观看,后续我将单独整理出来
待整理的内容
如下的内容,将在后面时间允许的情况下,加入这篇文档,没有的话,其实也无伤大雅