我的技术学习物语果然有问题
(最后更新 )

SpringBoot部署启动

SpringBoot部署启动

序言

在开发中,经常需要部署SpringBoot服务,所以来简单记录一下我比较常用的一些部署方式。

简单粗暴的脚本

这种方法其实就是直接使用java -jar命令进行启动Jar包,所以得需要系统安装好Java的环境,然后打包好服务

#!/bin/bash

JAVAHOME=$JAVA_HOME

echo "--------start--------"

PID=$(ps -ef|grep app.jar  |grep -v grep|awk '{print $2}')

if [ ! $PID ]; then
    nohup java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Xms512m -Xmn768m -Xmx1024m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC app.jar > app.log 2>&1 &
    echo "--------------start success-----------"
    exit
else
    kill -9 ${PID}
    echo "--------------kill success-----------"
    echo "---------------now wait start-------"
    nohup java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=256m -Xms512m -Xmn768m -Xmx1024m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC app.jar > app.log 2>&1 &
    echo "--------------start success-----------"
    exit
fi

注意这种方法,简化了一些重启的操作,会寻找是否有名字为app.jar的服务进程,所以服务器上如果部署有多个服务,那么jar包不要重名,或者修改成路径

参数版脚本文件

这是我自己参考,然后修改的一个脚本文件,只要将该脚本文件和Jar包放入同一个目录下运行即可启动服务。

这种是本地启动的方式,所以需要自行配置服务器的Java环境。

#!/bin/bash

# 文件夹路径
FOLDER_PATH=''
# 服务名称
SERVER_NAME=''
# jar包名称
JAR_NAME=''
# PID文件
PID_FILE=''
# java -jar的参数
OPTIONS=''
# log文件
LOG_FILE=''

# 使用说明
usage() {
  echo "Usage:  sh ****.sh [OPTION]... "
  echo -e "\033[43;37m 注意: 需要添加参数运行,否则无法成功运行 \033[0m"
  echo -e "\033[43;37m 注意: 需要将本sh文件和jar包放在同一个文件夹 \033[0m"
  echo "当前OPTION参数有以下几种"
  echo "  --info       查看当前服务信息"
  echo "  --start      启动服务"
  echo "  --stop       停止服务"
  echo "  --restart    重启服务"
  echo "  --status     查询服务运行状态"
  exit 1
}

# 初始化
init() {
  FOLDER_PATH=$( pwd )
  JAR_NAME=$( ls -l |grep  .jar | awk '{print$9}' )
  SERVER_NAME=$( basename ${JAR_NAME} .jar )
  PID_FILE=${SERVER_NAME}\.pid
  LOG_FILE=${SERVER_NAME}\.log
  OPTIONS='-Xms256m -Xmx512m'
}

# 获取环境信息
info() {
  echo "----------检测是否有Java环境----------"
  if ! command -v java &> /dev/null
  then
    echo "-bash: java: command not found"
    echo "请检查是安装了Java环境,是否配置了环境变量"
  else
    echo "----------当前Java的环境为----------"
    echo ""
    echo "$( java -version )"
  fi
  echo "----------当前文件夹路径----------"
  echo "当前文件夹路径为${FOLDER_PATH}"
  echo "----------启动服务的信息----------"
  echo "当前服务名称为${SERVER_NAME}"
  echo "需要启动的jar包名称为${JAR_NAME}"
  echo "保存的PID文件名称为${PID_FILE}"
  echo "保存的LOG文件名称为${LOG_FILE}"
  echo "----------java -jar的参数----------"
  echo "当前参数为${OPTIONS},需要更改请执行 -setOptions参数进行修改"
}

# 查询当前程序是否运行
is_running() {
  pid=`ps -ef|grep $JAR_NAME | grep -v grep | awk '{print $2}' `
  # pid是否存在,存在返回1,不存在返回0
  if [ -n "${pid}" ]; then
    return 1
  else
    return 0
  fi
}

# 启动服务
start() {
  is_running
  # 如果服务没有运行,则启动服务,否则不启动
  if [ $? -eq "0" ]; then
    init
    echo "服务启动中,请稍后"
    nohup java ${OPTIONS} -jar ${JAR_NAME} >${LOG_FILE} 2>&1 &
    echo $! > ${PID_FILE}
    echo "服务启动成功,当前的PID为$( cat ${PID_FILE} )"
  else
    echo "目标服务正在运行,请勿再次启动"
  fi
}

# 停止服务
stop() {
  is_running
  if [ $? -eq "0" ]; then
    echo "没有检测到服务启动,请启动之后在尝试"
    exit 2
  fi
  pid=$(cat ${PID_FILE})
  kill ${pid}
  rm -rf ${PID_FILE}
  sleep 1
  is_running
  if [ $? -eq "1" ]; then
    kill -9 ${pid}
  fi
  echo "成功结束${SERVER_NAME}的进程"
}

# 查询服务运行状态
status() {
  is_running
  if [ $? -eq "1" ]; then
    echo "${SERVER_NAME}服务正在运行中,当前服务的PID为${pid}"
  else 
    echo "${SERVER_NAME}服务没有在运行"
  fi
  exit 0
}

# 重启服务
restart() {
  is_running
  if [ $? -eq "1" ]; then
    stop
    start
  else
    echo "当前服务并没有运行,请运行之后在尝试"
  fi
  exit 0
}

init

case "$1" in
  "--info")
    info
    ;;
  "--start")
    start
    ;;
  "--stop")
    stop
    ;;
  "--status")
    status
    ;;
  "--restart")
    restart
    ;;
  *)
    usage
    ;;
esac

exit 0

以下是使用方法

	# 获取当前服务信息
	sh start.sh --info
	# 启动服务
	sh start.sh --start
	# 停止服务
	sh start.sh --stop
	# 查询服务状态
	sh start.sh --status
	# 重启服务
	sh start.sh --restart
	# 提示使用信息
	sh start

其实这个脚本文件多多少少还是有一点问题的,提示信息也不是很美观,但是自己使用还是没什么问题的。

自动maven打包的Dockerfile

这种方法是通过Docker部署的方式,将源码使用maven打包成jar包,然后在容器内运行jar包。

步骤:

  1. 拉取Springboot源代码
  2. 如果需要自定义maven配置,请添加maven配置文件在于源码目录,或自己添加
  3. 修改服务打包生成的JAR包文件名
  4. 制作镜像

使用Docker的话,得自行选择需要的JDK镜像和Maven版本镜像,然后修改服务打包出来后的服务名即可。

# 多阶段构建:第一阶段用于编译 Spring Boot 项目
FROM maven:3.8.1-openjdk-17 AS builder
LABEL stage=builder

# 设置工作目录
WORKDIR /app

# 拷贝项目文件
COPY pom.xml .
COPY src ./src
# 如果需要自定义maven镜像仓库配置,请添加maven配置文件
COPY settings.xml /root/.m2/settings.xml

# 编译并打包(跳过测试)
RUN mvn clean package -DskipTests

# 第二阶段:运行阶段(基于轻量级 JRE 镜像)
FROM eclipse-temurin:17-jre-alpine
LABEL maintainer="yww@yww52.com"

# 设置时区
ENV TZ=Asia/Shanghai
RUN apk add --no-cache tzdata && \
    ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && \
    echo $TZ > /etc/timezone && \
    rm -rf /var/cache/apk/*

# 定义 JAR 名称变量(需自定义)
ARG JAR_NAME=app.jar

# 定义 JVM 参数和应用目录
ARG JAR_NAME=app.jar
ENV JAVA_OPTS="-Xms512m -Xmx1536m -Xmn614m -Xss256k -XX:SurvivorRatio=6 -XX:+UseG1GC -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
ENV APP_HOME=/app

# 创建非 root 用户并设置权限
RUN adduser -D appuser && \
    mkdir -p $APP_HOME && \
    chown -R appuser:appuser $APP_HOME
USER appuser

# 设置工作目录
WORKDIR $APP_HOME

# 从构建阶段复制生成的 JAR 文件
COPY --from=builder /app/target/*.jar ${JAR_NAME}

# 暴露应用端口
EXPOSE 9872

# 启动命令(使用 exec 确保 Java 成为 PID 1)
ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar ${JAR_NAME}"]

这个制作镜像的方式会有个问题,就是每次制作镜像都需要去跑maven下载依赖,然后打包,时间花费的很多,而且有时候有些maven依赖在仓库上获取不到,所以这种方式适合一些自建有maven仓库的项目,比如自建有Nexus,早就下载好依赖上传到仓库的项目。 不然的话还是在本地打包后在制作镜像吧,这样也快速,就是会很麻烦,不够自动化。

打包后的Dockerfile

步骤

  1. 打包好的JAR包
  2. 准备Dockerfile
  3. 修改服务打包生成的JAR包文件名
  4. 制作镜像
FROM eclipse-temurin:17-jre-alpine
LABEL maintainer="yww@yww52.com"

# 定义应用相关环境变量
ENV JAVA_OPTS="-Xms512m -Xmx2048m -Xmn614m -Xss256k -XX:SurvivorRatio=6 -XX:+UseG1GC -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
ENV APP_HOME=/app
ARG JAR_NAME=app.jar

# 设置时区
ENV TZ=Asia/Shanghai
RUN apk add tzdata \
    && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
    && echo $TZ > /etc/timezone \
    && apk del tzdata \
    && rm -rf /var/cache/apk/*

# 创建非root用户并设置权限
RUN adduser -D appuser && \
    mkdir -p $APP_HOME && \
    chown -R appuser:appuser $APP_HOME
USER appuser

# 设置工作目录和应用目录
WORKDIR $APP_HOME

# 复制已打包的 JAR 文件
COPY ${JAR_NAME} $APP_HOME/${JAR_NAME}

# 暴露应用端口
EXPOSE 9872

# 启动命令(使用环境变量配置 JVM 参数)
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar ${JAR_NAME}"]