背景知识
什么是服务治理
- 在传统的 RPC 远程调用框架中,管理每个服务与服务之间依赖关系比较复杂、管理比较复杂,所以需要使用服务治理,管理服务与服务之间的依赖关系,可以实现服务调用、负载均衡、容错等,实现服务注册与发现
CAP 理论
- CAP:Consistency(强一致性)、Availability(可用性)、Partition tolerance(分区容错性)
- 一个分布式系统不可能同时很好的满足一致性、可用性和分区容错性这三个需求,最多只能同时较好的满足两个。CA一般是单点集群,在可拓展上不太强;CP一般性能不是特别高;AP一般对一致性要求低一些
- CAP 理论关注粒度是数据,而不是整体系统设计的策略
Eureka
概念
- SpringCloud 封装了 Netfix 公司开发的 Eureka 模块来实现服务治理
- Eureka 采用了 CS 的设计架构,Eureka Server 作为服务注册功能的服务器,是服务注册中心。而系统中的其他微服务,使用 Eureka 的客户端连接到 Eureka Server 并维持心跳连接、这样系统的维护人员就可以通过 Eureka Server 来监控系统中各个微服务是否正常运行
- 在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息 比如 服务地址通讯地址等以别名方式注册到注册中心上。另一方(消费者|服务提供者)以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地 RPC 调用
- RPC 远程调用框架的思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何 RPC 远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))
- 类似于 Dubbo 系统架构图
组件
- Eureka Server 提供服务注册服务:各个微服务节点通过配置启动后,会在 Eureka Server 中进行注册,这样 Eureka Server 中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到
- Eureka Client 通过注册中心进行访问:是一个 Java 客户端,用于简化 Eureka Server 的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会向 Eureka Server 发送心跳(默认周期为 30 秒)。如果 Eureka Server 在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认 90 秒)
单机 Eureka 配置
- 主要通过 pom.xml 引入 spring-cloud-starter-netflix-eureka-client、 spring-cloud-starter-netflix-eureka-server。之后再 yml 添加相应配置,主启动类添加 @EnableEurekaClient、 @EnableEurekaServer
- 引入 pom 依赖,分为 Eureka 的服务注册中心,和 Eureka 的客户端
<!--引入 Eureka 组件作为服务注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--引入 Eureka Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 写 application.yml 文件,添加 Eureka 的相关配置
# Eureka Server 添加的配置
eureka:
instance:
# eureka服务端的实例名称
hostname: localhost
client:
# false表示不向注册中心注册自己。
register-with-eureka: false
# false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
# Eureka Client 添加的配置
eureka:
client:
# 表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
# 是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合 ribbon 使用负载均衡
fetchRegistry: true
service-url:
defaultZone: http://localhost:7001/eureka
- 写启动类 EurekaMain.class, 添加 @EnableEurekaClient、 @EnableEurekaServer
# 客户端添加
@SpringBootApplication
@EnableEurekaClient
public class OrderMain {
public static void main(String[] args) {
SpringApplication.run(OrderMain.class, args);
}
}
# Eureka 服务端添加
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain {
public static void main(String[] args) {
SpringApplication.run(EurekaMain.class, args);
}
}
- 启动服务测试连接
集群 Eureka 配置
- 在原有的基础上,新添加一个 Eureka Server
- 相互注册将 Eureka 配置的 defaultZone 添加另外的 Eureka 的 service-url。使用 Eureka 集群也只需要将配置的 defaultZone 添加注册的 Eureka service-url
- Eureka Server 配置 彼此之间相互注册
eureka:
instance:
# eureka 服务端的实例名称
hostname: eureka7002.com
client:
# false 表示不向注册中心注册自己。
register-with-eureka: false
# false 表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
defaultZone: http://eureka7001.com:7001/eureka/
eureka:
instance:
# eureka服务端的实例名称
hostname: eureka7001.com
client:
# false表示不向注册中心注册自己。
register-with-eureka: false
# false表示自己端就是注册中心,我的职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
# 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址。
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
defaultZone: http://eureka7002.com:7002/eureka/
- Eureka Client 使用只需要增加 defaultZone 里面的 server-url 即可
# 集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
- 配置 host 文件 C:\Windows\System32\drivers\etc 配置后重启生效
- 测试集群是否成功、访问 http://eureka7002.com:7002/、http://eureka7001.com:7001/
Eureka 自我保护
- 默认情况下,如果 Eureka Server 在一定时间内没有收到某个微服务实例的心跳,Eureka Server 将会注销该实例(默认 90 秒)。但是当发生网络分区故障(延时、卡顿、拥挤)时,微服务与 Eureka Sever 之间无法正常通信,由于服务本身是健康的,所以此时不应该注销这个微服务。Eureka 通过 自我保护模式 解决这个问题,当 Eureka Server 节点 在短时间内丢失过多客户端时(可能发生了网络分区故障),那么该节点会进入自我保护模式
- 某时刻某一个微服务不可用了, Eureka 不会立刻清理,依旧会对该微服务的信息进行保存
- 属于 CAP 理论的 AP 设计思想,保证高可用、分区容错性
- 标志字样:
取消自我保护机制
# Eureka Client 配置
eureka:
instance:
# Eureka 客户端向服务端发送心跳的时间间隔,单位为秒(默认30秒)
lease-renewal-interval-in-seconds: 1
# Eureka 服务端收到最后一次心跳后等待时间上限,单位为秒(默认90秒),超时将剔除服务
# 如果 Eureka 服务端同时有此项配置,服务端优先级大于客户端
lease-expiration-duration-in-seconds: 2
# Eureka Sever 配置
eureka:
server:
# 关闭自我保护机制,保证不可用服务及时被剔除
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
Zookeeper
- 服务注册的节点是临时节点,属于 CAP 理论的 CP 设计思想,保证数据一致性、分区容错性
- 引入配置与 Eureka 大体一致,都是使用 @EnableDiscoveryClient、@LoadBalanced 注解
- 项目源码
安装
| 名称 | 命令 |
|---|---|
| 使用 Docker 安装 | docker run --name zookeeper -p 2181:2181 --restart always -d zookeeper |
| 进入容器 | docker exec -it b3cd072581b2 bash |
| 进入 zookeeper 客户端 | ./bin/zkCli.sh -server 127.0.0.1:2181 |
| 验证是否注册上节点 |
缺点
- Zookeeper 属于 CP,不太适合当注册中心。
- 当 master 节点因为网络故障与其他节点失去联系时,剩下的节点会重新进行 leader 选举。而选举 leader 的时间太长,并且选举期间整个 zookeeper 集群都是不可用的。会导致在选举期间注册服务瘫痪。
Consul
概念
- Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发
- 提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之 Consul 提供了一种完整的服务网格解决方案
- 具有很多有点。包括:基于 raft 协议,比较简洁;支持健康检查,同时支持 HTTP 和 DNS 协议;支持跨数据中心的 WAN 集群;提供图形界面;跨平台,支持 Linux、Mac、Windows; Key-Value 的存储方式
- Consul 官网地址
- Spring Cloud Consul
安装
| 名称 | 命令 |
|---|---|
| 使用 Docker 安装 | docker run --name consul1 -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600 consul agent -server -bootstrap-expect=1 -ui -bind=0.0.0.0 -client=0.0.0.0 |
| 访问客户端 | http://47.95.211.172:8500/ |
缺点
- Consul 所在的 HashiCorp 公司宣布,不允许中国境内使用该公司旗下 Terraform、Consul、Vagrant 企业版
Nacos
- 目前章节主要包含 SpringCloud 内容,后续会补充 SpringCloudAlibaba
总结
- 一般会选择 AP + 最终一致性的方案来完成
- 简单来讲:AP在系统数据不同步的时候访问会返回旧值、CP在系统数据不同步的时候访问会返回错误状态(因为要保证系统之间的一致性)

京公网安备 11010502036488号