java-服务下线时需要执行方法, 如断开数据库连接,zk连接…

1. 实现DisposableBean接口

说明: 实现DisposableBean接口, destroy方法就是服务关闭执行的方法

  • 配置关闭服务执行方法:
package com.xhga.config;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

@Component
public class ShutdownListener implements DisposableBean {
    @Override
    public void destroy() {
        System.out.println("服务下线 !!!");
    }
}
  • 服务关闭方式: kill -15 pid

说明: 如:kill -9 pid 直接杀死服务, 将不会执行服务下线方法

2. 新增@PreDestroy注解方法

说明: 新增@PreDestory注解方法,并加载到spring容器

  • 配置关闭服务执行方法:
package com.xhga.config;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import javax.annotation.Resource;

@Component
public class ShutdownListener{
    @PreDestroy
    public void destroyPre(){
        System.out.println("服务下线 PreDestroy");
    }
}
  • 服务关闭方式: kill -15 pid

3. springboot引入依赖spring-boot-starter-actuator 2.x 依赖

说明: 根据springboot提供的actuator依赖对springboot项目的监控系统健康情况的工具, 优雅的关闭服务

  1. 新增pom依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>
  1. 配置application.properties (2.x与1.x是有1区别的, 这里是2.x的配置)
management.endpoints.web.exposure.include=*
	management.endpoint.shutdown.enabled=true
  1. 配置关闭服务执行方法
    方式1与方式2 任意一种 配置关闭服务执行方法即可
  2. 服务关闭方式:
发送post请求: http://ip:port/actuator/shutdown
 注: 若配置server.servlet.context-path=/api, 则uri需要加上/api 
 即: http://ip:port/api/actuator/shutdown

案例1 :服务关闭, 立刻删除本服务创建的zk临时节点

  • 需求场景:
    公司项目ZooKeeper做注册服务中心, 服务上线,创建服务临时节点, 服务下线时删除临时节点, 临时节点特点就是当客户端与zk服务端断开连接,自动删除此客户端创建的临时节点, 由于zk存在sessiontimeout默认30s, 服务关闭时, zk断开连接并没有通知zookeeper, 临时节点不能立刻删除, 直到sessiontimeout时间时zk服务端发现客户端已经断开连接,并删除临时节点, 不满足项目要求, 因为公司项目调用服务端接口时判断服务是否在线, 若不在线将不再请求…
  • 解决方法:
    执行服务关闭方法时, 主动断开zk连接 zk.close(), zk服务端知道客户端断开连接, 即可直接删除此客户端创建的临时节点, 调用服务接口时可以及时知道该服务是否在线…
  • 示例代码:
package com.xhga.config;

import org.apache.zookeeper.ZooKeeper;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
@Component
public class DisposableBeanService implements DisposableBean {
    @Resource
    private ZooKeeper zk;
    
    @PreDestroy
    public void destroyPre(){
        System.out.println("方式1 - 服务下线 PreDestroy!!!");
    }
    
    @Override
    public void destroy() {
        System.out.println("方式2 - 服务下线 DisposableBean!!!");
        try {
            if (zk == null) {
                return;
            }
            zk.close();
            System.out.println("服务下线- 关闭zk连接成功");
        } catch (InterruptedException e) {
            System.out.println("服务下线- 关闭zk连接异常");
            e.printStackTrace();
        }
    }
}