springboot向服务发现consul注册多个节点(SmartLifecycle)

一个服务正常情况下,应该只会注册一个节点,但是出于某些原因,需要把多个节点合并为一个节点,但是不能影响到其它节点的调用,除非去通知服务调用人员,改一下调用接口.但是要把所有调用端都改完,还是得花些时间的…
这里就是以最小时间成本,合并服务.

spring知识整理之服务发现
这里以consul为例,其它服务发现Eureka/k8s的api应该也都是类似的作法

基于 spring cloud /consul服务发现

pom.xml

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-consul-discovery</artifactId>
		</dependency>
		....</dependencies>

	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>org.springframework.cloud</groupId>
				<artifactId>spring-cloud-dependencies</artifactId>
				<version>Finchley.RELEASE</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>

定义一个类,添加节点的详细信息
节点id
节点名称
设置健康检查地址
等等

除了节点id,其它其它的信息都可以重复

@Component
public class MultipleConsulNode implements CommandLineRunner {
    @Autowired
    private ConsulDiscoveryProperties properties;

    @Autowired
    private HeartbeatProperties heartbeatProperties;
    @Autowired
    private AutoServiceRegistrationProperties autoServiceRegistrationProperties;

    @Autowired
    ConsulServiceRegistry ConsulServiceRegistry;

    @Autowired
    AnnotationConfigServletWebServerApplicationContext js_context;

    @Autowired(required = false)
    private TtlScheduler ttlScheduler;

    @Autowired
    private ConsulAutoConfiguration consulAutoConfiguration;


    @Autowired
    private DisposableBeanAdapterSub disposableBeanAdapter;

    public static List<Map<String,Object>> regs = new ArrayList<>();
    static {
        Map<String,Object> rej1 = new HashMap<>();
        rej1.put("before","service1");
        rej1.put("service_name","service1-micros");
        regs.add(rej1);

        Map<String,Object> rej2 = new HashMap<>();
        rej2.put("before","service2");
        rej2.put("service_name","service2-micros");
        regs.add(rej2);

    }


    @Override
    public void run(String... args) throws Exception {
        registration();
    }

    private void registration(){
    	
        Integer agentPort = Integer.parseInt(properties.getInstanceId().substring(properties.getInstanceId().lastIndexOf("-") + 1));
        //构造client
        ConsulClient client = consulAutoConfiguration.consulClient(consulAutoConfiguration.consulProperties());

        ConsulDiscoveryProperties jsProperties = new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties()));
        for(Map<String,Object> bean : regs) {
            bean.put("client", client);
            BeanUtils.copyProperties(properties, jsProperties);

            jsProperties.setServiceName(bean.get("service_name").toString());
            jsProperties.setPort(agentPort);


            ConsulServiceRegistry consulService = new ConsulServiceRegistry(client, properties, ttlScheduler, heartbeatProperties);

            bean.put("consulService", consulService);

			//生成节点信息
            NewService service = new NewService();
            String appName = ConsulAutoRegistration.getAppName(jsProperties, js_context.getEnvironment());
            String id = bean.get("before").toString() + ConsulAutoRegistration.getInstanceId(jsProperties, js_context);
            service.setId(id);
            if (!jsProperties.isPreferAgentAddress()) {
                service.setAddress(jsProperties.getHostname());
            }
            service.setName(ConsulAutoRegistration.normalizeForDns(appName));
            service.setTags(ConsulAutoRegistration.createTags(jsProperties));

            if (jsProperties.getPort() != null) {
                service.setPort(jsProperties.getPort());
                // we know the port and can set the check
                ConsulAutoRegistration.setCheck(service, autoServiceRegistrationProperties, jsProperties, js_context, heartbeatProperties);
            }

            ConsulRegistration reg = new ConsulRegistration(service, jsProperties);
            bean.put("consulRegistration", reg);
            //注册节点
            consulService.register(reg);
        }
        disposableBeanAdapter.start();
    }

}

删除节点,这里要做到自动删除,也要依赖springboot启动和注销顺序触发的事件去删除

@Component
public class DisposableBeanAdapterSub implements SmartLifecycle {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    private AtomicBoolean running = new AtomicBoolean(false);

    @Override
    public boolean isAutoStartup() {
        return false;
    }

    @Override
    public void stop(Runnable callback) {
        callback.run();
        if(this.running.compareAndSet(true, false) ) {
        	//当服务停止时,需要把服务发现列表删除注销当前服务
            for(Map<String,Object> bean : MultipleConsulNode.regs) {
                ConsulServiceRegistry consulService = (ConsulServiceRegistry) bean.get("consulService");
                ConsulRegistration consulRegistration = (ConsulRegistration) bean.get("consulRegistration");
                consulService.deregister(consulRegistration);
            }
        }
    }

    @Override
    public void start() {
        this.running.compareAndSet(false, true);
    }

    @Override
    public void stop() {

    }

    @Override
    public boolean isRunning() {
        //return false;
        return this.running.get();
    }

    @Override
    public int getPhase() {
    	//执行顺序在这里设置,类似aop,filter的执行链原理,0=启动时最先执行,停止最后执行
        return 1;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值