>我有一个打包成jar文件的springboot Web应用程序。产品服务器是安装了openjdk-8-jdk的Ubuntu 14.04.1。
我可以使用以下方法成功运行应用程序:
sudo java -jar /home/myUser/my_web_app.jar
然后,我通过以下命令将此应用程序作为 SystemV 服务进行:
sudo useradd webUser
sudo passwd webUser
sudo chown webUser:webUser /home/myUser/my_web_app.jar
sudo chmod 500 /home/myUser/my_web_app.jar
sudo ln -s /home/myUser/my_web_app.jar /etc/init.d/my_web_app
之后,当我运行时:
sudo service my_web_app start
错误引发为:
/etc/init.d/my_web_app: 1: /etc/init.d/my_web_app: Syntax error: ")" unexpected.
我想知道是什么原因导致此错误以及如何重新关注它。谢谢。
顺便说一句,同样的方法适用于我的开发机器(Ubuntu 14.04.6)。
问题是这两行:
sudo chmod 500 /home/myUser/my_web_app.jar
sudo ln -s /home/myUser/my_web_app.jar /etc/init.d/my_web_app
问题 #1:常规可执行 JAR 文件不是操作系统识别的可执行格式1。
在常规 JAR 文件上设置执行位将无济于事。 操作系统内核不知道如何运行它。 要运行常规 JAR,您必须执行命令java -jar /path/to/the.jar
。 如有必要,您可以创建一个简单的包装器脚本来执行此操作。
1 - 有一种方法可以生成一个特殊的"完全可执行"的 SpringBoot JAR 文件,该文件前面有一个 shell 脚本;请参阅"安装 Spring 引导应用程序"。 这是解决此问题的一种方法,尽管文档指出这些特殊的JAR文件会导致某些工具出现问题。
问题#2:/etc/init.d
中的文件应该是服务脚本。
它们不仅仅是服务的可执行文件。 这些脚本应该是理解动词的 shell 脚本,例如start
、stop
、restart
、reload
等。 并且(AFAIK)它们必须编码为兼容sh
shell脚本。 以下是一篇描述服务脚本结构的文章:
- https://www.linux.com/learn/managing-linux-daemons-init-scripts
(但请先阅读问题 #4!!
问题 #3:按root
运行服务可能存在安全风险。
最好创建一个(非特权)服务帐户来运行该服务。 如果服务向网络公开,这一点尤其重要。 (如果坏人可以通过网络"破解"服务并导致它做不想要的事情,那么它以root身份运行的事实会使整个系统处于危险之中。
问题 #4:/etc/init.d/
脚本已过时。
如果您使用的是最新的 Ubuntu 版本(15.04 或更高版本),则这些/etc/init.d/
脚本是"旧版"配置方式。initd
机制的当前迭代是systemd
。 它使用systemd
单元文件文件,而不是服务脚本。 以下文章提供了更多信息:
- https://www.linux.com/learn/managing-linux-daemons-init-scripts
systemd
服务包括旧版服务脚本,但它们没有那么强大、灵活和......简明。。。作为单元文件。
问题 #5:Ubuntu 14.04 LTS 已达到生命周期结束。
您应该升级到 16.04 LTS 或最好是 18.04 LTS。 对生产服务器使用生命周期结束的操作系统是不明智的。
请注意,网络上有很多文档和许多关于配置服务的新旧方法的文章。 (谷歌是你的朋友。
非常感谢@Stephne C的详细回答。经过一番搜索,我发现 Spring boot 为 Ubuntu 和 CentOS 提供了一个开箱即用的服务实践。
我犯的主要错误是没有将我的项目打包为可执行 jar。
要使 springboot jar 可执行,请编辑 POM 文件,将<executbale>
标签添加到 spring-boot-maven-plugin 的标签中<configuration>
作为打击:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
打包新的可执行 jar 并将其上传到服务器
将 jarchown
给 nologin 用户,该服务将由其所有者运行。
chmod 500
jar 以授予其可执行权限。
添加一个指向/etc/init.d 的软链接,以将其注册为服务。
运行该服务,到目前为止一切顺利。
但正如@Stephen C所说,默认选项既不够安全,也不是最新的。我认为最好只包装一个胖罐子并在生产环境中手动配置服务。