wordpress 2.0漏洞,肇庆seo,网页设计和网站建设实战大全,建筑人才网官网首页前言
上期讲了如何在windows平台搭建Java后端的开发环境#xff0c;并给出了一个简单的hello world级别的多模块代码示例。但上期仅仅是在IDEA中运行#xff0c;和正式的生产环境完全不同。 本期将讲解#xff0c;如何配置SpringBoot多模块项目的maven打包#xff0c;并分…前言
上期讲了如何在windows平台搭建Java后端的开发环境并给出了一个简单的hello world级别的多模块代码示例。但上期仅仅是在IDEA中运行和正式的生产环境完全不同。 本期将讲解如何配置SpringBoot多模块项目的maven打包并分离出lib和resource。
真实的项目不可能是运行在IDEA里的。实际的生产一般有两种模式。一则把写好的项目打包成Jar包通过命令启动jar包另一种则是把项目打包成一个docker镜像使用镜像启动。我们这里先讨论Jar包启动的情况。
一、打包配置
1.1 默认情况
我们直接在根目录点击package会在各自模块生成一个target的文件夹里面就有我们打包好的包。 我们随便找一个包打开看看会发现我们打的包异常的小只有几十k。 拿我们的主业务模块general-test来说包只包含3个模块我们的代码maven相关配置以及静态资源。application.yml放在最外层。 毫无疑问这样的包是无法直接通过java -jar命令运行的。
1.2 springboot 打包插件
在根pom中添加打包插件的版本引用
buildpluginManagementpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion${spring-boot.version}/version/plugin/plugins/pluginManagement/build而后在general-test的pom下添加如下内容
buildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdexecutionsexecutiongoalsgoalrepackage/goal/goals/execution/executions/plugin/plugins/build再次cleanpackage后观察现象。我们首先可以看到包的大小已经正常了 使用winRar打开可以发现如下目录 org中放了SpringFramework的相关内容 META-INF放了maven的pom引用以及jar包服务信息 BOOT-INF下结构如下 lib放置了项目引用需要的包包括自己写的core-commoncore-enum-memo 而classes下则放着本包的代码。 我们在打好包的位置单击右键打开命令行。 java -jar general-test-1.0.0.jar 即可启动服务器。 如果出现找不到favicon.ico的错误可以在resources/static下放一个你喜欢的美少女头像记得转成ico格式哦。
1.3 资源和配置文件的分离
2.2这样做我们就会发现一个问题配置文件被打到jar包里运维人员无法轻易的修改配置文件。那样配置文件的意义在哪里呢还不如直接写到Java文件里。 在生产上一般有2种做法。一种是使用配置中心不过这要整上一套SpringCloud的东西当然用K8S也可以实现。我们这里讲一个简单的方法通过修改打包方式来解决。
首先在Resource中把想要分离的文件拷出去
buildresources!--打包时把这些文件拷贝到外面--resourcedirectorysrc/main/java/indi/zhifa/study2024/class002/busy/generalTest/business/report/directoryincludesinclude**/*.xml/include/includestargetPath${project.build.directory}/resources/mybatis/targetPath/resourceresourcedirectorysrc/main/resources/static/directoryincludesinclude**/*.*/include/includestargetPath${project.build.directory}/resources/static/targetPath/resourceresourcedirectorysrc/main/resources/directoryincludesinclude*.yml/includeinclude*.properties/include/includestargetPath${project.build.directory}/config/targetPath/resource!--打包时为了idea能启动还要向classes里拷贝一份--resourcedirectorysrc/main/java/indi/zhifa/study2024/class002/busy/generalTest/business/report/directoryincludesinclude**/*.xml/include/includestargetPath${project.build.directory}/classes/mybatis/targetPath/resourceresourcedirectorysrc/main/resources/static/directoryincludesinclude**/*.*/include/includestargetPath${project.build.directory}/classes/static/targetPath/resourceresourcedirectorysrc/main/resources/directoryincludesinclude*.yml/includeinclude*.properties/include/includestargetPath${project.build.directory}/classes/targetPath/resource/resources....../build这样打包已经实现了需求但把包解压开后发现资源仍然存在于包中相当于浪费了空间 那我们再加个打包的配置排除这些文件
buildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-jar-plugin/artifactIdconfigurationfinalName${jar-name}/finalName!--主义properties里定义该变量打包后jar包的名字--!--排除掉配置资源等毕竟放到外面了--excludesexclude*.yml/excludeexclude*.properties/excludeexcludemybatis/**/*.xml/excludeexcludestatic/**/*/excludeexcludetemplates/**/*/exclude/excludes/configuration/plugin!--把${jar-name}包再打进包含springframework的包中--plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationfinalName${jar-name}/finalName/configurationexecutionsexecutiongoalsgoalrepackage/goal/goals/execution/executions/plugin/plugins
/build如此我们再点击package打包出的内容就会如图所示
1.4 启动jar包
把jar包config文件夹resources文件夹站到linux系统的相应位置我这里是/WORK/APP/study2024-class003
打开8080~8089的防火墙
ufw allow 8080/tcp
...输入启动命令
java -jar nbr.jar --spring.config.additional-locationconfig/ study2024-class003-001可以看出程序启动成功了。 访问192.168.0.64/doc.html即可看到swagger页面查询一个报表接口发现没有问题。
1.5 把lib包分离
其实有一说一把lib包分离在实际的生产中意义其实没有那么大。唯一的作用就是在公司的测试部署机放在外网减少打包部署的带宽消耗。但这也会造个坑就是当我们升级包时可能会忘记把更新的包拷过去导致莫名其妙的报错这非常搞心态。 pom做如下修改 pluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationfinalName${jar-name}/finalNameaddResourcestrue/addResourcesincludesincludegroupIdnothing/groupIdartifactIdnothing/artifactId/include/includesexcludesexcludegroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/exclude/excludes/configurationexecutionsexecutiongoalsgoalrepackage/goal/goals/execution/executions/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-jar-plugin/artifactIdconfigurationfinalName${jar-name}/finalNamearchive!-- 指定资源文件目录与打包的jar文件同级目录 --manifestEntriesClass-Pathresources//Class-Path/manifestEntriesmanifestaddClasspathtrue/addClasspathclasspathPrefixlib//classpathPrefix/manifest/archive!--排除掉配置资源等毕竟放到外面了--excludesexclude*.yml/excludeexclude*.properties/excludeexcludemybatis/**/*.xml/excludeexcludestatic/**/*/excludeexcludetemplates/**/*/exclude/excludes/configuration/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-dependency-plugin/artifactIdexecutionsexecutionidcopy-dependencies/idphasepackage/phasegoalsgoalcopy-dependencies/goal/goalsconfigurationoutputDirectory${project.build.directory}/lib//outputDirectory/configuration/execution/executions/plugin/plugins再进行打包观察现象 我们看到我们的包重新变小了。 把新打的包重新拷到相应的地方。而后再输入如下命令
java -jar nbr.jar -D loader.path./lib --spring.config.additional-locationconfig/ --logging.configconfig/logback.xml study2024-class003-001发现毫无问题。
二、部署环境
2.1 通常的4种环境
不考虑那种有中台的千人大厂情况一般开发团队通常会有4套部署环境。
local 本地开发环境即IDEA的环境用户个人调试dev 开发环境部署在公司内部的开发服务器中用于前后端联调。该分支服务通常不稳定经常发生代码变更。 更严谨点的做法dev也可以认为是一个测试环境公司内部服务器部署dev,dev-feature1,dev-feature2…feature表示某个新增功能通常有1个或几个程序员共同开发。测试先测试通过feature分支而后把feature合并到dev上。当测试发现dev上有bug则即刻要求开发进行修复拉取部署bugfix分支交由测试测试通过后合并到dev分支上。 但测试的最终验收以test分支为主。 dev环境下所用的数据库等中间件地址很多时候是与我们本地开发不同的。但有时候为了方便也采用相同的数据。test 测试环境部署在公司内部的测试服务器中也可以直接部署在外网的云服务器上。该服务用于交付测试代码不经常变动。测试通过后打tag可发到线上环境。 该环境的数据库等中间件与dev环境也不同。 个人观点这个环境下的数据不要让开发人员污染。放有意义的测试数据。最好由专业的测试人员提供录入。prod 线上部署环境。通常线上环境所用的数据库等中间件与测试环境也是不同的。
2.2 profile配置
正因为不同的环境可能有不同的配置。打包时要自动区分这点所以通常会在pom文件中声明这4种环境。 由于我们这里是学习配置只保留local和testlocal表示在IDEA里跑test表示放linux机器上没linux的可以用WSL我前面的文章介绍过
profiles!--本地--profileidlocal/idproperties!-- 环境标识需要与配置文件的名称相对应 --spring.profiles.activelocal/spring.profiles.active/propertiesactivation!-- 默认环境 --activeByDefaulttrue/activeByDefault/activation/profile!--测试--profileidtest/idpropertiesspring.profiles.activetest/spring.profiles.active/properties/profile/profiles2.3 把先前的yml配置文件和日志xml分环境
我们现在把这种配置文件这样 为了能够正常运行以及把对应文件拷到外面的config文件夹中xml可以做如下配置 resourcedirectorysrc/main/config/${spring.profiles.active}/directoryincludesinclude*.yml/includeinclude*.properties/includeincludelogback.xml/include/includestargetPath${project.build.directory}/config/targetPath/resourceresourcedirectorysrc/main/config/${spring.profiles.active}/directoryincludesinclude*.yml/includeinclude*.properties/includeincludelogback.xml/include/includestargetPath${project.build.directory}/classes/targetPath/resource点击compile观察现象 我想这样就实现了
三、maven打包命令
实际开发时可不会在IDEA里打包而是在jenkins中在linux下使用命令打包。 我们先在windows中尝试一下
mvn clean package -pl busy/general-test -am -Ptest嗯这就成功了。
四、创建一个启动和关闭脚本
实际开发中我们不可能用java -jar来启动服务。另外同一个jar包可能会部署多个实例。这时我们可以写一个shell脚本来做启动和关闭。 在如图位置创建这俩脚本 在resource的配置中添加拷贝脚本的配置 resourcedirectorysrc/main/bin/${spring.profiles.active}/directoryincludesinclude*.sh/includeinclude*.bat/include/includestargetPath${project.build.directory}/bin/targetPath/resource4.1 启动脚本startup.sh
#!/bin/bashcygwinfalse
darwinfalse
os400false
case uname in
CYGWIN*) cygwintrue;;
Darwin*) darwintrue;;
OS400*) os400true;;
esac
error_exit ()
{echo ERROR: $1 !!exit 1
}#参数解析
VERSION
appName
PORT8081
ARGSgetopt -o v:a:p: --long version:,appName:,port: -n $0 -- $
if [ $? ! 0 ]; thenecho Terminating...exit 1
fi
echo ARGS[$ARGS]
eval set -- ${ARGS}while true
docase $1 in-v|--version)case $2 in)VERSIONshift 1;;;*)VERSION$2shift 2;;;esac;;-a|--appName)case $2 in)appNamemainshift 1;;;*)appName$2shift 2;;;esac;;-p|--port)case $2 in)PORT8081shift 1;;;*)PORT$2shift 2;;;esac;;--) shift ; break ;;*) echo Internal error! ; exit 1 ;;esac
doneSERVERnbr
if [[ -z $VERSION ]]; thenSERVER_JAR$SERVER.jar
elseSERVER_JAR$SERVER-$VERSION.jar
fiSPACEstudy2024
SERV_NAMEgeneral-test
PROFILEtestwhich java
JAVA$JAVA_HOME/bin/java
echo $JAVABASE_DIRcd $(dirname $0)/..; pwd
CUSTOM_SEARCH_LOCATIONSfile:${BASE_DIR}/config/#
# JVM Configuration
#
#JAVA_OPT${JAVA_OPT} -Xms512m -Xmx512m -Xss128k -XX:MaxGCPauseMillis300 -Xlog:gc:../logs/gc.log
JAVA_OPT${JAVA_OPT} ${JAVA_OPT_EXT}
JAVA_OPT${JAVA_OPT} -jar ${BASE_DIR}/${SERVER_JAR}
JAVA_OPT${JAVA_OPT} -D loader.path./lib
JAVA_OPT${JAVA_OPT} --spring.profiles.active${PROFILE}
JAVA_OPT${JAVA_OPT} --server.port${PORT}
JAVA_OPT${JAVA_OPT} --spring.config.additional-location${CUSTOM_SEARCH_LOCATIONS}
JAVA_OPT${JAVA_OPT} --logging.config${BASE_DIR}/config/logback.xmlJAVA_MAJOR_VERSION$($JAVA -version 21 | sed -E -n s/.* version ([0-9]*).*$/\1/p)if [ ! -d ${BASE_DIR}/logs ]; thenmkdir ${BASE_DIR}/logs
fiecho $JAVA ${JAVA_OPT}# start
echo $JAVA ${JAVA_OPT} ${BASE_DIR}/logs/start.out 21
nohup $JAVA ${JAVA_OPT} ${SPACE}.${SERV_NAME}-${appName} ${BASE_DIR}/logs/start.out 21
echo ${SPACE}.${SERV_NAME}-${appName} is startingyou can check the ${BASE_DIR}/logs/start.out
echo $! pid.txt
4.2 关闭脚本shutdown.sh
#!/bin/bashSPACEstudy2024
SERV_NAMEgeneral-test
PROFILEtest#参数解析
appNameapp001
ARGSgetopt -o a: --long appName: -n $0 -- $
if [ $? ! 0 ]; thenecho Terminating...exit 1
fi
#echo ARGS[$ARGS]
eval set -- ${ARGS}
#echo formatted parameters[$]while true
docase $1 in-a|--appName)case $2 in)appNamemainshift 1;;;*)appName$2shift 2;;;esac;;--) shift ; break ;;*) echo Internal error! ; exit 1 ;;esac
done#cd dirname $0/..
target_dirpwdpid$(cat $target_dir/pid.txt)if [[ -z $pid ]]; thenpidps ax | grep -i $SPACE.$SERV_NAME-${appName} | grep ${target_dir} | grep java | grep -v grep | awk {print $1}
fiif [ -z $pid ] ; thenecho No $SPACE.$SERV_NAME-${appName} running.exit 0;
firm pid.txtecho The ${SPACE}.${SERV_NAME}-${appName}(${pid}) is running...
kill ${pid}
echo Send shutdown request to ${SPACE}.${SERV_NAME}-${appName}(${pid}) OK4.3 启动关闭实验
把该脚本拖到linux如图所示 cd进bin中把这俩脚本赋予可执行权限
cd bin
chmod x startup.sh
chmod x shutdown.sh启动命令
./startup -p 8083查看是否启动成功
lsof -i:8083可见程序启动成功了。 关闭程序
./shutdown.sh再次查看是否进程还在
lsof -i:8083观察到已经没有。
五、代码展示
不多讲还是移步我的码云吧