此处要说明一下wait-time属性,此属性是设置调用consul的接口方法时会阻塞指定的时间,如果在阻塞过程中有配置修改则立马返回,否则要等到阻塞时间结束,delay属性指的是在上次调用接口结束之后多久开始下一次调度;

1.ConfigWatch定时任务配置方法
	@Override
	public void start() {
		if (this.running.compareAndSet(false, true)) {
			this.watchFuture = this.taskScheduler.scheduleWithFixedDelay(this::watchConfigKeyValues,
					this.properties.getWatch().getDelay());
 

指定一个固定的线程池,每次在上次任务执行完成后间隔指定的时间执行下次任务;

2.watchConfigKeyValues监视器任务方法
	@Timed("consul.watch-config-keys")
	public void watchConfigKeyValues() {
		if (!this.running.get()) {
			return;
		for (String context : this.consulIndexes.keySet()) {
			  ...
        //通过API调度获取配置中心配置信息,接口阻塞指定的超时时间,默认是:55s
				Response<List<GetValue>> response = this.consul.getKVValues(context, aclToken,
						new QueryParams(this.properties.getWatch().getWaitTime(), currentIndex));
				// if response.value == null, response was a 404, otherwise it was a
				// 200, reducing churn if there wasn't anything
				if (response.getValue() != null && !response.getValue().isEmpty()) {
          // 获取配置中心的新版本
					Long newIndex = response.getConsulIndex();
					if (newIndex != null && !newIndex.equals(currentIndex)) {
						// 判定新版本和老版本是否一样,不同则发布事件刷新
						if (!this.consulIndexes.containsValue(newIndex) && !currentIndex.equals(-1L)) {
							if (log.isTraceEnabled()) {
								log.trace("Context " + context + " has new index " + newIndex);
							RefreshEventData data = new RefreshEventData(context, currentIndex, newIndex);
              //发布刷新本地配置事件
							this.publisher.publishEvent(new RefreshEvent(this, data, data.toString()));
						else if (log.isTraceEnabled()) {
							log.trace("Event for index already published for context " + context);
						this.consulIndexes.put(context, newIndex);
				...
 

上述监视器方法监测到配置变化会发布RefreshEvent事件,该事件会被RefreshEventListener监听器监听

3.RefreshEventListener监听器
public class RefreshEventListener implements SmartApplicationListener {
	private static Log log = LogFactory.getLog(RefreshEventListener.class);
	private ContextRefresher refresh;
	private AtomicBoolean ready = new AtomicBoolean(false);
	public RefreshEventListener(ContextRefresher refresh) {
		this.refresh = refresh;
	@Override
	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
		return ApplicationReadyEvent.class.isAssignableFrom(eventType)
				|| RefreshEvent.class.isAssignableFrom(eventType);
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof ApplicationReadyEvent) {
			handle((ApplicationReadyEvent) event);
		else if (event instanceof RefreshEvent) {
			handle((RefreshEvent) event);
	public void handle(ApplicationReadyEvent event) {
		this.ready.compareAndSet(false, true);
	public void handle(RefreshEvent event) {
		if (this.ready.get()) { // don't handle events before app is ready
			log.debug("Event received " + event.getEventDesc());
      //调用ContextRefresher刷新配置方法
			Set<String> keys = this.refresh.refresh();
			log.info("Refresh keys changed: " + keys);

GitHub地址:https://github.com/mingyang66/EmilyGateway

熟能生巧,通过实战发现问题,解决问题。 在之前系列基础上,在主工程里添加一个common模块,提供 Redis 工具, 从Consul Config 配置中心读取 Redis 配置,然后在订单服务里引用Common模块。 1、maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</a <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-cloud-starter-consul-config</artifactId> </dependency> 一、什么是consul Consul是HashiCorp公司推出的开源工具,Consul由Go语言开发,部署起来非常容易,只需要极少的可执行程序和配置文件,具有绿色、轻量级的特点。Consul是分布式的、高可用的、 可横向扩展的用于实现分布式系统的服务发现与配置。 二、consul的功能 1)服务发现:Consul提供了通过DNS或者HTTP接口的方式来注册服务和发现服务。一些外部的服务通过Consul很容易的找到它所依赖的服务。 2)健康检测:Consul的Client提供了健康检查的机制,可以通 这一篇文章我们主要学习Consul作为配置中心来使用,每一个步骤都很详细,包括Consul管理界面的介绍与使用,ConsulSpringCloudConfig相比较而言,不需要额外的git、svn、数据库等配合,且无需配合Bus即可实现配置刷新。...... Consul 是用于分布式系统服务发现与配置,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案。Consul是使用Go语言编写的,使用很方便。有个需求,配置文件里面的参数经常会调整,变动后需要实时获取,今天来实现监听consul中key/value 数据的变化。在ubuntu安装consul配置启动服务, $ wget https://releases.hashicorp.com/consul/1.2.0/consul_1.2.0_linux_amd64.z