前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >玩转 Spring Boot 应用篇(项目打包、发布)

玩转 Spring Boot 应用篇(项目打包、发布)

作者头像
一猿小讲
发布2022-05-31 09:47:54
6680
发布2022-05-31 09:47:54
举报
文章被收录于专栏:一猿小讲一猿小讲

0.

0.0. 历史文章整理

玩转 Spring Boot 入门篇

玩转 Spring Boot 集成篇(MySQL、Druid、HikariCP)

玩转 Spring Boot 集成篇(MyBatis、JPA、事务支持)

玩转 Spring Boot 集成篇(Redis)

玩转 Spring Boot 集成篇(Actuator、Spring Boot Admin)

玩转 Spring Boot 集成篇(RabbitMQ)

玩转 Spring Boot 集成篇(@Scheduled、静态、动态定时任务)

玩转 Spring Boot 集成篇(任务动态管理代码篇)

玩转 Spring Boot 集成篇(定时任务框架Quartz)

玩转 Spring Boot 原理篇(源码环境搭建)

玩转 Spring Boot 原理篇(核心注解知多少)

玩转 Spring Boot 原理篇(自动装配前凑之自定义Starter)

玩转 Spring Boot 原理篇(自动装配源码剖析)

玩转 Spring Boot 原理篇(启动机制源码剖析)

玩转 Spring Boot 原理篇(内嵌Tomcat实现原理&优雅停机源码剖析)

玩转 Spring Boot 应用篇(搭建菜菜的店铺)

玩转 Spring Boot 应用篇(解决菜菜店铺商品超卖问题)

玩转 Spring Boot 应用篇(引入Redis解决店铺高并发读的问题)

玩转 Spring Boot 应用篇(引入RabbitMQ解决店铺下单峰值问题)

玩转 Spring Boot 应用篇(序列号生成器服务实现)

0.1. 疑问

  • 开发出的 Spring Boot 应用,该如何打包?
  • 项目不可避免要引入三方依赖包,这种场景下该如何打包呢?
  • Spring Boot 应用编译打包后,该如何发布呢?

本次重点探讨 Spring Boot 应用的打包和发布。

1. 创建项目(ToyApp)

为了演示需要,基于 Spring Boot 创建一个 WEB 项目 ToyApp。

稍微注意一点:本次引入了一个三方依赖包(idgenerator-spring-boot-starter 是自定义的一个序列号生成器 starter)。

准备好环境,下面一起瞅瞅引入了三方依赖的 Spring Boot 该如何打包?

2. 编译打包

采用 IDEA 集成的 Maven 环境来对 Spring Boot 项目编译打包,可谓是超级 easy。

此时,通过反编译工具来瞅瞅编译打包成功之后的 ToyApp-0.0.1-SNAPSHOT.jar 里面的东西是否缺失,尤其是引入的三方依赖 jar 包。

通过反编译,发现引入的三方依赖 jar 包,没有打进去,咋回事儿?

由于 scope 为 system 的包 maven 默认是不打包进去的,所以解决方案就很简单:只需在 pom.xml 中指定一下 includeSystemScope 就可以。

代码语言:javascript
复制
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>

再次编译打包,然后对打成的 jar 包反编译观察一二。

至此,Spring Boot 项目打包就完成了,如果经历过传统的项目开发,相对传统的打包方式,你会知道着实简单不少。

3. 应用发布

3.1 一行命令的演化

运行 Spring Boot 打包之后的 jar 方式也简单,只需一行命令就行。

代码语言:javascript
复制
java -jar /Users/caicai/ToyApp-0.0.1-SNAPSHOT.jar

执行效果:

此时,服务是启动了,但是不能关闭这个窗口,一旦关闭服务就停止了,不得不考虑后台运行,并且还想看日志,所以这一行命令演变成了这个鸟样。

代码语言:javascript
复制
java -jar /Users/caicai/ToyApp-0.0.1-SNAPSHOT.jar > ToyApp.out &

执行启动时,效果如下,然后就可以轻松看日志输出了。

如果项目组中你既是研发又充当运维的角色,到这基本就完事儿了,因为相信通过熟练操作,会形成肌肉反应,你肯定能记住这一行命令。

不过,若是分工明确,生产权限隔离的话,一般都是运维同事来操作发布,所以还得想办法让运维同事省力,不得不考虑脚本化。

3.2 两个脚本

每个项目组的风格不同,而我习惯采取如下目录结构进行管理。

代码语言:javascript
复制
.
├── bin(脚本存放目录)
│   ├── start.sh
│   └── stop.sh
├── lib(jar包存放目录)
│   └── ToyApp-0.0.1-SNAPSHOT.jar
└── logs(日志目录)
    ├── toyapp.gc.log
    └── toyapp.out

首先创建项目目录例如 toyapp,然后分别创建 bin、lib、logs 目录;把 ToyApp-0.0.1-SNAPSHOT.jar 拷贝至 lib 目录下;bin 目录主要存放脚本。

  • 启动脚本(start.sh)

在 bin 目录下,创建 start.sh,应用启动脚本。

代码语言:javascript
复制
#!/bin/bash

#配置 Java 环境变量
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_251.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH
#定义应用名
App_Name=toyapp
#定义应用所在目录
App_Path=/Users/caicai/${App_Name}
#定义可执行文件的路径
JAR_PATH=${App_Path}/lib/ToyApp-0.0.1-SNAPSHOT.jar
#jvm启动参数
JAVA_OPTS="-Duser.timezone=GMT+8 -server -Xms4096m -Xmx4096m  -XX:MaxMetaspaceSize=256m -Xloggc:${App_Path}/logs/${App_Name}.gc.log -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5 -XX:+PrintGC -XX:+PrintGCTimeStamps  -XX:+PrintGCDetails  -XX:+PrintGCApplicationStoppedTime"
#启动JAVA进程函数
CURRENT_COUNT=`ps -ef|grep java |grep ${App_Name} |grep -vc grep`
if [ $CURRENT_COUNT -eq 0 ]
then
        Log_Name=$(echo ${App_Name}|awk  -F"-" '{ print $NF }')
        nohup java -Dfunc_type=${App_Name}  $JAVA_OPTS  -Dfile.encoding=utf-8  -jar  $JAR_PATH  > ${App_Path}/logs/${Log_Name}.out  2>&1 &
  PROCESS_ID=`ps -ef | grep  "${App_Name}" |grep -v grep | awk '{ print $2 }'`
      echo "\033[44;37m ☺☺☺☺☺启动应用 ${App_Name} 成功,进程 id 为 ${PROCESS_ID} ☺☺☺☺☺ \033[0m"
else
    echo "\033[41;37m ☺☺☺☺☺ 应用 ${App_Name} 已经被启动了 ☺☺☺☺☺ \033[0m"
fi
  • 停止脚本(stop.sh)
代码语言:javascript
复制
#!/bin/bash

# 定义应用名称
App_Name=toyapp

echo "\033[44;37m ☺☺☺☺☺ 开始停止 ${App_Name} 应用 ☺☺☺☺☺ \033[0m"
ps -ef | grep ${App_Name} | grep -v grep | awk '{print$2}' | xargs kill
echo "\033[41;37m ☺☺☺☺☺ 应用 ${App_Name} 停止成功!☺☺☺☺☺ \033[0m"
  • 脚本验证

应用启停脚本编写完成,执行脚本,蓝红搭配,sao 极了有没有?!

至此,Spring Boot 项目最基本的发布方式就完事了,可以直接执行脚本完成项目的启动和停止,爽歪歪!

4. 例行回顾

本文主要是对 Spring Boot 应用打包发布的探究,在面对引入三方依赖编译打包时,默认不会打进去,需要配置 includeSystemScope 方能包含 system 的三方依赖;接着重点讲解了如何用一行命令启动 Spring Boot 项目,以及如何把命令封装成脚本来对线上的应用进行发布操作。

如果你眼下运气欠佳,请不要气馁。一朵花的凋零荒芜不了整个春天,一次挫折也击垮不了整个人生。过去的已无法撤回,但未来还可努力书写。要相信,人生路上的每一次磨砺都是未来的铺垫 。 人民日报

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一猿小讲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档