Java调用linux脚本实现文件分割合并上传

优化前:

        因项目部署在内网环境,只有部分服务可以外网访问。之前部署项目,需要在本地打包,上传到运维机连vpn上传到内网服务器,通过脚本启动。

优化后:

  • 使用jenkins打包服务,并通过ssh上传到A服务器
  • jenkins执行upload.sh将jar包每9m分割一个文件
  • upload.sh调用内网服务器映射出来的上传文件接口,上传到分割后的多个文件到内网服务器
  • upload.sh调用内网服务器映射的执行脚本接口,调用内网服务器deploy.sh脚本
  • deploy.sh脚本合并文件 并备份发布项目
  • 新增查询日志接口 简单使用cat命令

0. shell脚本

0.1 upload.sh 分割文件、调用上传接口

#!/bin/bash

source /etc/profile

JAR_NAME=${1}

JAR_PATH=/mnt/data/iot-supplier-center/iot-supplier-deploy/jars

LOG_PATH=/mnt/data/iot-supplier-center/iot-supplier-deploy/logs/bash.log

echo $(date "+%Y-%m-%d %H:%M:%S") --  JAR_NAME is ${JAR_NAME} >> ${LOG_PATH}

cd ${JAR_PATH}

#每9m分割一个jar包
split -b 9m ${JAR_NAME} split-${JAR_NAME}-

echo $(date "+%Y-%m-%d %H:%M:%S") --  split finished!   >> ${LOG_PATH}


for file in $(find /mnt/data/iot-supplier-center/iot-supplier-deploy/jars/ -type f -name "spl*")

do

curl -F "file=@$file" -F "path=/data/platform/jar/upload/" -o /mnt/data/iot-supplier-center/iot-supplier-deploy/logs/upload.log  https://xxx.com/deploy-project/upload

done

rm -rf split-${JAR_NAME}-*

echo $(date "+%Y-%m-%d %H:%M:%S") --  upload finished!   >> ${LOG_PATH}

echo $(curl -X POST -H "Content-Type: application/json"  https://xxx.com/deploy-project/combine-and-deploy -d "{\"jarName\":\"${JAR_NAME}\"}") >>${LOG_PATH}

echo $(date "+%Y-%m-%d %H:%M:%S") --  execute sh finished!   >> ${LOG_PATH}

echo ----------end----------

 0.2 deploy.sh 合并文件 并发布

#!/bin/sh
source /etc/profile

JAR_NAME=${1}

WORK_PATH='/data/platform/jar/';

PROJECT='province';

if [ -z "$JAR_NAME" ];then
    echo "JAR_NAME is null !"
    exit
fi

JAR_PATH=/data/platform/jar/upload/

LOG_PATH=/data/platform/jar/upload/logs/bash.log

echo $(date "+%Y-%m-%d %H:%M:%S") --  ----- start -----  >> $LOG_PATH

echo $(date "+%Y-%m-%d %H:%M:%S") --  JAR_NAME is $JAR_NAME >> $LOG_PATH

cd $JAR_PATH

echo $(date "+%Y-%m-%d %H:%M:%S") --  pwd is `pwd` ,jarPath is $JAR_PATH ,jarName is $JAR_NAME !  >> $LOG_PATH

cat split-$JAR_NAME-* > $JAR_NAME

echo $(date "+%Y-%m-%d %H:%M:%S") --  combine fineshed!  >> $LOG_PATH

FILE_NAME=$WORK_PATH$JAR_NAME

echo $(date "+%Y-%m-%d %H:%M:%S") --  fileName is $FILE_NAME !  >> $LOG_PATH

COPY_PATH=${JAR_PATH}backup/$(date "+%Y%m%d%H%M%S")-$JAR_NAME

if [ -e "$FILE_NAME" ]; then
    echo $(date "+%Y-%m-%d %H:%M:%S") -- true copyPath is $COPY_PATH !  >> $LOG_PATH
    cp $FILE_NAME $COPY_PATH
fi

echo $(date "+%Y-%m-%d %H:%M:%S") --  backup fineshed!  >> $LOG_PATH

PID=`ps aux | grep $JAR_NAME |grep $PROJECT | grep -v grep | awk '{print $2}'`

echo $(date "+%Y-%m-%d %H:%M:%S") --  PID is $PID  >> $LOG_PATH

if [ -n "$PID" ]; then
    kill -9 $PID
    echo $(date "+%Y-%m-%d %H:%M:%S") --  kill fineshed!  pid is $PID  >> $LOG_PATH
fi

mv -u $JAR_NAME /data/platform/jar/

echo $(date "+%Y-%m-%d %H:%M:%S") --  mv fineshed!  >> $LOG_PATH

echo $(date "+%Y-%m-%d %H:%M:%S") --  start jar service!  >> $LOG_PATH

nohup java -Xms512m -Xmx512m -jar $FILE_NAME --spring.profiles.active=$PROJECT > /dev/null 2>&1 &

NEW_PID=`ps aux | grep $JAR_NAME |grep $PROJECT | grep -v grep | awk '{print $2}'`

echo $(date "+%Y-%m-%d %H:%M:%S") --  start jar service fineshed! old is $PID , newPid is $NEW_PID  >> $LOG_PATH

echo $(date "+%Y-%m-%d %H:%M:%S") --  ----- end -----  --  >> $LOG_PATH

1.Java代码 调用shell脚本

1.1 文件上传

@PostMapping("upload")
    public RestResult<String> upload(@RequestParam("file") MultipartFile multipartFile, @RequestParam("path") String path) {
        String originalFilename = multipartFile.getOriginalFilename();
        String[] split = originalFilename.split("\\.");
        String jarName = split[0];
        StringBuilder stringBuffer = new StringBuilder();
        stringBuffer.append("path : ").append(path);
        stringBuffer.append(" jarName : ").append(jarName);
        log.info("originalFilename :{},path :{},", originalFilename, path);
        //生成发布所需目录
        String deployPath = path + "/logs";
        boolean mkdirs = new File(deployPath).mkdirs();
        stringBuffer.append(" deployPath mkdirs : ").append(mkdirs);
        try {
            File file = new File(path + originalFilename);
            multipartFile.transferTo(file);
            stringBuffer.append(" upload success! ");
        } catch (IOException e) {
            stringBuffer.append(" " + e);
            return RestResult.wrapErrorResponse(stringBuffer.toString());
        }
        return RestResult.wrapSuccessResponse(stringBuffer.toString());
    }

1.2 合并文件并发布

	@PostMapping("combine-and-deploy")
	public RestResult<String> combineAndDeploy(@RequestBody JarNameParam jarNameParam) { 
			StringBuilder stringBuffer = new StringBuilder();
        String jarName = jarNameParam.getJarName();
        stringBuffer.append("jarName : ").append(jarName);
        ProcessBuilder builder = new ProcessBuilder("/bin/sh", "-c", "/home/sh/combine-and-deploy.sh " + jarName);
			Process process = null;
        try {
            process = builder.start();
            stringBuffer.append("execute bash success ! ");
            StreamGobbler streamGobbler = new StreamGobbler(process.getInputStream(), System.out::println);
            Future<?> future = Executors.newSingleThreadExecutor().submit(streamGobbler);
            int exitCode = process.waitFor();
            assert exitCode == 0;
            future.get(10, TimeUnit.SECONDS);
        } catch (IOException | InterruptedException | ExecutionException | TimeoutException e) {
            stringBuffer.append(e);
            return RestResult.wrapErrorResponse(stringBuffer.toString());
        }
        return RestResult.wrapSuccessResponse(stringBuffer.toString());
    }

    static class StreamGobbler implements Runnable {
        private InputStream inputStream;
        private Consumer<String> consumeInputLine;

        public StreamGobbler(InputStream inputStream, Consumer<String> consumeInputLine) {
            this.inputStream = inputStream;
            this.consumeInputLine = consumeInputLine;
        }

        public void run() {
            new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(consumeInputLine);
        }
    }

1.3 查看日志

@PostMapping("returnStream")
    public void returnStream(HttpServletResponse response, @RequestBody JarNameParam param) throws IOException {
        String command = param.getJarName();
        if (!command.startsWith("cat")) {
            return;
        }
        // 执行脚本文件
        log.info("开始执行命令:" + command);
        //主要在这步写入后调用命令
        String[] cmd = {"/bin/sh", "-c", command};
        Process process = Runtime.getRuntime().exec(cmd);
        try (BufferedReader read = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            Future<String> future = Executors.newSingleThreadExecutor().submit(() -> {
                String line;
                StringBuilder buffer = new StringBuilder();
                while ((line = read.readLine()) != null) {
                    buffer.append(line).append(System.lineSeparator());
                }
                return buffer.toString();
            });
            int exitCode = process.waitFor();
            assert exitCode == 0;
            String buffer = future.get(10, TimeUnit.SECONDS);
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream;charset=UTF-8");
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(buffer.getBytes());
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            log.error("", e);
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值