跳至主要內容

Cloud之Consul

sixkey大约 5 分钟后端SpringCloud微服务Consul

Cloud之Consul

Consul作为新一代服务注册中心和分布式配置,官网:https://www.consul.io

下载安装

https://developer.hashicorp.com/consul/downloads

下载完成后只有一个consul.exe文件,全路径下查看版本号信息

screenshot-1712817095119
screenshot-1712817095119

开发者模式启动

consul agent -dev

访问路径

http://localhost:8500
screenshot-1712817225728

服务注册与发现

依赖

<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控制台

screenshot-1712818936175
screenshot-1712818936175

经过以上步骤就一个将一个服务注册到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 contextApplication Context有着不同的约定,所以新增了一个bootstrap.yml文件,保证Bootstrap ContextApplication 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配置填写

screenshot-1712821630127

为什么要配置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不再是文件夹

screenshot-1712822054433screenshot-1712822233783

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;
    }

可以看到我们已经读取到了内容

screenshot-1712822912151

5、问题引出

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

screenshot-1712823307970

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

screenshot-1712823608668

解决方案:

启动类添加刷新注解

@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文件夹存放配置文件进行持久化,再放一个脚本实现后台开机自启

screenshot-1712825026182
screenshot-1712825026182

2、右键管理员方式启动

启动错误:第一次启动会提示启动失败,服务已经被启动,这时候以管理员身份执行cmd,然后sc delete

consul,最后再执行.bat文件即可

screenshot-1712825935157
screenshot-1712825935157

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