2-SpringCloud-Consul服务注册与发现和分布式配置管理
1.2 Consul 微服务组件
Consul 微服务主键主要用于解决服务注册与发现和分布式配置管理。
Consul 是一套开源的分布式服务发现和配置管理系统,由 HashiCorp 公司用 Go 语言开发。提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格,总之Consul提供了一种完整的服务网格解决方案。它具有很多优点。包括: 基于 raft 协议,比较简洁; 支持健康检查, 同时支持 HTTP 和 DNS 协议 支持跨数据中心的 WAN 集群 提供图形界面 跨平台,支持 Linux、Mac、Windows。
HashiCorp是一家非常知名的基础软件提供商,很多人可能没听过它的名字,但是其旗下的6款主流软件,Terraform、Consul、Vagrant、Nomad、Vault,Packer 相信不少程序员都听说或使用过,尤其是Consul使用者不尽其数。截止目前为止,从HashiCorp 官网上的声明来看,开源项目其实还是“安全”的,被禁用的只是Vault企业版(并且原因是Vault产品目前使用的加密算法在中国不符合法规,另一方面是美国出口管制法在涉及加密相关软件上也有相应规定。因此这两项原因使得HashiCorp不得不在声明中说明风险)而非其他所有开源产品(Terraform、Consul等)。因此,大家可以暂时放下心来,放心使用!
- Consul 官网:https://www.consul.io
- Consul 理论学习网址:https://developer.hashicorp.com/consul/docs
- Spring Consul理论学习网址:https://docs.spring.io/spring-cloud-consul/reference/index.html
- Spring Consul 源码学习网址:https://github.com/spring-cloud/spring-cloud-consul
- Spring Consul 编码 BUG 解决网址:https://stackoverflow.com/questions/tagged/spring-cloud
- Consul 下载网址:https://developer.hashicorp.com/consul/install
Consul 主要特征:
- 服务发现:提供 HTTP 和 DNS 两种服务发现方式。
- 健康监测:支持多种方式,HTTP、TCP、Docker、Shell 脚本定制化监控。
- KV 存储:Key、Value 存储方式。
- 多数据中心:Consul 支持多种数据中心。
- 可视化 Web 界面
1.2.1 安装 Consul
下载 Consul 请到网址https://developer.hashicorp.com/consul/install进行下载。我这里下载的 Consul 版本是 consul_1.21.4_windows_386
。
下载完成后直接解压压缩包。
首先进入解压后的文件内,其中包含consul.exe
文件,在包含改文件的目录搜索框内输入 cmd 并回车。输入命令consul --version
查询 consul 是由安装成功,如出现版本信息即安装成功。接着输入命令consul agent -dev
,运行 consul 组件。具体操作请参考下图。
接着打开浏览器输入网址http://localhost:8500,若出现下图,表示 consul 安装成功。
1.2.2 服务注册与发现
本节主要用于注册订单微服务80和支付微服务8001,使这两个微服务入驻 Consul。
1.2.2.1 支付微服务8001入驻 Consul
-
在 pom.xml 文件中添加如下依赖。可从 Spring Cloud Consul 官网查看。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-discovery</artifactId><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions> </dependency>
-
在 application.yml 文件中添加配置,具体内容如下,也是根据 Spring Cloud Consul 官网查看。
spring:cloud:consul:host: localhostport: 8500discovery:# 设置服务名代替 IP 地址和端口号service-name: ${spring.application.name}
参考网站截图,如下。
-
在主启动类添加类注解
@EnableDiscoveryClient
开启服务注册与发现 Consul。 -
最后在 Consul 控制台查看是否有相关服务注册成功。如出现以下图片类似内容表示注册成功。
1.2.2.2 订单微服务80入驻 Consul
-
在 pom.xml 文件中添加依赖,添加依赖与支付微服务8001的依赖一致,此处不再书写。
-
在 application.yml 文件中添加如下内容。
spring:application:name: cloud-consumer-order####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:prefer-ip-address: true #优先使用服务ip进行注册service-name: ${spring.application.name}
-
在主启动类添加类注解
@EnableDiscoveryClient
开启服务注册与发现 Consul。 -
将 OrderController 控制类中的硬编码
public static final String PaymentSrv_URL = "http://localhost:8001";
更改为服务注册中心的微服务名称public static final String PaymentSrv_URL = "http://cloud-payment-service";
-
需要在配置类 RestTemplateConfig 的方法上添加注解
@LoadBalaced
,因为 Consul 天然带有负载均衡,该服务引用了其他微服务,默认引用服务有多个,所以必须添加注解,否则会报错 java.net.UnknowHostException 错误。 -
在微服务注册中心 Consul 中查看是否出现相关微服务名称,若有表示微服务入驻成功。查看方法与上面一致。
-
测试,在浏览器中输入网址 http://localhost/consumer/pay/get/4,查看是否成功响应。若显示以下信息表示微服务注册中心入驻成功。
1.2.2.3 三个注册中心的异同
CAP:“C”表示 Consistency→强一致性,“A”表示 Availability →可用性,“P”表示 Partition tolerance→分区容错性。
CAP 理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
CAP 原理图如下所示。
AP架构:Eureka
当网络分区出现后,为了保证可用性,系统B可以返回旧值,保证系统的可用性。当数据出现不一致时,虽然A, B上的注册信息不完全相同,但每个Eureka节点依然能够正常对外提供服务,这会出现查询服务信息时如果请求A查不到,但请求B就能查到。如此保证了可用性但牺牲了一致性结论:违背了一致性C的要求,只满足可用性和分区容错,即AP。
CP架构:Zookeeper/Consul
当网络分区出现后,为了保证一致性,就必须拒接请求,否则无法保证一致性,Consul 遵循CAP原理中的CP原则,保证了强一致性和分区容错性,且使用的是Raft算法,比zookeeper使用的Paxos算法更加简单。虽然保证了强一致性,但是可用性就相应下降了,例如服务注册的时间会稍长一些,因为 Consul 的 raft 协议要求必须过半数的节点都写入成功才认为注册成功 ;在leader挂掉了之后,重新选举出leader之前会导致Consul 服务不可用。结论:违背了可用性A的要求,只满足一致性和分区容错,即CP。
1.2.3 服务配置与刷新
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。比如某些配置文件中的内容大部分都是相同的,只有个别的配置项不同。就拿数据库配置来说吧,如果每个微服务使用的技术栈都是相同的,则每个微服务中关于数据库的配置几乎都是相同的,有时候主机迁移了,我希望一次修改,处处生效。当下我们每一个微服务自己带着一个application.yml,上百个配置文件的管理…/(ㄒoㄒ)/~~。
分布式配置管理的配置要求可参考网址:https://docs.spring.io/spring-cloud-consul/reference/config.html
1.2.3.1 服务配置
本节主要设置支付微服务8001的分布式配置管理,具体设置步骤如下所述。
-
在 pom.xml 文件中导入以下依赖。
<!--SpringCloud consul config--> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-consul-config</artifactId> </dependency> <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
-
设置配置文件信息
applicaiton.yml是用户级的资源配置项。
bootstrap.yml是系统级的,优先级更加高。
Spring Cloud会创建一个“Bootstrap Context”,作为Spring应用的
Application Context
的父上下文。初始化的时候,Bootstrap Context
负责从外部源加载配置属性并解析配置。这两个上下文共享一个从外部获取的Environment
。Bootstrap
属性有高优先级,默认情况下,它们不会被本地配置覆盖。Bootstrap context
和Application Context
有着不同的约定,所以新增了一个bootstrap.yml
文件,保证Bootstrap Context
和Application Context
配置的分离。application.yml 文件改为bootstrap.yml,这是很关键的或者两者共存
因为 bootstrap.yml 是比 application.yml 先加载的。bootstrap.yml 优先级高于application.yml。
-
添加新的配置文件 bootstrap.yml ,该文件是系统配置文件,优先级高于 application.yml 配置文件。
spring:application:name: cloud-payment-service####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:service-name: ${spring.application.name}config:profile-separator: '-' # default value is ",",we update '-'format: YAML# config/cloud-payment-service/data # /cloud-payment-service-dev/data # /cloud-payment-service-prod/data
-
用户级别的资源配置文件 application.yml 文件。
server:port: 8001# ==========applicationName + druid-mysql8 driver=================== spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=trueusername: rootpassword: rootprofiles:active: dev# ========================mybatis=================== mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.atguigu.entitiesconfiguration:map-underscore-to-camel-case: true
-
-
业务层 Controller 的业务添加。
@Value("${server.port}")private String port;@GetMapping("/get/info")public String getInfo(@Value("${atguigu.info}") String atguiguInfo){return "atguigu.info:"+atguiguInfo+"port:"+port;}
-
在服务注册中心 Consul 中配置 Key/Value。配置规则可参考下图信息。
启动订单微服务80和支付微服务8001,还有注册中心 consul。注册中心的启动命令和方式在1.2.1节已经讲过,所以此处不在赘述。
请按照以下图片创建目录和 data 文件。
在每个目录下输入上图类似信息,只修改 prod=3部分。
-
测试网址localhost:8001/pay/get/info结果,如下图所示表示配置成功。
1.2.3.2 动态刷新
当我们配置了注册中心 Consul 的 data 文件数据后访问网站并不能马上生效,这是我们只需要在主启动类8001添加类注解@RefreshScope
再在系统配置文件中添加配置spring.cloud.consul.config.watch.wait-time
,该配置可自由设置等待时间。
spring:application:name: cloud-payment-service####Spring Cloud Consul for Service Discoverycloud:consul:host: localhostport: 8500discovery:service-name: ${spring.application.name}config:profile-separator: '-' # default value is ",",we update '-'format: YAMLwatch:wait-time: 1# config/cloud-payment-service/data
# /cloud-payment-service-dev/data
# /cloud-payment-service-prod/data
思考:截至目前,当我们关闭注册中心后重新打开,里面的配置信息消失了,没有持久性保存,我们要如何才能使其具有持久性?
上一页 1-springcloud-支付微服务准备