Spring Boot 2系列(六十一):作为Linux服务运行Java程序
除了使用 java -jar 运行 Spring Boot 应用程序之外,还可以为 Unix 系统制作完全可执行的应用程序。
完全可执行的 jar 可以像任何其他可执行二进制文件一样执行,也可以使用 init.d
或 systemd
注册。
这有助于在常见的生产环境中安装和管理 Spring Boot 应用程序。
以下操作在 Ubuntu 16.04.4版本上操作
创建可执行应用
Maven 管理的项目,在pom.xml
文件中的spring-boot-maven-plugin插件下添加开启可执行文件的配置。
打包成可执行文件
1
2
3
4
5
6
7<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>通过
rz
或sftp
将jar
包上传到 Linux 服务器。修改包的
jar
包的权限1
2这个`jar`就变成了 Linux 环境下的一个可执行文件了。
chmod 777 myapp.jar以可执行文件的方式运行 jar包
1
./myapp.jar
init.d 方式
创建软链接
1
ln -s /usr/local/java-app/myapp.jar /etc/init.d/myapp
官文档指示操作:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#deployment-install
给服务授权为可执行
1
/etc/init.d# chmod +x myapp
查看服务可用命令
1
2/etc/init.d# ./myapp
Usage: ./myapp {start|stop|force-stop|restart|force-reload|status|run}可执行命令
1
2
3
4
5
6
7/etc/init.d# ./myapp start
/etc/init.d# ./myapp stop
/etc/init.d# ./myapp force-stop
/etc/init.d# ./myapp restart
/etc/init.d# ./myapp force-reload
/etc/init.d# ./myapp status
/etc/init.d# ./myapp run以上操作还不算是将
jar
注册为服务来启动.
服务启动命令应该是:service service_name [start|stop|reload|status],或者是:systemctl [tart|stop|reload|status] service_name.service
以service方式运行
1
2service myapp start
提示:Failed to start myapp.service: Unit myapp.service not found.将服务注册为系统默认服务
1
2
3
4update-rc.d myapp defaults
再次启动服务
service myapp start
提示:Job for myapp.service failed because the control process exited with error code. See "systemctl status myapp.service" and "journalctl -xe" for details.根据提示查找问题
1
2
3systemctl status myapp.service
提示:Loaded: loaded (/etc/init.d/myqpp; bad; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2018-06-13 18:21:42 CST; 51s ago继续查找
1
2journalctl -xe
提示:Unable to find Java提示是找不到 java,提示内容是服务文件输出的,服务文件中使用的是
$JAVA_HOME
来查找 java。实际已经配置了 Java 环境,在**/etc/profile** 文件配置了 export JAVA_HOME=/usr/local/java/jdk1.8.0_172 ,问题出在服务文件中的$JAVA_HOME
定位不到jdk目录,把文件中的**$JAVA_HOME**用绝对路径显式指定,如下:1
2
3
4
5
6
7
8
9
10# Find Java
if [[ -n "/usr/local/java/jdk1.8.0_172" ]] && [[ -x "/usr/local/java/jdk1.8.0_172/bin/java" ]]; then
javaexe="/usr/local/java/jdk1.8.0_172/bin/java"
elif type -p java > /dev/null 2>&1; then
javaexe=$(type -p java)
elif [[ -x "/usr/bin/java" ]]; then
javaexe="/usr/bin/java"
else
echo "Unable to find Java"
exit 1以服务方式启动
1
2
3service myapp start //启动成功
service myapp status //状态:活动
systemctl status myapp.service //状态:活动目前来看以服务方式启动是成功了,现在访问下服务
访问服务:
http://ip:port/mapping_path
//无响应,访问失败。
使用ps -ef|grep java
没有看到Java进程,不知具体原因,问题仍未解决。CentOS 7环境验证
在 CentOS 7 环境下,截止到第 5 步的操作可正常部署运行可访问,这也是 Spring Boot 官方文档支持的方式。在 Ubuntu 16.04.4版本上就比较诡异了,其它版本是否有差异会造成异常还不确定。
官方文档:https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/
systemd方式
Spring Boot 项目 jar 包是安装在** /var/myapp** 目录下(安装目录根据自己需要而选择)
在 /etc/systemd/system 目录下创建
myapp.service
脚本文件1
2
31.
/etc/systemd/system# touch myqpp.service编辑脚本文件内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13[Unit]
Description=myapp
After=syslog.target
[Service]
#如果没有添加指定用户权限,注释User限制
#User=myapp
#jar文件绝对路径
ExecStart=/var/myapp/myapp.jar
SuccessExitStatus=143
[Install]
WantedBy=multi-user.targetExecStart=/var/myapp/myapp.jar
此设置可能会提示:Unable to find Java; 也是找不到java
执行命令;
改为java
命令的绝对路径:ExecStart=/usr/local/java/jdk1.8.0_172/bin/java -jar /var/myapp/myapp.jar
启用服务
1
systemctl enable myapp.service
查看服务状态
1
2绿色 `active(running)`表示启动成功,活动的状态。
systemctl status myapp.service浏览器访问服务地址
返回成功表示此方式部署的服务成功。systemctl常用命令
1
2
3
4systemctl start myapp.service //启动
systemctl restart myapp.service //重启
systemctl status myapp.service //查看状态
systemctl stop myapp.service //停止
问题:init.d
和systemd
两种方式部署的应用,启动时如何指定配置文件是个问题(像java命令指定配置文件,如:java -jar xxx.jar - -spring.profiles.active=prod),现还没找到方法。
Spring Boot 2系列(六十一):作为Linux服务运行Java程序
http://blog.gxitsky.com/2022/07/18/SpringBoot-61-run-as-linux-service/