Conusl可以作为注册中心,也可以作为配置中心。

作为配置中心,使用起来也很方便,大多数都是配置。

Consul的安装这里不说了,主要是说明java后端怎么使用,所以本次采用windows版本的consul。

引入和配置

2个文件:

pom配置:

<!-- consul配置中心 -->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-consul-config</artifactId>

</dependency>

<!-- 使用 @EnableConfigurationProperties 开启 @ConfigurationProperties 注解 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-configuration-processor</artifactId>

<optional>true</optional>

</dependency>

bootstrap.yml

spring:

profiles:

active: dev

cloud:

consul:

host: 127.0.0.1  #注册中心的ip或host。也是集群地址,配置一个即可。注释掉整个consul这段就可以启动,即使没有注册中心也不报错。有这段就必须有一个可用的注册中心,否则启动报错

port: 8500

discovery:

enabled: true #默认true。Consul Discovery Client是否注册到注册中心。和register同时设置成false,就不需要起consul服务。

register: true #是否将服务注册到Consul集群中心.。这个参数和上面的enabled参数同时设置成false,应用才不会注册注册中心,才可以不起consul服务!

deregister: true #默认true,服务停止时注销服务,即从服务列表中删除。设置成false的话,???

#service-name: ${spring.application.name}  #注册在consul上面的名字,在consul的调用中,是通过此名字调用的。默认服务名,不要改

instance-id: ${spring.application.name}-${spring.cloud.client.ip-address}:${server.port} #只供显示用,在ID列显示

health-check-interval: 5s  #配置 Consul 健康检查频率,也就是心跳频率。

#        health-check-critical-timeout: 2s #健康检查失败多长时间后,取消注册。在node上显示红色叉。配了这个参数,如果consul集群的server重启会注销应用!

#健康检查路径。默认是使用actuator的健康检查接口:http://localhost:8901/actuator/health返回{"status":"UP"}。其实只看http状态码是200就认为服务正常。你可以换成自己的一个rest接口替代actuator

#health-check-path: /hello

prefer-ip-address: true #表示注册时使用IP而不是hostname

retry:

initial-interval: 5000   # 服务监测时间间隔

max-attempts: 20

#consul作为配置中心,官网属性https://docs.spring.io/spring-cloud-consul/docs/2.2.4.RELEASE/reference/html/appendix.html

config:

enabled: true          # 启用 consul 配置中心.默认是true

format: YAML           # 配置转码方式,默认 key-value,其他可选:yaml/files/properties

data-key: data         # 配置 key 值,value 对应整个配置文件。例如config/application,dev/data

prefix: config         # 基础文件夹,默认值 config.

default-context: one  #应用文件夹,默认值 application,consul 会加载 config/<applicationName> 和 config/<defaultContext> 两份配置,设置为相同值,则只加载一份.sets the folder name used by all applications

#        profile-separator: '-'   #环境分隔符,默认值 ",例如例如config/application,dev/data修改后是config/application-dev/data

watch:

enabled: true         # 启用配置自动刷新

delay: 1000           # 刷新频率,单位:毫秒

servlet:

multipart:

enabled: true

max-file-size: 100MB

max-request-size: 300MB

到此为止,consul作为配置中心就可以使用了。

要注意,consul作为配置中心,一些配置项在应用启动的时候就需要加载和初始化了,所以consul的配置必须写在bootstrap.yml

我们可以将welcom.value属性写入配置文件中,但要注意,配置中心的配置优先级高于本地配置文件.

如果本地配置文件不存在,配置中心也没有,启动会报错的.

注意,需要变更配置的类上,要加@RefreshScope注解,否则不会刷新配置。

(网上有人做实验,就是没有加@RefreshScope注解,所以才说@Value不会刷新consul修改后的值,只有@ConfigurationProperties才会。原因就是没有加@RefreshScope注解)

先说结论:consul作为配置中心,既然必须配置在bootstrap.yml,那地址只能写死了。如果有多个环境怎么办?其实一个配置中心也是支持多个环境的,配置中心就是把原来使用的bootstrap.yml,application.yml,application-dev.yml,application-test.yml搬到了consul的内存中而已,并且取值的优先级比这些配置文件高,其他使用并没有区别。

那么多个环境还是跟以前一样,通过

spring:

profiles:

active: dev

指定使用哪套配置就行了,没必要每个环境搭建一套consul。

实际情况,我们确实每个环境搭建了一套consul,毕竟生产环境和开发环境是物理隔离的。

对于bootstrap.yml里我们必须要按环境分开配置的项怎么办?我们可以使用环境变量参数来修改,例如java -jar -Dspring.profiles.active=test -Dspring.cloud.consul.host=192.168.1.18

参考springboot启动时加载参数的顺序优先级:

启动时读取参数属性顺序:

Spring Boot允许您外部化配置,以便您可以在不同的环境中使用相同的应用程序代码。您可以使用属性文件,YAML文件,环境变量和命令行参数来外部化配置。属性值可以通过直接注射到你的bean @Value注释,通过Spring的访问Environment抽象,或者被 绑定到结构化对象通过@ConfigurationProperties。Spring Boot使用一种非常特殊的PropertySource顺序,旨在允许合理地覆盖值。按以下顺序考虑属性:

  1. Devtools 主目录上的全局设置属性(当devtools处于活动状态时,配置是~/.spring-boot-devtools.properties)。
  2. @TestPropertySource 你的测试注释。
  3. properties属性测试。可 用于测试特定应用程序片段[url=https://docs.spring.io/spring-boot/docs/2.1.2.RELEASE/api/org/springframework/boot/test/context/SpringBootTest.html]@SpringBootTest[/url]的 测试注释。
  4. 命令行参数。
  5. 来自SPRING_APPLICATION_JSON(嵌入在环境变量或系统属性中的内联JSON)的属性。
  6. ServletConfig init参数。
  7. ServletContext init参数。
  8. JNDI属性来自java:comp/env。
  9. Java系统属性(System.getProperties())。
  10. OS环境变量。
  11. 一RandomValuePropertySource,只有在拥有性能random.*。
  12. 特定于配置文件的应用程序属性在打包的jar(application-{profile}.properties和YAML变体)之外。
  13. 打包在jar中的特定于配置文件的应用程序属性(application-{profile}.properties 以及YAML变体)。
  14. 打包jar之外的应用程序属性(application.properties以及YAML变体)。
  15. 打包在jar中的应用程序属性(application.properties和YAML变体)。
  16. @PropertySource 你@Configuration班上的注释。
  17. 默认属性(由设置指定SpringApplication.setDefaultProperties

既然可以把之前的配置文件内容搬到consul里,那么,我们可以把整个配置文件的内容复制到consul中就可以了,这是一套使用方式。

还有一种使用方式,我使用consul的配置中心是为了动态修改配置,我在consul里初始时不配置任何属性值。这样应用会使用配置文件的值。当我需要修改某个值时,我在consul里去修改这个值,然后应用读取最新的值。

测试

测试配置类

写个配置项

mytest:

myname: lsy

myaddress: bejing

mysalary:

在写个查看该值的controller,用于测试应用中的值是什么。

/one/src/main/java/com/example/one/bean/MyTestBean.java

package com.example.one.bean;

import javax.annotation.PostConstruct;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**

* 在另一个类中使用@EnableConfigurationProperties(MyTestBean.class) 就注释掉@Component

* @author lsy

*

*

*ignoreUnknownFields = false告诉Spring Boot在有属性不能匹配到声明的域的时候抛出异常。

*开发的时候很方便! prefix 用来选择哪个属性的prefix名字来绑定。

*/

//@Component

//@ConfigurationProperties(prefix = "mytest")

@ConfigurationProperties(prefix = "mytest", ignoreInvalidFields = true)

public class MyTestBean {

private String myname;

private String myaddress;

private String mysalary;//测试ignoreInvalidFields,如果没有改属性,是否报错

public String getMyname() {

return myname;

}

public void setMyname(String myname) {

this.myname = myname;

}

public String getMyaddress() {

return myaddress;

}

public void setMyaddress(String myaddress) {

this.myaddress = myaddress;

}

public String getMysalary() {

return mysalary;

}

public void setMysalary(String mysalary) {

this.mysalary = mysalary;

}

/*

* 在对象构建后打印一下.

* 经测试世纪打印:

*

* MyTestBean toPrint: [myname=lsy, myaddress=bejing, mysalary=null]

*

*/

@PostConstruct

public String toPrint() {

String str= " [myname=" + myname + ", myaddress=" + myaddress + ", mysalary=" + mysalary + "]";

System.out.println("MyTestBean toPrint:"+str);

return str;

}

}

/one/src/main/java/com/example/one/config/ConfigCenterConfig.java

package com.example.one.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.context.annotation.Configuration;

import com.example.one.bean.MyTestBean;

/**

* 配置中心相关

*

* 这类测试了一个注解的使用

*

* @ConfigurationProperties

* @Component

* @EnableConfigurationProperties

* 这3个注解的关系

*

* @EnableConfigurationProperties注解的作用是:使使用 @ConfigurationProperties 注解的类生效。

* 定义一个配置类的时候,我们可以把这个类直接用@Component声明并注入spring容器,也可以不用@Component,然后再另一个@Configuration的类中

* 显示的使用@Bean注入到spring容器中。

*

* 还有另外一种方式:不使用@Component,也不在@Configuration的类中使用@Bean,

* 而是在@Configuration的类中使用注解@EnableConfigurationProperties,指定那个类。

* @EnableConfigurationProperties就是告诉spring容器需要生成这个bean

* 请看下面的例子

*

*

*

* @author lsy

*

*/

@Configuration

@EnableConfigurationProperties(MyTestBean.class)

@ConditionalOnClass(MyTestBean.class)

public class ConfigCenterConfig {

}

/one/src/main/java/com/example/one/controller/ConfigCenterController.java

package com.example.one.controller;

import java.time.LocalDateTime;

import java.time.format.DateTimeFormatter;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.cloud.context.config.annotation.RefreshScope;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import com.example.one.bean.MyTestBean;

/**

* 使用consul作为配置中心的测试

*

* 一个方法用于查看这些属性的值,比较用@Value和 @Autowired加@ConfigurationProperties 两种方式的区别

*

*  @RefreshScope

* 有人做过实验,说consul作为配置中心,修改值后,@Value的对象值不变,还是之前的,@ConfigurationProperties对象的值就变了,是最新的。

* 其实是没有加@RefreshScope注解导致的。

*

*

* @author lsy

*

*/

@RestController

@RequestMapping("/config")

@RefreshScope

public class ConfigCenterController {

@Value("${mytest.myname}")

private String myname;

@Value("${mytest.myaddress}")

private String myaddress;

/**

* @Value("${mytest.mysalary:100万}")

* 冒号后跟的是默认值,要注意:不是在配置文件中这个属性为空才是用默认值,而是在属性文件中根本配有这个属性采用默认值。

* 如果你在属性文件中配置了这个属性,但是值没写东西,那么这个值也算是配置了,所以默认值不会起作用。

* 另外要注意,如果没有默认值,那么你在属性文件中必须配置这个属性,不然spring在做映射的时候找不到这个属性就报错了。

* 所以,一些对程序不重要的属性,可有可无,就配置上这个默认值。保证程序不会应为配置文件中少了这个属性导致应用无法启动。

*

* @Value这个注解有这个限制,@ConfigurationProperties没有这个限制,@ConfigurationProperties找不到对应的属性值就是null,不会报错。

*

*/

@Value("${mytest.mysalary:100万}")

// @Value("${mytest.mysalary}")

private String mysalary;

@Autowired

private MyTestBean myTestBean;

/**

*

@RefreshScope

* 有人做过实验,说consul作为配置中心,修改值后,@Value的对象值不变,还是之前的,@ConfigurationProperties对象的值就变了,是最新的。

* 其实是没有加@RefreshScope注解导致的。

* @return

*/

@GetMapping(value="/queryValue")

public String queryValue() {

DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");//LocalDateTime startTime = LocalDateTime.now();

String timeNow=LocalDateTime.now().format(df);

String message="Value方式返回:myname=["+myname+"],myaddress=["+myaddress+"],mysalary=["+mysalary+"] ";

message+="<br>";

message+="对象方式返回:myTestBean="+myTestBean.toPrint();

System.out.println(message);

return message;

}

}

测试配置中心步骤

访问consul的UI控制台,点击Key/Value菜单

按照我们的配置

config:

enabled: true          # 启用 consul 配置中心.默认是true

format: YAML           # 配置转码方式,默认 key-value,其他可选:yaml/files/properties

data-key: data         # 配置 key 值,value 对应整个配置文件。例如config/application,dev/data

prefix: config         # 基础文件夹,默认值 config.

default-context: one  #应用文件夹,默认值 application,consul 会加载 config/<applicationName> 和 config/<defaultContext> 两份配置,设置为相同值,则只加载一份.sets the folder name used by all applications

#        profile-separator: '-'   #环境分隔符,默认值 ",例如例如config/application,dev/data修改后是config/application-dev/data

watch:

enabled: true         # 启用配置自动刷新

delay: 1000           # 刷新频率,单位:毫秒

最上层目录必须是config,创建目录的时候加斜杠/就可以了,如果创建文件就不要加。

最下层是文件,我们配置的是data,

中间是各个环境的配置。

比如,要把application.yml的文件内容迁移过来,我们就在config下建立one目录;

如果要把application-dev.yml的文件内容迁移过来,我们就在config下建立one,dev目录(这个目录全名就是“one,dev”)。

(逗号是默认的,你可以通过profile-separator改成其他符号)

步骤:

把config和one建立好后,再建data,这时候注意data是文件,不要加斜杠了。

里面的内容,直接把application.yml的内容全部复制进去就好,格式选择yml

这样,application.yml就迁移到配置中心了。

同理,我们在config下建立目录“one,dev”,再建立data文件,把application-dev.yml的内容全部复制进去。

到此,因为配置中心的优先级比yml文件高,其实本地的yml文件除了bootstrap.yml,其他就可以删掉了。

留着也不会报错,应用优先取配置中心的。

Yml文件中的配置项本身都是一段段的,所以我们也可以在初始的时候,consul里面的data都是空,这样应用先使用yml文件的配置。我们想在不重启应用的情况下去修改某个配置就可以把需要修改的项(也可以把整个yml文件内容写入data),写入consul的data中。这样应用自动就获取了。

访问controller查看配置项的值

修改配置中心的值

再访问:

有人做过实验,说consul作为配置中心,修改值后,@Value的对象值不变,还是之前的,@ConfigurationProperties对象的值就变了,是最新的。

其实是没有加@RefreshScope注解导致的。

总结

搭建开发测试生产环境。

在有api网关的情况下,这样搭建环境。

首先,生产环境只能是独立的一套。

生产环境使用环境变量参数指定环境

java -jar -Dspring.profiles.active=prod -Dspring.cloud.consul.host=192.168.1.18

这样bootstrap.yml中的配置对生产环境无效了。

那么开发和测试环境怎么配置?

开发和测试使用同一个consul:

(这里的开发环境指开发人员的电脑环境)

首先考虑注册中心,如果开发和测试用一个consul,那么api网关转发请求就会把两个环境搞乱。为了不乱,开发环境的注册中心配置就必须关闭。

即:

把discovery的enabled和register改成false。

spring:

profiles:

active: dev

cloud:

consul:

host: 127.0.0.1  #注册中心的ip或host。也是集群地址,配置一个即可。注释掉整个consul这段就可以启动,即使没有注册中心也不报错。有这段就必须有一个可用的注册中心,否则启动报错

port: 8500

discovery:

enabled: false #默认true。Consul Discovery Client是否注册到注册中心。和register同时设置成false,就不需要起consul服务。

register: false #是否将服务注册到Consul集群中心.。这个参数和上面的enabled参数同时设置成false,应用才不会注册注册中心,才可以不起consul服务!

deregister: true #默认true,服务停止时注销服务,即从服务列表中删除。设置成false的话,???

#service-name: ${spring.application.name}  #注册在consul上面的名字,在consul的调用中,是通过此名字调用的。默认服务名,不要改

instance-id: ${spring.application.name}-${spring.cloud.client.ip-address}:${server.port} #只供显示用,在ID列显示

health-check-interval: 5s  #配置 Consul 健康检查频率,也就是心跳频率。

#        health-check-critical-timeout: 2s #健康检查失败多长时间后,取消注册。在node上显示红色叉。配了这个参数,如果consul集群的server重启会注销应用!

#健康检查路径。默认是使用actuator的健康检查接口:http://localhost:8901/actuator/health返回{"status":"UP"}。其实只看http状态码是200就认为服务正常。你可以换成自己的一个rest接口替代actuator

#health-check-path: /hello

prefer-ip-address: true #表示注册时使用IP而不是hostname

retry:

initial-interval: 5000   # 服务监测时间间隔

max-attempts: 20

#consul作为配置中心,官网属性https://docs.spring.io/spring-cloud-consul/docs/2.2.4.RELEASE/reference/html/appendix.html

config:

enabled: true          # 启用 consul 配置中心.默认是true

format: YAML           # 配置转码方式,默认 key-value,其他可选:yaml/files/properties

data-key: data         # 配置 key 值,value 对应整个配置文件。例如config/application,dev/data

prefix: config         # 基础文件夹,默认值 config.

default-context: one  #应用文件夹,默认值 application,consul 会加载 config/<applicationName> 和 config/<defaultContext> 两份配置,设置为相同值,则只加载一份.sets the folder name used by all applications

#        profile-separator: '-'   #环境分隔符,默认值 ",例如例如config/application,dev/data修改后是config/application-dev/data

watch:

enabled: true         # 启用配置自动刷新

delay: 1000           # 刷新频率,单位:毫秒

servlet:

multipart:

enabled: true

max-file-size: 100MB

max-request-size: 300MB

这时候开发环境就不用注册中心了,因为大家在本地写代码的时候都是单实例启动,不需要注册中心。而配置中心和测试环境是一个consul,不同的spring.profiles.active参数。

bootstrap.yml写的是dev,测试环境用命令行参数覆盖:

java -jar -Dspring.profiles.active=test -Dspring.cloud.consul.host=192.168.1.11 -Dspring.cloud.consul.discovery.enabled=true -Dspring.cloud.consul.discovery.register=true

这样开发环境不使用注册中心,但是使用测试环境的配置中心,使用配置中心的spring.profiles.active是dev。而测试环境既使用注册中心,也使用配置中心spring.profiles.active=test。

开发和测试使用不同consul:

这种情况和生产环境就一样了,每个环境搭建一套consul,互不影响。

在这种情况下,开发环境也可以关闭注册中心。同时配置中心的配置不方便每个开发人员各自改本地的配置,所以建议把配置中心的配置都删除,让开发人员使用本地yml文件更直观。

附录

Springcloud的cosnul相关文档

所有属性值在这个链接里:https://docs.spring.io/spring-cloud-consul/docs/2.2.4.RELEASE/reference/html/appendix.html

consul作为配置中心相关推荐

  1. SpringCloud Consul Config 配置中心 (二)

    上次配置中心启动命令为consul agent -dev,这样数据不会持久化,重新启动consul后key/value配置的信息会丢失. 实现数据持久化,使用如下命令启动,-data-dir 为数据保 ...

  2. Consul作为配置中心,配置Asp.Net Core应用程序 依据key/value动态更新

    Consul作为配置中心,配置Asp.Net Core应用程序 依据key/value自动更新 https://github.com/wintoncode/Winton.Extensions.Conf ...

  3. SpringCloud使用Consul作为配置中心

    目录 一.前言 二.初始化配置 三.代码练习 1. 创建cloud-consul-configdemo8007项目 2. 修改配置 3. 添加主启动类 4. 读取配置文件 5. 添加controlle ...

  4. Spring Cloud 采用Consul做配置中心

    -----------------pom.xml依赖,主要是spring-cloud-starter-consul-config <dependency><groupId>or ...

  5. SpringCloud Consul Config 配置中心(一)

    用 Consul 存储键值对,实现分布式配置中心,支持不需要重启配置中心服务就能读取更新后的属性. 在前面开发基础上,稍作调整,暂只调整日志服务. 1.在日志服务里添加maven依赖 <depe ...

  6. consul java_springcloud使用consul作为配置中心

    也就是说在我们使用consul config时最好在consul 建立相应的目录结构 适用于某一个服务的目录结构以及适用于所有的服务的目录结构 本列consul web UI :springboot为 ...

  7. .NET Core with 微服务 - Consul 配置中心

    上一次我们介绍了Elastic APM组件.这一次我们继续介绍微服务相关组件配置中心的使用方法.本来打算介绍下携程开源的重型配置中心框架 apollo 但是体系实在是太过于庞大,还是让我爱不起来.因为 ...

  8. 第4关 注册配置中心实现

    复杂的不是代码,而是问题本身.--ta说 第4关 注册配置中心实现 4.1 注册中心的基本介绍 4.2 注册中心的安装 4.3 分类模块目录结构生成 4.4 编写对外暴露的服务 4.5 数据库进行交互 ...

  9. 微服务配置中心, 这个方案 Go 里用起来不输 SpringCloud

    微服务架构设计模式里有一条讲到,要设计可配置的服务.把服务从单体架构细分成微服务后,所有配置属性都集中存储在一个位置,更易于管理.这个集中存储管理配置的地方,就是配置中心. 使用配置中心还有一个好处就 ...

最新文章

  1. Python多线程thread与threading实现
  2. Android adb你真的会用吗?
  3. notepad++安装
  4. matlab仿真生成信号程序,信号与系统的MATLAB仿真
  5. 电流源并联怎么合并_一种特殊的并联切换电力系统,长见识了
  6. python36 mysql_python-day36(初识MySQL数据库)
  7. angular2.0中为什么初始化的时候就把全部路由下的模板文件加载出来的原因。
  8. Waymo捷豹合推电动无人车I-PACE,将加入无人出租车队
  9. 算法导论 资源 课后答案 PDF
  10. Cisco常见命令大全
  11. Oracle11g软硬件基本要求,Oracle 11g的安装
  12. C++使用librdkafka创建消费者和生产者
  13. 数模电路基础知识 —— 7. PN结与二极管的工作原理
  14. 计算机基础之二进制详解(二)
  15. Redis数据结构-字符串对象(SDS)
  16. Lrc文件与音乐的同步显示
  17. Python 命令行参数:Argparse 与 Click
  18. 无法打开位置服务器,电脑的定位功能无法打开怎么办?
  19. linux中可以使用以下命令查看文件内容,在Linux服务器中使用命令行中查看文件内容...
  20. Tranformer模型与Softmax函数

热门文章

  1. 把视频转换成gif动图的最简单方法
  2. (转载)混合图层算法
  3. 你知道怎么选择线上培训学校吗
  4. QTime QDate
  5. 设计模式之桥接模式详解(附应用举例实现)
  6. 正交频分复用(OFDM)原理及实现
  7. C# Linq 未将对象引用设置到对象的实例
  8. signature=1435e157ebdd6880f63875e99a78e7c4,英语课堂学生英汉语码转换的动机分析
  9. Windows 7定时关机命令(很实用)
  10. 二分查找法(函数binary_search)