文档章节

补丁更新

g
 gongsiai
发布于 2017/04/07 14:08
字数 2219
阅读 10
收藏 0

package com.suteam.zsyun.job;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSON;
import com.suteam.zsyun.application.model.ApplicationFilePack;
import com.suteam.zsyun.commonUtil.FileUtil;
import com.suteam.zsyun.commonUtil.HttpAuthUtil;
import com.suteam.zsyun.commonUtil.ModifyConfig;
import com.suteam.zsyun.config.Config;

/**
 * agent守护进程项目定时任务
 * 
 * @author zsyun_gsa
 *
 */
public class BasicJobUtil {
    public static Logger log = Logger.getLogger(BasicJobUtil.class);

    public static void executeTask() {
        log.info(" *****agent守护进程定时任务开始***** ");
        try {
            // 获取jar文件当前路径
            String path = System.getProperty("user.dir");
            log.info("jar文件当前路径:"+path);
            // 获取配置文件路径
            String configPath = FileUtil.getConfigPath();
            // 读取配置文件config.ini,获取版本号version_Number与当前jar文件名称
            Properties configProperty = FileUtil.getConfig(configPath + Config.configName);
            String versionNumber = configProperty.getProperty("version_Number");
            String agentName = configProperty.getProperty("agent_Name");
            // 读取配置文件es.ini,获取code
            Properties esProperty = FileUtil.getConfig(configPath + Config.esName);
            String code = esProperty.getProperty("code");
            // 读取配置文件watch.ini,获取app项目服务器地址
            Properties watchProperty = FileUtil.getConfig(configPath + Config.watchName);
            String appServer = watchProperty.getProperty("appServer");

            // 声明一个存放请求参数的map
            Map<String, String> parameterMap = new HashMap<String, String>();
            // 拼接调用app项目中的版本查询接口的url和参数
            String url = appServer + "/v1/port/appService/query/queryPatch.do";
            parameterMap.put("code", code);
            parameterMap.put("versionNumber", versionNumber);
            // 调用APP项目中版本查询接口
            log.info("调用APP项目中版本查询接口:");
            String result = HttpAuthUtil.doAuthPost(url, parameterMap);
            Map<String, Object> mapResult = (Map<String, Object>) JSON.parse(result);
            if (null != mapResult && "ok".equals(mapResult.get("result"))) {
                log.info("调用APP项目中版本查询接口,ok:");
                // 解析获取应用文件包对象
                ApplicationFilePack applicationFilePack = JSON.parseObject(String.valueOf(mapResult.get("values")),
                        ApplicationFilePack.class);
                // 判断应用文件包对象是否为空。不为空说明有要更新的agent。
                if (null != applicationFilePack) {
                    log.info("文件包对象不为空,说明有要更新的agent。");
                    // 获取版本
                    String version = applicationFilePack.getVersion();
                    log.info("获取新版本version:" + version);
                    if (!version.equals(versionNumber)) {
                        log.info("新旧版本不同。");
                        // 获取应用文件路径
                        String filePath = applicationFilePack.getFilePath();
                        log.info("新文件路径:"+filePath);
                        // 获取文件hash
                        String hash = applicationFilePack.getHash();
                        log.info("新文件hash:"+hash);
                        // 获取名称,如agent_1.2.jar
                        String name = applicationFilePack.getName();
                        log.info("新文件名称:" + name);
                        
                        // 调用下载补丁方法
                        String getHash = downLoadFromUrl(filePath, name, path);
                        if (!getHash.equals(hash)) {
                            // 将下载失败的文件删除
                            if (path.contains("/")) {
                                path += "/";
                            }
                            if (path.contains("\\")) {
                                path += "\\";
                            }
                            log.info("将下载失败的文件删除,要删除的文件为:"+path + name);
                            deleteFile(path + name);
                            // hash不同,下次定时任务重新下载
                            log.info("hash不同,下次定时任务重新下载");
                        } else {
                            log.info("新下载的jar文件与原文件hash相同。");
                            // 修改配置文件,将文件版本更新成新版本
                            log.info("修改配置文件更新版本信息:");
                            String[] keyArray = new String[2];
                            keyArray[0] = "version_Number";
                            keyArray[1] = "agent_Name";
                            String[] valueArray = new String[2];
                            valueArray[0] = version;
                            valueArray[1] = name;
                            log.info("新的版本为:" + version);
                            String fileName = "config.ini";
                            ModifyConfig.modifyConfig(keyArray, valueArray, fileName);
                            log.info("修改配置文件更新版本信息,完成。");

                            log.info("将原agent停止:");
                            if (path.contains("/")) {
                                path += "/";
                                log.info("Linux将原agent停止:");
                                String psCommander = "ps -ef|grep "+agentName;
                                log.info("查看进程指令:" + psCommander);
                                Process ps = Runtime.getRuntime().exec(new String[] { "sh", "-c", psCommander });
                                BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
                                StringBuffer sb = new StringBuffer();
                                String line;
                                while ((line = br.readLine()) != null) {
                                    sb.append(line).append("\n");
                                }
                                String ret = sb.toString();
                                // 将获取结果去除回车拆分
                                String[] resultStr = ret.split("\n");
                                for (int j = 0; j < resultStr.length; j++) {
                                    String s = resultStr[j];
                                    // 去除tab键
                                    s = s.replace("    ", " ");
                                    log.info("去除tab键:" + s);
                                    // 将所有的多空格转成单空格
                                    s = s.replaceAll(" +", " ");
                                    log.info("将所有的多空格转成单空格:" + s);
                                    if (s.startsWith(" ")) {
                                        // 将第一个空格截取去除
                                        s = s.substring(1, s.length());
                                        log.info("将第一个空格截取去除:" + s);
                                    }
                                    // 将数据以空格拆分:root 16608 4888 0 15:08 pts/1
                                    // 00:00:47 java -jar agent.jar
                                    String[] retStr = s.split(" ");
                                    log.info("将数据以空格拆分:" + s);
                                    // 获取进程结果的最后一个数据(所下达的指令为何)
                                    String cmdCommander = "";
                                    for (int i = 7; i < retStr.length; i++) {
                                        cmdCommander = cmdCommander + retStr[i];
                                    }
                                    log.info("logCode进程结果的最后一个数据:" + cmdCommander);
                                    log.info("pid为:" + retStr[1]);
                                    if (cmdCommander.contains("java-jar")) {
                                        // 包含文件名,说明这个进程为要杀死的agent进程。获取进程的pid(第二个数据)。
                                        String pid = retStr[1];
                                        log.info("pid为:" + retStr[1]);
                                        // 获取cp进程的标识号,拼接杀进程指令kill -9 进程标识号
                                        String killCommander = "kill -9 " + pid;
                                        // 执行杀进程指令
                                        log.info("---开始执行kill指令:" + killCommander);
                                        Runtime.getRuntime().exec(killCommander);
                                        log.info("---执行kill指令完毕。");
                                    }
                                }
                                
                                // 文件路径
                                String shfileName = path+"/restarJar.sh";
                                log.info("获取sh文件路径如下 :"+shfileName);
                                // 1.删除文件
                                deleteFile(shfileName);
                                log.info("删除文件完成。");
                                // 2.创建文件
                                createNewFile(shfileName);
                                log.info("创建文件完成。");
                                //changeParam为要追加到.sh文件的信息
                                String changeParam = "nohup java -jar /usr/agenthost/" + name +" > /usr/agenthost/logs/myout.file 2>&1 &";
                                log.info("追加到.sh文件的信息:"+ changeParam);
                                // 3.追加内容  \n代表回车换行
                                StringBuffer strBuffer = new StringBuffer();
                                strBuffer.append("#!/bin/sh\n");
                                strBuffer.append(changeParam);
                                appendMethod(shfileName, strBuffer.toString());
                                log.info("追加完成");
                                
                                log.info("执行sh文件:bash "+path+"/restarJar.sh");
                                Runtime.getRuntime().exec("bash "+path+"/restarJar.sh");
                                log.info("执行sh文件完成");
                            }
                            if (path.contains("\\")) {
                                path += "\\";
                                log.info("Windows将原agent停止:");
                                
                                // 查看Windows系统所有正在运行的java程序
                                String psCommander = "jps -l";
                                log.info("查看进程指令:" + psCommander);
                                Process ps = Runtime.getRuntime().exec(psCommander);
                                BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
                                StringBuffer sb = new StringBuffer();
                                String line;
                                while ((line = br.readLine()) != null) {
                                    sb.append(line).append("\n");
                                }
                                String ret = sb.toString();
                                // 将获取结果去除回车拆分
                                String[] resultStr = ret.split("\n");
                                for (int j = 0; j < resultStr.length; j++) {
                                    String s = resultStr[j];
                                    // 去除tab键
                                    s = s.replace("    ", " ");
                                    log.info("去除tab键:" + s);
                                    // 将所有的多空格转成单空格
                                    s = s.replaceAll(" +", " ");
                                    log.info("将所有的多空格转成单空格:" + s);
                                    if (s.startsWith(" ")) {
                                        // 将第一个空格截取去除
                                        s = s.substring(1, s.length());
                                        log.info("将第一个空格截取去除:" + s);
                                    }
                                    // 将数据以空格拆分:root 16608 4888 0 15:08 pts/1
                                    // 00:00:47 java -jar agent.jar
                                    String[] retStr = s.split(" ");
                                    log.info("将数据以空格拆分:" + s);
                                    // 获取进程结果的最后一个数据(所下达的指令为何)
                                    if(retStr.length>1){
                                        String cmdCommander = retStr[1];
                                        log.info("logCode进程结果的最后一个数据:" + cmdCommander);
                                        if (cmdCommander.contains(agentName)) {
                                            // 包含文件名,说明这个进程为要杀死的agent进程。获取进程的pid(第二个数据)。
                                            String pid = retStr[0];
                                            log.info("pid为:" + retStr[0]);
                                            // 获取cp进程的标识号,拼接杀进程指令kill -9 进程标识号
                                            String killCommander = "TASKKILL /F /PID " + pid;
                                            // 执行杀进程指令
                                            log.info("---开始执行kill指令:" + killCommander);
                                            Runtime.getRuntime().exec(killCommander);
                                            log.info("---执行kill指令完毕。");
                                        }
                                    }
                                }
                                
                                // 重启jar文件路径
                                String shfileName = path+"\\restarJar.bat";
                                log.info("获取重启jar文件路径如下 :"+shfileName);
                                // 删除原文件
                                deleteFile(shfileName);
                                log.info("删除原文件完成。");
                                // 重新创建文件
                                createNewFile(shfileName);
                                log.info("重新创建文件完成。");
                                //changeParam为要追加到.sh文件的信息
                                String changeParam = "start javaw -jar " + name;
                                log.info("追加到.bat文件的信息:"+ changeParam);
                                // 将内容追加到重启bat文件中  \n代表回车换行
                                StringBuffer strBuffer = new StringBuffer();
                                strBuffer.append("@echo off\n");
                                strBuffer.append(changeParam+"\n");
                                strBuffer.append("success& exit\n");
                                appendMethod(shfileName, strBuffer.toString());
                                log.info("追加完成");
                                
                                log.info("执行重启jarbat文件");
                                String cmd = "cmd.exe /c   start  " + shfileName;
                                Runtime.getRuntime().exec(cmd);
                                log.info("执行重启jarbat文件完成");
                            }
                            
                        }
                    }
                }
            } else {
                log.info("获取对象为空,没有要更新的!");
            }
        } catch (Exception e) {
            log.info("agent守护进程抛出异常。");
        }
        log.info(" *****agent守护进程定时任务结束*****");
    }

    /***
     * 对文件做hash处理
     * 
     * @param filename
     * @return
     * @throws Exception
     */
    public static String getMD5Checksum(String filename) throws Exception {
        log.info("进入获取hash方法:");
        byte[] b = createChecksum(filename);
        String result = "";

        for (int i = 0; i < b.length; i++) {
            result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);// 加0x100是因为有的b[i]的十六进制只有1位
        }
        return result;
    }

    public static byte[] createChecksum(String filename) throws Exception {
        InputStream fis = new FileInputStream(filename);// 20px;">将流类型字符串转换为String类型字符串</span>

        byte[] buffer = new byte[1024];
        MessageDigest complete = MessageDigest.getInstance("MD5"); // 如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256
        int numRead;
        do {
            numRead = fis.read(buffer); // 从文件读到buffer,最多装满buffer
            if (numRead > 0) {
                complete.update(buffer, 0, numRead); // 用读到的字节进行MD5的计算,第二个参数是偏移量
            }
        } while (numRead != -1);

        fis.close();
        return complete.digest();
    }

    /**
     * 删除文件方法
     */
    public static void deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果是文件,非目录
        if (file.isFile()) {
            file.delete();
        } else {
            return;
        }
    }

    /**
     * 新建文件方法
     */
    public static void createNewFile(String fileName) {
        File file = new File(fileName);
        // 如果文件不存在,新建一个文件
        if (file.isFile() && !file.exists()) {
            try {
                // 创建文件
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 追加文件方法
     */
    public static void appendMethod(String fileName, String content) {
        try {
            // 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(fileName, true), "GBK");
            osw.write(content);
            osw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 从网络Url中下载文件
     * 
     * @param urlStr
     * @param fileName
     * @param savePath
     * @throws IOException
     */
    public static String downLoadFromUrl(String urlStr, String fileName, String savePath) throws IOException {
        String retHash = "";
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        // 设置超时间为3秒
        conn.setConnectTimeout(3 * 1000);
        // 防止屏蔽程序抓取而返回403错误
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        // 得到输入流
        InputStream inputStream = conn.getInputStream();
        // 获取自己数组
        byte[] getData = readInputStream(inputStream);
        // 文件保存位置
        File saveDir = new File(savePath);
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }
        File file = new File(saveDir + File.separator + fileName);
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(getData);
        if (fos != null) {
            fos.close();
        }
        if (inputStream != null) {
            inputStream.close();
        }
        log.info("info:" + url + " download success");
        // 下载完毕,对补丁(或agent)进行hash处理
        try {
            if (savePath.contains("/")) {
                savePath += "/";
            }
            if (savePath.contains("\\")) {
                savePath += "\\";
            }
            log.info("hash路径:" + savePath + fileName);
            retHash = getMD5Checksum(savePath + fileName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("获取的文件hash:" + retHash);
        return retHash;
    }

    /**
     * 从输入流中获取字节数组
     * 
     * @param inputStream
     * @return
     * @throws IOException
     */
    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }
    public static void main(String[] args) {
        try {
            String hash = getMD5Checksum("H:\\agent_v1.2.jar");
            System.out.println(hash);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
 

© 著作权归作者所有

上一篇: 进程操作
下一篇: java下载文件
g

gongsiai

粉丝 1
博文 27
码字总数 10914
作品 0
大兴
程序员
私信 提问
AWS关于适用于修补实例的SSM文档

AWS-ConfigureWindowsUpdate 支持配置基本的 Windows 更新功能,并使用它们来自动安装更新 (或禁用自动更新)。在所有 AWS 区域中可用。 此 SSM 文档将提示 Windows 更新下载并安装指定的更新...

Rainy0426
2018/06/05
0
0
SCCM 2012升级到1702 Windows 10补丁更新问题

  升级SCCM 2012到1702版本(http://lorysun.blog.51cto.com/1035880/1588661)后,安装的两台Windows 10和个人使用的Windows 2016一直未接收到推送的更新补丁,客户端版本和状态都是正常的...

lorysun
2017/05/26
0
0
Android进阶——Small源码分析之更新流程详解

前言 Small的更新有两种方式,一种是将插件放在插件目录,一种是将插件放在补丁目录下。更新插件的方法可以通过以下思路进行更新,本篇主要是通过Sample的例子来请求更新补丁,更新插件的方式...

qq_30379689
2018/02/02
0
0
CentOS 6.0系列更新安全补丁

一、安装yum-security 这个方法是使用的yum方式更新安全补丁,不需要再去官网上来回查看了,还以自动安装更新。 安装yum-security,这个软件可以检查并更新安全补丁,挺方便 [root@zabbix_s...

wangpengtai
2017/09/05
0
0
win10升级提示图标的四种关闭方法

方法一:临时退出 1、查找更新提示进程 既然是一个新玩意,那么进程里面肯定会有。仔细查看找到如夏天GWX.exe没错就是这个 就是那个更新的进程。 方法二:停用禁止更新程序 1、当然以上的方法...

robortly
2015/10/07
105
0

没有更多内容

加载失败,请刷新页面

加载更多

在阿里云ecs服务器(linux之centos系统)安装调试nginx

购买阿里云ecs服务器实例 由于这里只是测试,我们就随便买一个(当然我就选最便宜的了,这里的抢占式实例测试完可以直接释放) 选择centos7.6镜像 点击下一步:网络和安全组 接下来选中开通h...

祖达
昨天
2
0
【阴阳师】真蛇10层记录

蛇切黑体系 追月神 散件一速,速度越高越好(220+) 镰鼬 招财二速,速度211以上; 山兔 火灵三速,速度180-200均可; 丑女 心眼四速,速度170左右即可; 大蛇 蚌精暴击套。速度高于阴阳师即...

Areya
昨天
5
0
js动态设置元素高度

this.$refs.xxx.style.height= this.contentHeight; 元素需要绑定

Carbenson
昨天
2
0
今天的学习

今天学到了ci框架中的查询语句的where条件语句: 1、$this->db->select('')->from('')->where('id = ??')->get()->result_array();2、$this->db->select('')->from('')->where('id', '??'......

墨冥
昨天
2
0
MySQL在高并发下的订单撮合、系统使用、共享锁与排他锁保证数据一致性

前序 距离上次择文发表,两月余久。2018年也即将要结束了,目前的工作依然是与区块链应用相关的,也很荣幸在9月初受邀签约出版暂名为《区块链以太坊DApp实战开发》一书,预计在明年年初出版。...

我最喜欢三大框架
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部