• 简单的项目部署脚本(转载)


    原文链接 https://mp.weixin.qq.com/s/jjW2aIi_KUusQdc9uLnUGg

    1. 环境准备

    1.1 java

    yum install -y java-1.8.0-openjdk-devel
    #/etc/profile环境变量
    # jdk 8
    export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.382.b05-1.amzn2.0.2.x86_64
    export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export PATH=$PATH:$JAVA_HOME/bin
    # 保存后,source生效
    source /etc/profile
    

    1.2 maven

    mkdir /opt/tools/maven
    cd /opt/tools/maven
    wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz
    tar -zxvf apache-maven-3.8.8-bin.tar.gz
    #配置环境变量
    vim /etc/profile
    # maven 3.8.8
    export MAVEN_HOME=/opt/tools/maven/apache-maven-3.8.8
    export PATH=${PATH}:${MAVEN_HOME}/bin
    #保存后source生效
    source /etc/profile
    

    1.3 git

    yum -y install git
    ssh-keygen
    

    把~/.ssh/id_rsa.pub内容添加到远程仓库的ssh秘钥中

    2 以项目springboot-demo为例,创建项目路径

    mkdir -p /opt/app/server/springboot-demo
    

    编写部署脚本

    
    cd /opt/app/server/springboot-demo
    touch start.sh
    chmod +x start.sh
    

    start.sh脚本内容

    #!/bin/bash
    #项目路径
    WORK_DIR=/opt/app/server/springboot-demo
    #项目名称
    PROJECT_NAME=springboot-demo
    #获取代码
    cd $WORK_DIR
    if [ ! -d $PROJECT_NAME ];then
            #如果项目文件夹内不存在,则从远程仓库拉取指定分支代码
            git clone -b branch_name git@gitlab.com:xxx.git
            #进入应用目录
            cd $PROJECT_NAME
    else
            #如果项目文件夹存在,说明之前拉取过,那么进入项目路径拉取最新代码
            cd $PROJECT_NAME
            git pull
    fi
    #maven构建
    mvn -U clean compile package -Dmaven.test.skip=true -P$1
    # 如果构建失败,退出脚本
    if [ $? -ne 0 ]; then
            echo "maven build failue!"
            exit 1
    fi
    
    
    #部署项目
    #找到之前启动的服务进程
    SPRINGBOOT_DEMO_PID=$(ps -ef | grep "springboot-demo-$1.jar" | egrep -v "grep|$$" | awk 'NR==1{print $2}')
    #如果已经存在进程,则发送kill信号终止
    [ -n "$SPRINGBOOT_DEMO_PID" ] && kill $SPRINGBOOT_DEMO_PID
    # 休眠10s,等待进程终止
    sleep 10
    #把maven编译打包的最新jar包拷贝到工作目录
    cp  target/springboot-demo-$1.jar $WORK_DIR
    #再次检查进程是否终止,如果没有终止则发送kill -9信号强行终止
    [ -n "$SPRINGBOOT_DEMO_PID" ] && kill -9 $SPRINGBOOT_DEMO_PID
    #使用nohup java -jar命令后台启动服务
    nohup java -Djava.security.egd=file:/dev/./urandom -Xms1g -Xmx1g -Xmn512m -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+CMSScavengeBeforeRemark -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:/mnt/applogs/$springboot-demo/gc.log  -Dfile.encoding=utf-8  -jar $WORK_DIR/springboot-demo-$1.jar  >/dev/null 2>&1 &
    echo "springboot-demo startup success"
    

    该脚本核心做了以下几件事情:

    • 从远程仓库拉取项目代码;如果已经存在项目目录,则进入目录拉取最新代码
    • 使用mvn命令编译打包,并输出可执行jar到target目录,如果编译失败则退出执行
    • 找出服务进程,并发送kill执行进行终止服务进程,并且休眠10s,给服务进程足够的时间处理剩余的事情
    • 从项目目录的target文件夹拷贝可执行jar到项目工作目录
    • 再次检查服务进程是否已经终止,如果没有终止则强行终止(理论上10s可以正常终止,休眠时间可按需调整)
    • 通过nohup java -jar命令后台运行服务,启动成功后打印启动成功日志

    执行start.sh脚本打包部署

    sh start.sh dev
    

    3. 基于docker启动的部署脚本

    有些项目团队喜欢使用docker启动java服务,那么我们同样可以将上述脚本稍做改造,来实现基于shell+docker的简单项目部署能力。

    安装docker运行环境(服务器是aws ec2):

    sudo yum update -y
    sudo amazon-linux-extras install docker
    
    
    sudo service docker start
    sudo systemctl enable docker
    

    项目路径不再重复创建,还是基于上一小节的路径,在项目工作路径创建Dockerfile文件,内容如下:

    FROM openjdk:8
    ARG PROFILES
    ARG APP_NAME_ARG
    ARG SERVER_PORT_ARG
    ENV PROFILES_ACTIVE ${PROFILES}
    ENV APP_SERVER_PORT ${SERVER_PORT_ARG}
    ENV LANG=zh_CN.UTF-8
    RUN apt-get update && apt-get install -y locales && sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
    VOLUME /tmp
    ADD ${APP_NAME_ARG}-${PROFILES}.jar /app.jar
    RUN bash -c 'touch /app.jar'
    EXPOSE ${APP_SERVER_PORT}
    ENTRYPOINT ["sh", "-c", " date && java -XX:+UseG1GC -Dfile.encoding=utf-8 -Dserver.port=${APP_SERVER_PORT} \
    -jar /app.jar --spring.profiles.active=${PROFILES_ACTIVE}"]
    

    Dockerfile文件接收三个参数:

    • PROFILES:激活的profile
    • APP_NAME_ARG:应用名称
    • SERVER_PORT_ARG:服务端口

    同样在项目工作目录创建start.sh脚本:

    cd /opt/app/server/springboot-demo
    touch start.sh
    chmod +x start.sh
    

    脚本内容如下:

    #!/bin/bash
    WORK_DIR=/opt/app/server/springboot-demo/
    PROJECT_NAME=springboot-demo
    #获取代码
    cd $WORK_DIR
    if [ ! -d $PROJECT_NAME ];then
            git clone -b branch_name git@gitlab.com:xxx.git
            cd $PROJECT_NAME
    else
            cd $PROJECT_NAME
            git pull
    fi
    #maven构建
    mvn -U clean compile package -Dmaven.test.skip=true -P$1
    if [ $? -ne 0 ]; then
            echo "maven build failue!"
            exit 1
    fi
    #部署项目
    cp  target/springboot-demo-$1.jar $WORK_DIR
    docker build --build-arg PROFILES=$1 --build-arg APP_NAME_ARG=$2 --build-arg SERVER_PORT_ARG=$3 -t $2:0.0.1 .
    docker stop $2
    docker rm $2
    docker rmi $(docker images | awk '/^/ { print $3 }')
    docker run -v /mnt:/mnt -p $3:$3 --restart=always --name $2 -d $2:0.0.1
    
    
    echo "springboot-demo startup success"
    

    该脚本和前边的类似,做了以下几件事情:

    • 从远程仓库拉取项目代码;如果已经存在项目目录,则进入目录拉取最新代码
    • 使用mvn命令编译打包,并输出可执行jar到target目录,如果编译失败则退出执行
    • 从项目目录的target文件夹拷贝可执行jar到项目工作目录
    • 使用docker命令构建java服务镜像,并定义传入三个入参
    • 停止老的docker中的java服务容器,并移除
    • 找到老的java服务镜像,并移除
    • 启动新的java服务容器,启动成功后打印启动成功日志

    执行start.sh脚本打包部署:

    sh start.sh dev springboot-demo 8099
    

    4. 部署日志记录

    4.1 将部署开始和结束的日志追加到部署日志中

    # 日志文件路径
    LOG_FILE="/opt/app/server/springboot-demo/deploy.log"
    
    # 记录当前时间和执行的命令到日志文件
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting start.sh script" >> "$LOG_FILE"
    
    # 部署脚本内容
    
    # 记录脚本执行结束的时间到日志文件
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] End of start.sh script" >> "$LOG_FILE"
    

    4.2 部署结果通知

    可以将核心节点的错误或者失败内容通过webhook发送到对应的告警平台,比如钉钉、飞书机器人等。

    以maven编译打包失败发送飞书告警为例:

    
    ROBOT_TOKEN="xxxxxx"
    REQ_PATH="https://open.feishu.cn/open-apis/bot/v2/hook/$ROBOT_TOKEN"
    REQ_TYPE="Content-Type: application/json"
    
    
    mvn -U clean compile package -Dmaven.test.skip=true -P$1
    if [ $? -ne 0 ]; then
            echo "maven build failue!"
            BODY="{\"msg_type\":\"interactive\",\"card\":{\"config\":{\"wide_screen_mode\":false,\"enable_forward\":true},\"elements\":[{\"tag\":\"markdown\",\"content\":\" \n$CURR_DATE $CURR_TIME \n**服务器别名** : $CURR_IP \n\n\n**关注进程名** : $FOCUS_PROCESS \n**警告级别** :  CRITICAL \n**警告内容** : mvn构建失败!\"}],\"header\":{\"title\":{\"tag\":\"plain_text\",\"content\":\"[$CURR_ENV 环境]: server-Alert\"},\"template\":\"red\"}}}"
        curl "$REQ_PATH" \
        -H "$REQ_TYPE" \
        -d "$BODY"
            exit 1
    fi
    
  • 相关阅读:
    【Python】图像和办公文档的处理
    MySQL-事务隔离机制的实现
    QEMU(Quick EMUlator)学习
    计算机服务器中了faust勒索病毒怎么解密,faust勒索病毒解密工具流程
    C++11_初始化列表
    软件质量保证计划书(2024Word完整版)
    C++——多态
    HCIP 第五天实验
    基于threejs的3d可视化工厂示例
    Spark面试题(二)
  • 原文地址:https://blog.csdn.net/u010230019/article/details/139562587