最近需要部署一个代码生成程序,而这个程序是用spring boot 写的。那么spring boot 的部署就是一个必修课了。 参考了这篇博客 Spring Boot 部署与服务配置
ubuntu中部署
在ubuntu中部署的话 可以在.bashrc添加 alias
alias start_weixin_service='nohup ./weixin-service-1.0.0-SNAPSHOT.jar > weixin-service.log 2>&1 &'
export SPRING_PROFILES_ACTIVE=development
命令行部署
java -jar demo.jar --spring.config.location=/opt/config/application.properties
写脚本部署
start.sh
#!/bin/sh
rm -f tpid
nohup java -jar myapp.jar --spring.config.location=application.yml --spring. profiles.active=production > /dev/null 2>&1 &
echo $! > tpid
echo Start Success!
stop.sh
#!/bin/sh
APP_NAME=myapp
tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
if [ ${tpid} ]; then
echo 'Stop Process...'
kill -15 $tpid
fi
sleep 5
tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
if [ ${tpid} ]; then
echo 'Kill Process!'
kill -9 $tpid
else
echo 'Stop Success!'
fi
#另一种写法是
#!/bin/sh
APP_PORT=20085
kill -9 `lsof -t -i:$APP_PORT`
check.sh
#!/bin/sh
APP_NAME=myapp
tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
if [ ${tpid} ]; then
echo 'App is running.'
else
echo 'App is NOT running.'
fi
kill.sh
#!/bin/sh
APP_NAME=myapp
tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
if [ ${tpid} ]; then
echo 'Kill Process!'
kill -9 $tpid
fi
不过这些文件用vm创建出来后并不能直接运行,因为没有运行的权限
chmod -755 start.sh
####直接用命令来部署
以下两种方法选一种就ok了
#指定激活的profile(推荐)--对于的文件为同目录下的application-development.yml
nohup java -jar myapp.jar --spring.profiles.active=development > weixin-service.log 2>&1 &
#指定对于的配置文件(不推荐)
nohup java -jar myapp.jar --spring.config.location=application.yml > weixin-service.log 2>&1 &
关闭
netstat -nltp
kill -9 pid
有时,需要部署的时候配置jvm参数 因为我用的是jdk8的版本,配置上和jdk8以前的版本会有一些差别。看来要好好学习关于jvm,还有监控jvm的学习上了,不然基于jvm的程序如何调优都不知道,只会一脸懵逼。
jdk内存实际是jvm内存,jvm有一个运行时数据区,其实就是对这一部分的大小分配。
运行时数据区通常包括这几个部分:程序计数器(Program Counter Register)、Java栈(VM Stack)、本地方法栈(Native Method Stack)、方法区(Method Area)、堆(Heap)
Xss:每个线程的stack大小(栈) Xmx:JAVA HEAP的最大值、默认为物理内存的1/4 Xms:JAVA HEAP的初始值,server端最好Xms与Xmx一样 Xmn:JAVA HEAP young区的大小 XX:PermSize:设定内存的永久保存区域 XX:MaxPermSize:设定最大内存的永久保存区域
在JDK1.8中,取消了PermGen,取而代之的是Metaspace,所以PermSize和MaxPermSize参数失效,取而代之的是
-XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m
修改JDK内存
linux下:在tomcat的bin目录下编辑catalina.sh
cygwin=false上面加入
JAVA_OPTS="-Xms1024m -Xmx2048m -Xss1024K -XX:MetaspaceSize=512m
-XX:MaxMetaspaceSize1024m"
这是我本地测试的一个实际例子
java -jar -Xms1024m -Xmx2048m -Xss1024K -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m -javaagent:/Library/oneApm/OneAPM/oneapm.jar smk-exec.jar
jvm配置常见的组合有
-Xmx128m -Xms64m -Xmn32m -Xss16m
也可以参考这篇文章。JVM参数,启动jar 包以及 启动tomcat的 JVM参数设置 一行命令获取当前JVM所有可设置的参数以及当前默认值
今天用war打包启动的时候会遇到一些问题,
可以参考这篇文章 简述Java命令行参数、JVM、打包Java程序、JAR文件
把原来的项目用spring boot整合的时候,会出现cpu占用率甚至会高到100%以上很高的情况,这点不是很理想,以至于我都不用部署到服务器。即使我调高了jvm配置,还是会有这样的情况。 部署的时候发现发现下面这样的警告。
Unable to add the resource at [/WEB-INF/lib/displaytag-1.2.jar] to the cache because there was insufficient free space available after evicting expired cache entries - consider increasing the maximum size of the cache
但是我用了 参看文章 How does Spring Boot control Tomcat cache?
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory();
tomcatFactory.addContextCustomizers((context) -> {
StandardRoot standardRoot = new StandardRoot(context);
standardRoot.setCacheMaxSize(40 * 1024);
});
return tomcatFactory;
}
然而这样的警告还是存在。 后来我用jar包的方式打包,发现比较神奇的是,这个错误不存在了,可能用jar包的方式不会出现这样的问题吧。还有就是cpu的占用率终于下降了。 不过我还不是很确定cpu占用率下降是因为具体哪一个原因。 是换了ThymeLeaf模板,还是修改了jvm参数,还是用jar打包配置上面的配置(猜想是这个原因)。
Spring Boot & Spring Cloud应用内存管理
设置为系统服务
参考了这篇文章
该方式主要借助官方的spring-boot-maven-plugin创建"Fully executable" jar ,这中jar包内置一个shell脚本,可以方便的将该应用设置为Unix/Linux的系统服务(init.d service),官方对该功能在CentOS和Ubuntu进行了测试,对于OS X和FreeBSD,可能需要自定义。具体步骤如下:
- 在pom.xml中引入插件:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
- 设置为系统服务 将你的应用打成jar包,部署到服务器,假设部署路径为/var/app,包名为app.jar,通过如下方式将应该设置为一个系统服务:
sudo ln -s /var/app/app.jar /etc/init.d/app
- 赋予可执行权限:
chmod u+x app.jar
- 以系统服务的方式管理
接下来,就可以使用我们熟悉的service foo start|stop|restart来对应用进行启停等管理了
sudo service app start|stop
命令将得到形如Started|Stopped [PID]的结果反馈
默认PID文件路径:/var/run/appname/appname.pid
默认日志文件路径:/var/log/appname.log
这可能是我们更熟悉也更常用的管理方式。
还有就是需要让这个系统服务可以自动启动起来
自定义参数
在这种方式下,我们还可以使用自定义的.conf文件来变更默认配置,方法如下:
在jar包相同路径下创建一个.conf文件,名称应该与.jar的名称相同,如appname.conf 在其中配置相关变量,如:
JAVA_HOME=/usr/local/jdk
JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log
LINUX环境下
与Spring Boot项目同路径下新建一同名配置文件。
例如:当前项目为demo.jar,那么新建一文件demo.conf,内容如下:
JAVA_OPTS="-Xms1024M -Xmx2048M" //jvm运行参数
RUN_ARGS="--server.port=8081 --logging.level=INFO --spring.thymeleaf.cache=true --logging.file=/var/log/demo.log" //项目运行参数
Linux环境下Spring Boot项目内置Tomcat参数配置
与Spring Boot项目同路径下新建一同名配置文件
项目为boot.jar,新建文件boot.conf,项目启动之后默认读取该配置文件
1、jvm运行参数
JAVA_OPTS="-Xms2048m -Xmx2048m -Xss512k"
-Xms:初始Heap大小,使用的最小内存,cpu性能高时此值应设的大一些
-Xmx:Java heap最大值,使用的最大内存
上面两个值是分配JVM的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半。
-XX:PermSize:设定内存的永久保存区域
-XX:MaxPermSize:设定最大内存的永久保存区域
-XX:MaxNewSize:
-Xss 15120 这使得JBoss每增加一个线程(thread)就会立即消耗15M内存,而最佳值应该是128K,默认值好像是512k.
+XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。
-Xss:每个线程的Stack大小
-verbose:gc 现实垃圾收集信息
-Xloggc:gc.log 指定垃圾收集日志文件
-Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一
-XX:+UseParNewGC :缩短minor收集的时间
-XX:+UseConcMarkSweepGC :缩短major收集的时间
提示:此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。
2、项目运行参数
RUN_ARGS="--server.port=8081 --logging.level=INFO --spring.thymeleaf.cache=true --logging.file=/var/log/demo.log"
####上面的脚本,需要部署两个一个start.sh 一个stop.sh 其实可以考虑把这两个合并起来。
#!/bin/bash
Tag="Application"
MainClass="com.test.Application"
Lib="/testboot/test/lib/"
Log="/testboot/test/run.log"
JVM="-server -Xms128m -Xmx128m -XX:PermSize=32M -XX:MaxNewSize=64m -XX:MaxPermSize=64m -Djava.awt.headless=true -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled"
echo $Tag
RETVAL="0"
# See how we were called.
function start() {
echo $Log
if [ ! -f $Log ]; then
touch $Log
fi
nohup java $JVM -Dappliction=$Tag -Djava.ext.dirs=$Lib":${JAVA_HOME}/jre/lib/ext" $MainClass > $Log 2>&1 &
tailf $Log
}
function stop() {
pid=$(ps -ef | grep -v 'grep' | egrep $Tag| awk '{printf $2 " "}')
if [ "$pid" != "" ]; then
echo -n "boot ( pid $pid) is running"
echo
echo -n $"Shutting down boot: "
pid=$(ps -ef | grep -v 'grep' | egrep $Tag| awk '{printf $2 " "}')
if [ "$pid" != "" ]; then
echo "kill boot process"
kill -9 "$pid"
fi
else
echo "boot is stopped"
fi
status
}
function status()
{
pid=$(ps -ef | grep -v 'grep' | egrep $Tag| awk '{printf $2 " "}')
#echo "$pid"
if [ "$pid" != "" ]; then
echo "boot is running,pid is $pid"
else
echo "boot is stopped"
fi
}
function usage()
{
echo "Usage: $0 {start|stop|restart|status}"
RETVAL="2"
}
# See how we were called.
RETVAL="0"
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
reload)
RETVAL="3"
;;
status)
status
;;
*)
usage
;;
esac
exit $RETVAL
参考 shell 管理SpringBoot 生产环境服务 (配置JVM)
SpringBoot 启动参数设置环境变量、JVM参数、tomcat远程调试
本文详细介绍SpringBoot项目的多种部署方法,包括直接命令行部署、编写Shell脚本部署、使用spring-boot-maven-plugin创建可执行jar包并设置为系统服务。同时讨论了如何配置JVM参数以优化应用程序性能。


被折叠的 条评论
为什么被折叠?



