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

简单的项目部署脚本

    • 1. 环境准备
      • 1.1 java
      • 1.2 maven
      • 1.3 git
    • 2 以项目springboot-demo为例,创建项目路径
    • 3. 基于docker启动的部署脚本
    • 4. 部署日志记录
      • 4.1 将部署开始和结束的日志追加到部署日志中
      • 4.2 部署结果通知

原文链接 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_NAMEgit pull
fi
#maven构建
mvn -U clean compile package -Dmaven.test.skip=true -P$1
# 如果构建失败,退出脚本
if [ $? -ne 0 ]; thenecho "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 dockersudo 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 ];thengit clone -b branch_name git@gitlab.com:xxx.gitcd $PROJECT_NAME
elsecd $PROJECT_NAMEgit pull
fi
#maven构建
mvn -U clean compile package -Dmaven.test.skip=true -P$1
if [ $? -ne 0 ]; thenecho "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 '/^<none>/ { print $3 }')
docker run -v /mnt:/mnt -p $3:$3 --restart=always --name $2 -d $2:0.0.1echo "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 ]; thenecho "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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/25475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IT闲谈-Kylin入门教程

目录 一、引言二、Kylin简介三、环境准备四、安装与配置五、数据导入与建模六、查询与分析七、总结 一、引言 Apache Kylin是一个开源的分布式分析引擎&#xff0c;旨在提供Hadoop/Spark之上的SQL接口及多维分析&#xff08;OLAP&#xff09;能力以支持超大规模数据。Kylin通过…

【设计模式】结构型设计模式之 享元模式

文章目录 介绍关键概念 应用举例象棋游戏共享棋子对象文本编辑器中文字格式设计成享元模式 享元模式在 Java 中的应用享元模式在包装类缓存中的应用享元模式在 String 中的应用 对比享元模式和单例模式的区别享元模式与缓存的区别 总结优点缺点 介绍 享元模式&#xff0c;”享…

简单用java集合模拟斗地主发牌操作

简易斗地主发牌&#xff08;熟悉java集合的使用&#xff09; 1、需求 按照斗地主规则&#xff0c;完成洗牌发牌的动作。 具体要求如下&#xff1a; 1、准备牌&#xff1a;组装54张扑克牌 2、洗牌&#xff1a;54张牌顺序打乱 3、发牌&#xff1a;三个玩家参与游戏&#xf…

TinyVision V851s 使用 OpenCV + NPU 实现 Mobilenet v2 目标分类识别

用39块钱的V851se视觉开发板做了个小相机。 可以进行物品识别、自动追焦&#xff01; 这个超低成本的小相机是在V851se上移植使用全志在线开源版本的Tina Linux与OpenCV框架开启摄像头拍照捕获视频&#xff0c;并结合NPU实现Mobilenet v2目标分类识别以及运动追踪等功能......并…

以无厚,入有间,做一件事为什么靠努力不行,不能长期维持

庖丁解牛&#xff0c;并不是在说人和技巧&#xff0c;而是在说解牛不在于刀的锋利&#xff0c;而是怎样才能做到让刀不产生损耗&#xff0c;就是熟悉牛肉纹路&#xff0c;按照纹路和肉骨间隙进行操刀。这就是尊重自然规律&#xff0c;对于人也是一样的&#xff0c;如果所有事情…

C++输入输出与IO流

C 输入输出与I/O流 文章目录 C 输入输出与I/O流IO类型与基础特性概念与特性IO状态输出缓冲区 文件输入输出文件模式 string流IO处理中常用的函数及操作符综合练习与demo一、 创建文件并写入二、控制台输入数据并拆分存储三、读写电话簿 IO类型与基础特性 C11标准提供了几种IO处…

el-date-picker设置结束时间为23:59:59

type datetime <el-date-pickerstyle"width: 100%"v-model"currentEditConfigObj.expirationDate"placeholder"请选择结束时间"type"datetime"default-time[23:59:59]value-format"yyyy-MM-dd HH:mm:ss"format"yy…

Python使用Flask构建简单的web应用

构建一个简单的 Flask Web 应用程序是学习 Python Web 开发的良好起点。Flask 是一个轻量级的 WSGI Web 应用框架&#xff0c;它的主要目标是让开发者更容易构建 Web 应用&#xff0c;同时保持简单性和灵活性。下面我们将详细介绍如何使用 Flask 构建一个简单的 Web 应用&#…

一个支持多存储的文件列表/WebDAV程序,使用 Gin 和 Solidjs

网址 https://github.com/alist-org/alist 看了下介绍&#xff0c;支持挺多oss和云盘的&#xff0c;看了下代码&#xff0c;值得学习一下 部署方便&#xff0c;开箱即用 文件预览&#xff08;PDF、markdown、代码、纯文本……&#xff09; 画廊模式下的图像预览 视频和音频预…

android 抓取 logcat 日志的方法

1.找到这个路径 2.然后执行命令&#xff08;adb logcat -v time >.\\logcat.log&#xff09;&#xff0c;开始抓取日志 3.这个时候就可以去操作APP了&#xff0c;复现BUG了。 Ctrlc 结束日志抓取 adb logcat -c 清空旧日志

逆市创新高!水电“双雄“是怎样炼成的? 博通,赢麻了!

高分红夏季用电高峰AI的尽头是电力 6月7日&#xff0c;长江电力&#xff08;600900&#xff09;、华能水电&#xff08;600025&#xff09;股价双双上涨。截至收盘&#xff0c;长江电力股价上涨1%&#xff0c;收于28.31元/股&#xff1b;华能水电股价上涨1.52%&#xff0c;收于…

Matlab|遗传粒子群-混沌粒子群-基本粒子群

目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点&#xff08;重要的事情说三遍&#xff09;&#xff0c;对于采用智能算法的模型&#xff0c;可以采用算法改进的方式来达到提高整个文章创新水平的目的&…

基于STM32开发的智能机器人导航系统

目录 引言环境准备智能机器人导航系统基础代码实现&#xff1a;实现智能机器人导航系统 4.1 距离传感器数据读取4.2 电机控制4.3 实时路径规划与避障4.4 用户界面与状态显示应用场景&#xff1a;智能机器人导航与控制问题解决方案与优化收尾与总结 1. 引言 智能机器人导航系…

C++: map和set的使用

目录 1.头文件 2.set和multiset的区别 3.set和map的区别 4.加了multi的区别 这里只说几个要点。 1.头文件 #include <map> #include <set> 2.set和multiset的区别 set和multiset的区别 setmultiset只能插入不重复的key可以插入重复的key一串包含重复的strin…

力扣算法题:轮转数组 -- 多语言实现

无意间看到&#xff0c;力扣存算法代码居然还得升级vip。。。好吧&#xff0c;我自己存吧 其他的题找不回来了……重写吧 golang&#xff1a; func rotate(nums []int, k int) { // 第一想到的 // n : len(nums) // k % n // newNums : nums[n-k:] // numsFeature : …

btstack协议栈实战篇--GAP LE Advertisements Scanner

btstack协议栈---总目录-CSDN博客 目录 1.GAP LE 用于接收广播的设置 2.GAP LE 广告数据转储器 3.HCI packet handler 4.log信息 实现如何扫描和解析广告。 1.GAP LE 用于接收广播的设置 GAP LE 广告作为 GAP EVENT ADVERTISING REPORT的自定义 HCI 事件被接收。要接收…

中国西部AI创新港,数字经济的新引擎

编辑&#xff1a;阿冒 设计&#xff1a;沐由 时间&#xff1a;2024年5月31日。 地点&#xff1a;西安交通大学创新港校区涵英楼千人报告厅。 人物&#xff1a;近千位政府、高校和企事业单位的代表&#xff0c;还有我。 我们的脚下&#xff0c;就是八百里秦川。 三秦自古多才俊。…

Linux基础指令(一)

前言 Linux基础指令主要学习&#xff1a;对目录、文件、压缩包、匹配查找&#xff0c;权限等操作 第一次接触ubuntu需要知道的基本知识 sudo passwd root 先给root用户设置密码 su root 切换到root用户 su zhangsan …

Django里的Form组件

Form组件提供 自动生成HTML标签和半自动读取关联数据 (“半自动”是指还得需要自己手写输入数据进来)表单验证和错误提示 要想创建并使用该组件&#xff0c;操作步骤如下&#xff1a; 在 views.py 里创建类 # 在 views.py 文件里from django import formsclass AssetForm(fo…

core dump核心转储

检查核心转储是否开启&#xff0c;否则无法生成core文件 ulimit -a 如果为0就需要修改 ulimit -c 10240 写一个会触发core命令的程序 以浮点数运算为例 #include <iostream>int main() {int i 1/0; } 在编译时使用-g选项 运行程序&#xff0c;生成core文件 gdb调试 g…