Cloud之Consul
Cloud之Consul
Consul作为新一代服务注册中心和分布式配置,官网:https://www.consul.io
下载安装
https://developer.hashicorp.com/consul/downloads
下载完成后只有一个consul.exe文件,全路径下查看版本号信息

开发者模式启动
consul agent -dev
访问路径
http://localhost:8500

服务注册与发现
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
yml配置
####Spring Cloud Consul for Service Discovery
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
主启动类开启服务发现
@SpringBootApplication
@MapperScan("org.cloud.mapper")
@EnableDiscoveryClient
public class Main8001
{
public static void main(String[] args)
{
SpringApplication.run(Main8001.class,args);
}
}
启动服务并查看consul控制台

经过以上步骤就一个将一个服务注册到consul中进行管理
服务配置与刷新
面临问题
微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务。由于每个服务都需要必要的配置信息才能运行,所以一套集中式的、动态的配置管理设施是必不可少的。比如某些配置文件中的内容大部分都是相同的,只有个别的配置项不同。就拿数据库配置来说吧,如果每个微服务使用的技术栈都是相同的,则每个微服务中关于数据库的配置几乎都是相同的,有时候主机迁移了,我希望一次修改,处处生效。
作用:一次修改,处处生效
需求:
通用全局配置信息,直接注册进consul服务器,从consul获取 既然从consul获取自然要遵守consul的配置规则要求
实践
操作对象:修改cloud-payment-service8001服务
1、导入依赖
<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>
2、新增配置文件bootstrap.yml
bootstrap.yml是什么呢?:
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
配置内容
将原来application.yml中consul的一些配置抽到bootstrap.yml中
spring:
application:
name: cloud-payment-service
####Spring Cloud Consul for Service Discovery
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
config:
profile-separator: '-' # default value is ",",we update '-'
format: YAML
原来的application.yml文件内容
server:
port: 8001
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/cloud_24?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: root
password: '020708'
# Spring Cloud Consul for Service Discovery
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
# ========================mybatis===================
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: org.cloud.entity
configuration:
map-underscore-to-camel-case: true
抽离后的文件
server:
port: 8001
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/cloud_24?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
username: root
password: '020708'
profiles:
active: dev # 多环境配置加载内容dev/prod,不写就是默认default配置
# ========================mybatis===================
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: org.cloud.entity
configuration:
map-underscore-to-camel-case: true
3、consul服务器k/v配置填写

为什么要配置k/v配置填写呢,因为规则是人家定的,要遵守规矩配置,步骤如下
1、创建config文件夹,以/结尾
2、config文件夹下分别创建3个文件夹,分别为默认环境:cloud-payment-service;开发环境:cloud-payment-service-dev;生产环境:cloud-payment-service-prod这几个文件后缀名分别对应着application.yml中的profiles: active: dev这个参数。
3、上述3个文件夹下分别创建data内容,data不再是文件夹


data中的内容
cloud:
info: welcometoclouddefaultstudy
4、测试:测试是否可以读取到配置好的内容
@Value("${server.port}")
private String port;
@GetMapping(value = "/pay/get/info")
private String getInfoByConsul(@Value("${cloud.info}") String cloudInfo)
{
return "cloudInfo: "+cloudInfo+"\t"+"port: "+port;
}
可以看到我们已经读取到了内容

5、问题引出
我们将consul服务器起上的dev配置内容修改后,不能及时读取到修改后的值,没有做到及时响应和动态刷新

原因:这是因为没有开启及时刷新注解,还有一个原因就是并不是不会修改,而是官方默认要等待55s修改后的配置内容才会生效

解决方案:
启动类添加刷新注解
@SpringBootApplication
@MapperScan("com.atguigu.cloud.mapper") //import tk.mybatis.spring.annotation.MapperScan;
@EnableDiscoveryClient //服务注册和发现
@RefreshScope // 动态刷新
public class Main8001
{
public static void main(String[] args)
{
SpringApplication.run(Main8001.class,args);
}
}
修改bootstrap.yml配置文件:将官方默认的55s修改为1s
spring:
application:
name: cloud-payment-service
####Spring Cloud Consul for Service Discovery
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
config:
profile-separator: '-' # default value is ",",we update '-'
format: YAML
#实际生产不建议修改
watch:
wait-time: 1
6、持久化问题
以上所有的配置,如果关闭了consul,所有的配置文件立即丢失,需要做持久化配置处理
解决:解决持久化并加入到后台启动
1、在consul同级目录下新建MyData文件夹存放配置文件进行持久化,再放一个脚本实现后台开机自启

2、右键管理员方式启动
启动错误:第一次启动会提示启动失败,服务已经被启动,这时候以管理员身份执行cmd,然后sc delete
consul,最后再执行.bat文件即可

3、后续consul的配置文件就保存在mydata文件夹中了,启动就有