SpringBoot Linux服务化部署

除了使用java -jar运行SpringBoot应用程序之外,还可以为Unix系统创建可执行的应用程序。可执行的jar可以其他 Unix 系统程序一样运行,也可以注册到init.d或systemd。这使我们可以很方便的在生成应用环境中安装和管理SpringBoot应用程序。

提示

可执行的jar是通过 jar 文件前面嵌入额外的脚本来工作。目前,一些工具不接受这种格式,所以这种技术还不是完全稳定的。例如,jar -xf可能无法提取可执行的jar或war。如果你不能确保此方式可行,建议还是使用java -jar运行它或将其部署到servlet容器中。

使用Maven创建一个“可执行”的jar,插件配置:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
    </configuration>
</plugin>

在Gradle中

bootJar {
    launchScript()
}

配置之后,就可以输入./my-application.jar(my-application是打包的 jar 文件名称)来运行SpringBoot程序了。jar所在目录为应用程序的work目录,相当于 classPath路径。

支持操作系统

默认脚本支持大多数Linux发行版,并在CentOS和Ubuntu上进行了测试。其他平台,如OS X和FreeBSD,需要使用定制的embeddedLaunchScript。

Unix / Linux服务

通过使用init.d或systemd,可以轻松地将Spring引导应用程序启动为Unix/Linux服务。

安装为init.d服务

如果配置了Spring Boot的Maven或Gradle插件来生成一个可执行的jar,并且不使用自定义embeddedLaunchScript,那么可用将应用程序配置为init.d服务。就可以支持标准的start、stop、restart和status命令。

该脚本支持以下功能:

  • 作为拥有jar文件的用户启动服务
  • 使用/var/run/<appname>/<appname>.pid跟踪应用程序的PID
  • 将控制台日志写入/var/log/<appname>.log

假设你的SpringBoot程序部署在/var/myapp路径,要将SpringBoot程序作为init.d服务,需要创建一个软链接,如下:

$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp

安装后,就可以按系统服务的方式启动和停止。例如,在基于debian的系统上,可以使用以下命令启动它:

$ service myapp start

如果应用程序启动失败,可以在/var/log/<appname>.log日志文件中查找错误。

将程序标记为自动启动。例如,在Debian上,可以使用以下命令:

$ update-rc.d myapp defaults <priority>

init.d服务安全

下面是一组关于如何保护以init.d形式运行的SpringBoot应用程序的指导原则。注意,这里只是列出部分为增强应用程序及其运行环境的安全性而应该做的事情。

当以 root 身份执行应用程序,应用程序的拥有者就是 root。而我们不应该使用 root 用户作为程序的拥有者,而是要创建一个特定的用户,并使用chown使其成为jar文件的所有者,如下面的示例所示:

$ chown bootapp:bootapp your-app.jar

在这种情况下,程序将使用bootapp用户运行。

为了减少应用程序的用户帐户被破坏的可能性,应该考虑阻止它使用shell登录。例如,可以将帐户的shell设置为/usr/sbin/nologin。

防止应用程序jar文件被篡改

首先,配置其权限,使其不能被写入,只能被其所有者读取或执行,如下例所示:

$ chmod 500 your-app.jar

其次,如果应用程序或运行它的帐户受到损害,应该采取措施来限制损害。如果攻击者确实获得了访问权,他们可以篡改jar文件。防止这种情况发生的一种方法是使用chattr使其不可变,如下面的示例所示:

$ sudo chattr +i your-app.jar

这将阻止任何用户(包括root)修改jar。

如果root用于控制应用程序的服务,而程序是使用.conf文件自定义启动配置,则root需要可以将读取.conf文件。使用chmod使文件只能被所有者读取,使用chown使root成为所有者,如下例所示:

$ chmod 400 your-app.conf
$ sudo chown root:root your-app.conf

安装为systemd服务

systemd是System V init.d系统的继承者,现在许多现代Linux发行版都在使用它。尽管你可以继续使用init.d。通过systemd脚本,也可以使用systemd ' service '脚本启动SpringBoot应用程序。

假设在/var/myapp中部署了一个SpringBoot应用程序,要将SpringBoot应用程序安装为systemd服务,请创建一个名为myapp.service脚本,并将其放在/etc/systemd/system目录中。下面的脚本提供了一个例子:

[Unit]
Description=myapp
After=syslog.target

[Service]
User=myapp
ExecStart=/var/myapp/myapp.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

注意:请记住对应更改应用程序的描述、用户和ExecStart字段为你运行的环境值

ExecStart字段不声明脚本操作命令,这意味着默认情况下使用run命令。

注意,这与作为init.d运行时不同。init.d服务运行应用程序的用户、PID文件和控制台日志文件由systemd本身管理,因此必须通过在“service”脚本中使用适当的字段进行配置。有关详细信息,请参阅服务单元配置手册页。

标记自动启动,请使用以下命令:

$ systemctl enable myapp.service

自定义启动脚本

Maven或Gradle插件编写的默认嵌入式启动脚本可以通过多种方式定制。对于大多数人来说,使用默认脚本和一些定制通常就足够了。如果您发现无法定制需要的内容,可以使用embeddedLaunchScript选项完全编写自己的文件。

在编写开始脚本时自定义它

在将开始脚本的元素写入jar文件时,对其进行自定义通常是有意义的。例如,init.d脚本可以提供“描述”。因为您已经预先知道了描述(并且它不需要更改),所以最好在生成jar时提供它。

要自定义编写的元素,请使用Spring Boot Maven插件的embeddedLaunchScriptProperties选项或Spring Boot Gradle插件的launchScript的properties属性。

默认脚本支持以下属性替换:

属性名 说明 Gradle 默认值 Maven 默认值
mode The script mode. auto auto
initInfoProvides The Provides section of “INIT INFO” ${task.baseName} ${project.artifactId}
initInfoRequiredStart Required-Start section of “INIT INFO”. remote_fssyslog $network remote_fssyslog $network
initInfoRequiredStop Required-Stop section of “INIT INFO”. remote_fssyslog $network remote_fssyslog $network
initInfoDefaultStart Default-Start section of “INIT INFO”. 2 3 4 5 2 3 4 5
initInfoDefaultStop Default-Stop section of “INIT INFO”. 0 1 6 0 1 6
initInfoShortDescription Short-Description section of “INIT INFO”. Single-line version of {project.description} (falling back to{task.baseName}) ${project.name}
initInfoDescription Description section of “INIT INFO”. {project.description} (falling back to{task.baseName}) {project.description} (falling back to{project.name})
initInfoChkconfig chkconfig section of “INIT INFO” 2345 99 01 2345 99 01
confFolder The default value for CONF_FOLDER Folder containing the jar Folder containing the jar
inlinedConfScript Reference to a file script that should be inlined in the default launch script. This can be used to set environmental variables such as JAVA_OPTS before any external config files are loaded
logFolder Default value for LOG_FOLDER. Only valid for an init.d service
logFilename Default value for LOG_FILENAME. Only valid for an init.d service
pidFolder Default value for PID_FOLDER. Only valid for an init.d service
pidFilename Default value for the name of the PID file in PID_FOLDER. Only valid for an init.d service
useStartStopDaemon Whether the start-stop-daemon command, when it’s available, should be used to control the process true true
stopWaitTime Default value for STOP_WAIT_TIME in seconds. Only valid for an init.d service 60 60

在脚本运行时自定义脚本

对于在编写jar之后需要定制的脚本项,可以使用环境变量或配置文件。

默认脚本支持以下环境属性:

变量名 说明
MODE The “mode” of operation. The default depends on the way the jar was built but is usually auto (meaning it tries to guess if it is an init script by checking if it is a symlink in a directory called init.d). You can explicitly set it to service so that the stop start status restart commands work or to run if you want to run the script in the foreground.
USE_START_STOP_DAEMON Whether the start-stop-daemon command, when it’s available, should be used to control the process. Defaults to true.
PID_FOLDER The root name of the pid folder (/var/run by default).
LOG_FOLDER The name of the folder in which to put log files (/var/log by default).
CONF_FOLDER The name of the folder from which to read .conf files (same folder as jar-file by default).
LOG_FILENAME The name of the log file in the LOG_FOLDER (<appname>.log by default).
APP_NAME The name of the app. If the jar is run from a symlink, the script guesses the app name. If it is not a symlink or you want to explicitly set the app name, this can be useful.
RUN_ARGS The arguments to pass to the program (the Spring Boot app).
JAVA_HOME The location of the java executable is discovered by using the PATH by default, but you can set it explicitly if there is an executable file at $JAVA_HOME/bin/java.
JAVA_OPTS Options that are passed to the JVM when it is launched.
JARFILE The explicit location of the jar file, in case the script is being used to launch a jar that it is not actually embedded.
DEBUG If not empty, sets the -x flag on the shell process, making it easy to see the logic in the script.
STOP_WAIT_TIME The time in seconds to wait when stopping the application before forcing a shutdown (60 by default).

PID_FOLDER、LOG_FOLDER和LOG_FILENAME变量仅对init.d 方式有效。对于systemd,通过使用“service”脚本进行相同的定制。

除了JARFILE和APP_NAME之外,可以使用.conf文件配置上一节中列出的设置。这个文件应该和 jar 文件在同级目录中,并且名字和 jar 文件名字一致。但是后缀是.conf而不是.jar。例如,名为/var/myapp/myapp.jar使用名为/var/myapp/myapp的配置文件。conf,如下例所示:

myapp.conf

JAVA_OPTS=-Xmx1024M
LOG_FOLDER=/custom/log/folder

如果不喜欢将配置文件放在jar文件旁边,可以设置CONF_FOLDER环境变量来定制配置文件的位置。

本文翻译原地址:https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 最近在研究Docker的源码.读到ApiServer的启动过程时,发现其有一个新的概念,叫做service act...
    AlstonWilliams阅读 1,103评论 1 4
  • 一、Python简介和环境搭建以及pip的安装 4课时实验课主要内容 【Python简介】: Python 是一个...
    _小老虎_阅读 5,688评论 0 10
  • 当我们使用Spring Boot完成应用开发时,我们可以在命令行使用java -jar .jar来启动我们的应用...
    倔强的小亮阅读 1,193评论 0 1
  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,792评论 0 5
  • 近看了7-11创始人铃木敏文在零售流通行业里面浸渍了近50年的心得体会,确实颇具想法,从一手创办7-11开始,到不...
    ROYO阅读 239评论 0 0