【SpringBoot 004】 整合consul

一、注册中心

1、pom.xml

在pom.xml 引入 spring-cloud-starter-consul-discovery 配置

		<!--	consul 注册中心	-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
		</dependency>

2、启动类:SpringBootDemoApplication

在 SpringBootDemoApplication 上加上 EnableDiscoveryClient 注解

package com.example.springbootdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient // consul 注册必须加上这个注解
public class SpringBootDemoApplication {

	//@EnableAutoConfiguration注解通过@SpringBootApplication注解被间接的标记在了SpringBoot的启动类上,
	// SpringApplicaton.run方法的内部就会执行selectImports方法,
	// 进而找到所有JavaConfig配置类全限定名对应的class,然后将所有自动配置类加载到IOC容器中
	public static void main(String[] args) {
		//pringBootDemoApplication.class --> primarySource
		SpringApplication.run(SpringBootDemoApplication.class, args);
	}
}

3、配置文件

将application.yml 替换成 bootstrap.yml, 在 bootstrap.yml 加上注册中心的配置

server:
  port: 8080

spring:
  application:
    name: spring-boot-demo
    # profiles:
    # active: dev # 指定环境,默认加载 default 环境
  #================== consul 服务发现与注册中心配置 =======================#
  cloud:
    consul:
      host: 1.116.43.223
      port: 8500
      #========注册中心==============
      discovery:
        instance-id: ${spring.application.name}:${server.port} #实例ID
        health-check-path: /actuator/health #健康检测
        service-name: ${spring.application.name}  #服务名称
        heartbeat:
          enabled: true
        health-check-critical-timeout: 60s  #健康检测60s失败,取消注册
      #========配置中心==============
      config:
        enabled: true # false禁用Consul配置,默认为true
        format: YAML  # 表示consul上面文件的格式,有四种:YAML、PROPERTIES、KEY-VALUE、FILES
        prefix: config  # 可以理解为配置文件所在的最外层目录
        default-context: consul-service # 设置应用的文件夹名称
        data-key: consul-service-config # Consul的Key/Values中的Key,Value对应整个配置文件
        # 以上配置可以理解为:加载config/consul-service/文件夹下Key为consul-service-config的Value对应的配置信息
        # 配置环境分隔符,默认值 "," 和 default-context 配置项搭配
        # 例如应用 consul-service 分别有环境 default、dev、test、prod
        # 只需在 config 文件夹下创建 consul-service、consul-service-dev、consul-service-test、consul-service-prod 文件夹即可
        # profile-separator: '-'
        watch:
          enabled: true # 是否开启自动刷新,默认值true开启
          delay: 1000 # 刷新频率,单位毫秒,默认值1000

运行效果
image.png

二、配置中心

1、pom.xml

在pom.xml 引入 spring-cloud-starter-consul-config 配置

		<!--	consul 配置中心	-->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-consul-config</artifactId>
		</dependency>

2、配置文件

将application.yml 替换成 bootstrap.yml, 在 bootstrap.yml 加上注册中心的配置

server:
  port: 8080

spring:
  application:
    name: spring-boot-demo
    # profiles:
    # active: dev # 指定环境,默认加载 default 环境
  #================== consul 服务发现与注册中心配置 =======================#
  cloud:
    consul:
      host: 1.116.43.223
      port: 8500
      #========注册中心==============
      discovery:
        instance-id: ${spring.application.name}:${server.port} #实例ID
        health-check-path: /actuator/health #健康检测
        service-name: ${spring.application.name}  #服务名称
        heartbeat:
          enabled: true
        health-check-critical-timeout: 60s  #健康检测60s失败,取消注册
      #========配置中心==============
      config:
        enabled: true # false禁用Consul配置,默认为true
        format: YAML  # 表示consul上面文件的格式,有四种:YAML、PROPERTIES、KEY-VALUE、FILES
        prefix: config  # 可以理解为配置文件所在的最外层目录
        default-context: consul-service # 设置应用的文件夹名称
        data-key: consul-service-config # Consul的Key/Values中的Key,Value对应整个配置文件
        # 以上配置可以理解为:加载config/consul-service/文件夹下Key为consul-service-config的Value对应的配置信息
        # 配置环境分隔符,默认值 "," 和 default-context 配置项搭配
        # 例如应用 consul-service 分别有环境 default、dev、test、prod
        # 只需在 config 文件夹下创建 consul-service、consul-service-dev、consul-service-test、consul-service-prod 文件夹即可
        # profile-separator: '-'
        watch:
          enabled: true # 是否开启自动刷新,默认值true开启
          delay: 1000 # 刷新频率,单位毫秒,默认值1000

3、consul 配置

根据 配置文件,新建对应的目录,并建好配置文件
image.png
image.png

三、consul 的自动注册

1、核心代码

package com.example.springbootdemo.config.consul;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: geek
 * @Date: 2023/08/25/4:06 PM
 * @Description:
 */
@Data
@Configuration
@ConfigurationProperties("spring.cloud.consul.retry")
public class ConsulRetryProperties {
	/**
	 * 监测间隔(单位:ms)
	 */
	private long initialInterval = 10000L;
	/**
	 * 间隔因子(备用)
	 */
	private double multiplier = 1.1D;
	/**
	 * 最大间隔(备用)
	 */
	private long maxInterval = 20000L;
	/**
	 * 重试次数(备用)
	 */
	private int maxAttempts = 6;
}

package com.example.springbootdemo.config.consul;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryClient;
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: geek
 * @Date: 2023/08/25/4:09 PM
 * @Description:
 */
@Configuration
@ConditionalOnClass({
		ConsulDiscoveryClient.class,
		ConsulAutoRegistration.class,
		ConsulServiceRegistry.class
})
//@EnableConfigurationProperties(ConsulRetryProperties.class)
@Import({ConsulRetryProperties.class})
public class ConsulRetryAutoConfiguration {

//	@Autowired
//	private ConsulRetryProperties consulRetryProperties;

	@Bean
	@ConditionalOnMissingBean(ConsulRetryRegistry.class)
	public ConsulRetryRegistry consulRetryRegistry(
			ConsulAutoRegistration consulAutoRegistration,
			ConsulServiceRegistry consulServiceRegistry,
			DiscoveryClient discoveryClient,
			ConsulRetryProperties properties
	) {
		return new ConsulRetryRegistry(
				consulAutoRegistration,
				consulServiceRegistry,
				discoveryClient,
				properties
		);
	}
}

package com.example.springbootdemo.config.consul;

import cn.hutool.core.thread.ThreadUtil;
import com.ecwid.consul.v1.agent.model.NewService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration;
import org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistry;

import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: geek
 * @Date: 2023/08/25/4:14 PM
 * @Description:
 */
@Slf4j
public class ConsulRetryRegistry implements CommandLineRunner {

	private ConsulAutoRegistration consulAutoRegistration;
	private ConsulServiceRegistry consulServiceRegistry;
	private DiscoveryClient discoveryClient;
	private ConsulRetryProperties properties;

	public ConsulRetryRegistry(
			ConsulAutoRegistration consulAutoRegistration,
			ConsulServiceRegistry consulServiceRegistry,
			DiscoveryClient discoveryClient,
			ConsulRetryProperties properties
	) {
		this.consulAutoRegistration = consulAutoRegistration;
		this.consulServiceRegistry = consulServiceRegistry;
		this.discoveryClient = discoveryClient;
		this.properties = properties;
	}

	@Override
	public void run(String... args) {
		// 获取当前服务
		final NewService service = this.consulAutoRegistration.getService();

		ThreadUtil.newSingleExecutor().execute(() -> {
			log.debug("consul服务监测已启动【{}】", service);
			while (true) {
				try {
					Thread.sleep(this.properties.getInitialInterval());
				} catch (InterruptedException e) {
					// 当前线程异常退出
					log.error("consul服务已停止重新注册【{}】", service);
					break;
				}
				// 健康检查
				if (!checkStatus(service)) {
					try {
						// 重新注册
						this.registry();
						log.info("consul服务重新注册成功【{}】", service);
					} catch (Exception e) {
						log.warn("consul服务当前注册失败,准备下一次注册【{}】", service);
					}
				}
			}

		});
	}

	/**
	 * 服务注册
	 */
	private void registry() {
		this.consulServiceRegistry.register(this.consulAutoRegistration);
	}


	/**
	 * 检查服务状态
	 *
	 * @param service 服务
	 * @return 返回布尔值,正常true,异常false
	 */
	private boolean checkStatus(NewService service) {
		// 检测标志
		boolean flag = false;
		int existNum = 0;
		try {
			// 获取所有服务实例
			List<ServiceInstance> instances = this.discoveryClient.getInstances(service.getName());
			// 遍历实例
			for (ServiceInstance instance : instances) {
				// 判断是否为当前服务
				if (instance.getInstanceId().equals(service.getId())) {
					flag = true;
					existNum++;
					if (existNum>1){
						log.info("consul服务心跳检测,注销多余注册的实例:{}",instance.getInstanceId());
						this.deregister();
					}
				}
			}
		} catch (Exception e) {
		}
		log.debug("consul服务心跳检测结束,检测结果为:{}", flag ? "正常" : "异常");
		return flag;
	}

	/**
	 * 服务取消注册
	 */
	private void deregister() {
		this.consulServiceRegistry.deregister(this.consulAutoRegistration);
	}

}

四、遇到的问题

1、config导致consul 配置host和port无效

解决方案1:
将 application.yml 替换成 bootsrap.yml

解法方案2:
因为安装网上的教程配置,发现都加这个配置,但是启动发现自己配置的host 和 port 无效

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-config</artifactId>
        </dependency>

2、consul 删除无效节点服务

POST 调用 PUT 提交方式
http://1.116.43.223:8500/v1/agent/service/deregister/spring-boot-demo-8080


curl -X PUT http://127.0.0.1:8500/v1/agent/service/deregister/ocation-server-7101

参考文档:consul 删除无效节点服务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值