springboot程序以jar包运行时中间状态持久化(checkpoint)

springboot程序以jar包运行时,有时希望能够保存程序运行的状态信息,以便程序终止后,能够在重新启动程序以后,能够根据之前的状态继续进行后续的处理。

在jar包的类路径下放置一个状态信息文件snowflake.properties。

1. 保存程序状态

/**
     * 文件不存在时,不影响正常使用
     * 只是不能持久化顺序号
     */
    public void saveCheckPoint() {

        String fileName = "snowflake.properties";
        String filePath = getConfFile(fileName);

        try {

            File confFile = new File(filePath);
            if (!confFile.exists()) {
                confFile.createNewFile();
            }

            FileOutputStream outputStream = new FileOutputStream(confFile);
            String configInfo = "sequence=" + sequence;
            outputStream.write(configInfo.getBytes(StandardCharsets.UTF_8));

            outputStream.close();

            System.out.println("id持久化成功到:" + this.sequence);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2. 读取程序状态

/**
     * 文件不存在时,不需要报错
     */
    public void restoreCheckPoint() {

        String fileName = "snowflake.properties";
        String confPath = getConfFile(fileName);

        try {

			File confFile = new File(confPath);

            // 文件不存在,不进行读取
            if (!confFile.exists()) {
                return;
            }

			InputStream inputStream = new FileInputStream(confFile);

            // 设置1KB的缓冲区
            byte buf[] = new byte[1024];
            int read = inputStream.read(buf);
            inputStream.close();

            String buffInfo = new String(buf);
            String confInfo = buffInfo.substring(0, read);
            if (confInfo.startsWith("sequence=")) {
                String splits[] = confInfo.split("=");
                String sequence = splits[1];
                this.sequence = Long.parseLong(sequence);

                System.out.println("id恢复成功到:" + this.sequence);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3. 状态信息文件路径

// 获取配置文件路径
    public String getConfFile(String fileName)
    {
        URL resource1 = getClass().getResource("/");

        String path = resource1.getPath();
        System.out.println("path1 = " + path);

        int endPos = path.indexOf(".jar!");
        if(endPos > 0)
            path = path.substring(0, endPos);
        System.out.println("path2 = " + path);

        endPos = path.lastIndexOf("/");
        if(path.startsWith("file:/"))
            path = path.substring(6, endPos);
        else if(path.startsWith("/"))
            path = path.substring(1, endPos);
        
        System.out.println("path3 = " + path);

        path = path + "/snowflake.properties";
        System.out.println("path4 = " + path);

        return path;
    }

4. 恢复和保存状态信息

@RequestMapping("/add")
    public String add()
    {
        restoreCheckPoint();

        System.out.println("下单成功");        

        if(sequence == null)
            sequence = 0l;
        else
            sequence = sequence + 1;

        saveCheckPoint();

        return "Hello world!";
    }

这里按照每次都读取保存的状态信息的方式,在实际应用场景下,可以只在程序启动的时候保存之前保存的状态信息,然后保存起来,在后续过程中,将中间状态保存在内存中,并在必要的时候进行持久化保存。

这里将中间状态信息保存在了jar包所在目录下的一个文件中,这就需要运行程序的用户具有jar包所在目录的创建文件和写文件权限。

5. 启动jar包,执行测试

控制台可以看到输出信息类似如下:

id恢复成功到:37
下单成功
path1 = file:/D:/order/target/order.jar!/BOOT-INF/classes!/
path2 = file:/D:/order/target/order
path3 = D:/order/target
path4 = D:/order/target/snowflake.properties
id持久化成功到:38
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值