当前位置: 首页 > article >正文

工具箱:【1】简单的自动部署

工具箱:【1】简单的自动部署

  • 1、简单粗暴直接上代码
  • 2、配合服务器的shell脚本

甲方无自动化部署平台,自己实在也不想搭建自动部署jekins

但是现在都是maven工程,一个破项目好几个jar,每次部署几台服务器,动不动忘了这个忘了那个,索性手撸一个简单的打包部署

1、简单粗暴直接上代码

package com.yzj.plutus.executor;

import cn.hutool.extra.ssh.JschUtil;
import cn.hutool.extra.ssh.Sftp;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.Charset;

@Slf4j
public class RemoteDelopyment {

    public static void main(String[] args) {
        packageJar();

        putFile();
    }

    private final static String env = "test";
    private final static String[] ips = {"127.0.0.1"};
    private final static int port = 22;
    private final static String user = "ftpuser";
    private final static String pass = "123456";
    private final static String[] fileNames = {"a.jar","b.jar"};
    private final static String target = "target";
    private final static String jar = "jar";
    private final static String sh = "cd /home/app/pack/ && ./bak.sh && sleep 10 && ./stopAll.sh && ./startAll.sh";
    private final static String destPath = "/home/app/bak/put/";

    public static void putFile(){
        for (String ip: ips) {
            Session session = JschUtil.openSession(ip, port, user, pass);
            Sftp sftp = JschUtil.createSftp(session);
            String property = System.getProperty("user.dir");
            String rootPath = property.substring(0, property.lastIndexOf(File.separator));

            for (String fileName: fileNames) {
                try {
                    String srcPath = rootPath + File.separator + fileName + File.separator + target + File.separator + fileName + "." + jar;
                    log.info("当前上传文件为:{}", srcPath);
                    sftp.put(srcPath, destPath);
                }catch (Exception e){
                    log.warn("================>{}", e.toString());
                }
            }
            String exec = JschUtil.exec(session, sh, Charset.defaultCharset());
            log.info("执行脚本返回信息:{}", exec);
            JschUtil.close(session);
        }
    }

    public static void packageJar(){
        String property = System.getProperty("user.dir");
        String rootPath = property.substring(0, property.lastIndexOf(File.separator));
        //先打包依赖包
        String pomPath = rootPath + File.separator + "framework";
        process(pomPath);

        for (String fileName: fileNames) {
            try {
                pomPath = rootPath + File.separator + fileName;
                process(pomPath);
            }catch (Exception e){
                log.warn("==============>:{}", e.toString());
            }
        }
    }

    public static void process(String pomPath){
        try {
            Process process = Runtime.getRuntime().exec("cmd /k cd " + pomPath + " && mvn clean install -Dmaven.test.skip=true -P" + env);
            OutStream error = new OutStream(process.getErrorStream(), "Error");
            OutStream outPut = new OutStream(process.getInputStream(), "OutPut");
            process.getOutputStream().close();//不加流卡死

            error.start();
            outPut.start();

            process.waitFor();

            String fileName = pomPath.substring(pomPath.lastIndexOf(File.separator) + 1) + "." + jar;
            if (process.exitValue() == 0){
                log.info("{}打包正常结束!", fileName);
            }else {
                log.info("{}打包异常结束!", fileName);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    static class OutStream extends Thread{
        InputStream is;
        String type;

        public OutStream(InputStream is, String type){
            this.is = is;
            this.type = type;
        }

        @Override
        public void run() {
            try{
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null){
                    if (type.equals("ERROR")){
                        log.error("Error: {}", line);
                    }else {
                        log.info(line);
                    }
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

2、配合服务器的shell脚本

  • bak.sh
#应用目录
dir=/home/app/xxx
fileDir=`date +%Y%m%d-%H%M%S`
#备份路径
bakDir=/home/app/xxx/bak/${fileDir}
#更新jar自动上传路径
putDir=/home/app/xxx/bak/put
mkdir -p ${bakDir}
#先备份原jar包
cp -f ${dir}/*.jar ${bakDir}
#将上传的jar放到应用目录
cp -f ${putDir/*.jar} ${dir}/
  • start.sh
!/bin/bash
#检查当前用户是否为app用户,不能以root用户启动
if [ "USER" != "app" ];then
	echo -e "\e[31m 必须以app用户执行脚本! \e[0m"
	exit 1
fi

#基础变量
jar_name=xxx.jar
jar_path=/home/app/xxx
jar_log=/home/app/logs/nohup_`date +%y-%m-%d`_out.log
#初始化方法,选择需要启动的jr包
init(){
	echo "请输入数字选每要执行的jar包:1=xxx-1,jar,2=xxx-2.jar,3=xxx-3.jar"
	echo '你输入的数字为:'
	read a
	case $a in
	"1")
		jar_name=xxx-1.jar
		;;
	"2")
		jar_name=xxx-1.jar
		;;
	"3"jar_name=xxx-3.jar
		;;
	*)
		echo "\e[31m 输入错误,请重新输入 \e[0m"
		init
	esac
}
#初始调用
init

#停止应用
stop(){
	pid=$(ps -ef | grep $jar_name | grep -v grep | awk 'print $2}')
	if [ -z $pid ]; then
		echo -e "\e[33m ${jar_name}未运行! \e[0m"
	else
		echo "准备关闭进行${pid}"
		kill -9 $pid
		echo -e "\e[32m ${jar_name}已关闭!\e[0m"
	fi
}
#启动应用
start(){
	pid=$(ps -ef | grep $jar_name | grep -v grep | awk '{print $2)')
	if [ -z $pid ]; then
		cd $jar path
		nohup java -jar $jar_name > $jar_log 2>&1 &
		sleep 15s
		pid=$(ps -ef | grep $jar_name | grep -v grep | awk '{print $2}')
		if [-z $pid ]; then
			echo -e "\e[31m 应用${jar_name}启动失败,请检查!\e[0m"
		else
			echo -e "\e[32m 应用${jar_name}启动成功,pid=${pid} \e[0m"
		fi
	else
		echo -e "\e[33m 应用${jar_name}正在运行,pid=${pid} \e[0m"
	fi
}
#应用状态查看
status(){
	pid=$(ps -ef | grep $jar_name | grep -v grep | awk '{print $2}')
	if [ -z $pid ]; then
		echo -e "\e[33m 应用${jar_name}未运行 \e[0m"
	else
		echo -e "\e[32m 应用${jar_name}正在运行,pid=${pid} \e[0m"
	fi
}

#重启应用
restart(){
	stop
	sleep 2s
	echo "停止完成,准备启动jar包"
	start
}

#操作选项
action(){
	echo "请输入数字选择要执行的操作:1=启动,2=重启,3=停止,4-查看运行状态,5=退出"
	echo '你输入的字为:'
	read a
	case $a in
	"1")
		start
		;;
	"2")
		restart
		;;
	"3")
		stop
		;;
	"4")
		status
		;;
	"5")
		exit 1
		;;
	*)
		echo "输入错误,请重断输入"
		action
	esac
}
	
#调用操作选项
action
  • startAll.sh
!/bin/bash
if [ "$USER" != "app" ]; then
	echo -e "\e[31m 必须以app用户执行脚本! \e[0m"
	exit 1
fi

jar_path=/home/app/xxx
jar_log=/home/app/logs/nohup_`date +%y-%m-%d`_out.log
jarNames = ("xxx-1.jar" "xxx-2.jar" "xxx-3.jar")

echo "开始启动所有应用!"
for jar_name in "${jarNames[@]}"; do
	pid=$(ps -ef|grep $jar_name|grep -v grep|awk '{print $2}')
	if [ -z $pid ]; then
		cd $jar_path
		nohup java -jar $jar_name > $jar_log 2>&1 &
		sleep 15s
		pid=$(ps -ef|grep $jar_name|grep -v grep|awk '{print $2}')
		if [ -z $pid ]; then
			echo -e "\e[31m 应用${jar_name}启动失败, 请检查! \e[0m"
		else
			echo -e "\e[32m 应用${jar_name}启动成功, pid=${pid} \e[0m"
		fi
	else
		echo -e "\e[33m 应用${jar_name}正在运行, pid=${pid} \e[0m"
	fi
done
echo "所有应用启动完成!"
  • stopAll.sh
!/bin/bash
if [ "$USER" != "app" ]; then
	echo -e "\e[31m 必须以app用户执行脚本! \e[0m"
	exit 1
fi
jarNames = ("xxx-1.jar" "xxx-2.jar" "xxx-3.jar")

echo "开始停止所有应用!"
for jar_name in "${jarNames[@]}"; do
	pid=$(ps -ef|grep $jar_name|grep -v grep|awk '{print $2}')
	if [ -z $pid ]; then
		echo -e "\e[33m ${jar_name}未运行! \e[0m"
	else
		echo "准各关闭进行$pid"
		kill -9 $pid
		sleep 3s
		echo -e "\e[32m ${jar_name}已关闭! \e[0m"
	fi
done
echo "所有应用己停止!"

http://www.kler.cn/a/108388.html

相关文章:

  • 机器学习-35-提取时间序列信号的特征
  • PVE纵览-安装系统卡“Loading Driver”的快速解决方案
  • 用 Python 从零开始创建神经网络(三):添加层级(Adding Layers)
  • ubuntu22.04 安装FFmpeg,并进行视频的转化格式和裁剪
  • QTcpSocket 服务端和客户端
  • 工作和学习遇到的技术问题
  • 安全和便捷:如何将运营商二要素API应用于实名制管理中
  • 网络安全—小白自学
  • 数据结构和算法(15):排序
  • 【QT】对象树
  • 14. 机器学习 - KNN 贝叶斯
  • React-快速搭建开发环境
  • openpnp - 汇川伺服和冰沙主板的连接
  • 2023辽宁省赛E
  • MySQL篇---第六篇
  • 最新FL Studio 21.2中文版即将发布,2024年会有哪些新功能呢?
  • css overflow-x: scroll 滚动不展示/隐藏滚动条 /如何滚动
  • Lauterbach使用指南之RunTime功能
  • ROS自学笔记十七:Arbotix
  • 视频特效制作软件 After Effects 2023 mac中文版介绍说明
  • 基础课13——数据异常处理
  • 【STM32】GPIO控制LED(HAL库版)
  • QT5.15在Ubuntu22.04上编译流程
  • 归并排序——
  • san.js源码解读之模版解析(parseTemplate)篇——readCall函数
  • Python-自动化绘制股票价格通道线