正确、安全地停止SpringBoot应用服务

引言

Spring Boot,作为Spring框架对“约定优先于配置(Convention Over Configuration)”理念的最佳实践的产物,它能帮助我们很快捷的创建出独立运行、产品级别的基于Spring框架的应用,大部分Spring Boot应用只需要非常少的配置就可以快速运行起来,是一个与微服务(MicroServices)相当契合的微框架。
网络上关于Spring Boot的QuickStart式中文内容已经相当丰富,但是对于部署后怎样便捷、安全地停止服务(shutdown),还比较缺乏,最近发现Spring Boot的官方指南更新了相关内容,因此结合该部分更新,对如何基于官方提供的特性正确地停止Spring Boot应用进行简单说明。

主要有两种方式:通过HTTP发送shutdown信号,或者通过service stop的方式

方式一:通过HTTP发送shutdown信号

该方式主要依赖Spring Boot Actuatorendpoint特性,具体步骤如下:

1. 在pom.xml中引入actuator依赖

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2. 开启shutdown endpoint

Spring Boot Actuatorshutdown endpoint默认是关闭的,因此在application.properties中开启shutdown endpoint

#启用shutdown
endpoints.shutdown.enabled=true
#禁用密码验证
endpoints.shutdown.sensitive=false

3. 发送shutdown信号

shutdown的默认urlhost:port/shutdown,当需要停止服务时,向服务器post该请求即可,如:
curl -X POST host:port/shutdown
将得到形如{"message":"Shutting down, bye..."}的响应

4. 安全设置

可以看出,使用该方法可以非常方便的进行远程操作,但是需要注意的是,正式使用时,必须对该请求进行必要的安全设置,比如借助spring-boot-starter-security进行身份认证:

  1. pom.xml添加security依赖

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
  2. 开启安全验证
    application.properties中变更配置,并
    #开启shutdown的安全验证
    endpoints.shutdown.sensitive=true
    #验证用户名
    security.user.name=admin
    #验证密码
    security.user.password=secret
    #角色
    management.security.role=SUPERUSER
  3. 指定路径、IP、端口
    #指定shutdown endpoint的路径
    endpoints.shutdown.path=/custompath
    #也可以统一指定所有endpoints的路径`management.context-path=/manage`
    #指定管理端口和IP
    management.port=8081
    management.address=127.0.0.1

方式二:部署为Unix/Linux Service

该方式主要借助官方的spring-boot-maven-plugin创建"Fully executable" jar ,这中jar包内置一个shell脚本,可以方便的将该应用设置为Unix/Linux的系统服务(init.d service),官方对该功能在CentOS和Ubuntu进行了测试,对于OS X和FreeBSD,可能需要自定义。具体步骤如下:

1. 在pom.xml中引入插件:

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

2. 设置为系统服务

将你的应用打成jar包,部署到服务器,假设部署路径为/var/app,包名为app.jar,通过如下方式将应该设置为一个系统服务:
sudo ln -s /var/app/app.jar /etc/init.d/app

3. 赋予可执行权限:

chmod u+x app.jar

4. 以系统服务的方式管理

接下来,就可以使用我们熟悉的service foo start|stop|restart来对应用进行启停等管理了
sudo service app start|stop
命令将得到形如Started|Stopped [PID]的结果反馈

默认PID文件路径:/var/run/appname/appname.pid
默认日志文件路径:/var/log/appname.log

这可能是我们更熟悉也更常用的管理方式。

自定义参数

在这种方式下,我们还可以使用自定义的.conf文件来变更默认配置,方法如下:

  1. 在jar包相同路径下创建一个.conf文件,名称应该与.jar的名称相同,如appname.conf
  2. 在其中配置相关变量,如:
    JAVA_HOME=/usr/local/jdk
    JAVA_OPTS=-Xmx1024M
    LOG_FOLDER=/custom/log

安全设置

作为应用服务,安全性是一个不能忽略的问题,如下一些操作可以作为部分基础设置参考:

  • 为服务创建一个独立的用户,同时最好将该用户的shell绑定为/usr/sbin/nologin
  • 赋予最小范围权限:chmod 500 app.jar
  • 阻止修改:sudo chattr +i app.jar
  • 对.conf文件做类似的工作:chmod 400 app.conf,sudo chown root:root app.conf

References:

    1. Installing Spring Boot applications
    2. Endpoints
    3. Securing sensitive endpoints

http://www.cnblogs.com/lobo/p/5657684.html

时间: 2024-08-05 14:27:53

正确、安全地停止SpringBoot应用服务的相关文章

正确的停止java中的线程

stop()方法不是一个正确的停止线程方法. 正确的停止方法:设置退出旗标

浅析Java线程的正确停止

线程错误终止之destroy与stop方法 记得以前初学Java的时候,由于缺少对锁.同步.异步等这些线程的知识,想当然的以为destroy与stop方法都能正确的停止Java线程的执行.但是,后来随着工作的积累,以及对线程安全的一些理解,慢慢认识到这两个方法是有问题的,并且这两方法也早已在java doc上被指名是弃用的. destroy()这个方法其实根本没干什么事情,只是抛出了一个NoSuchMethodError,所以说该方法无法终止线程,因此不能望文生意: /** * Throws {

Springboot 优雅停止服务的几种方法

在使用Springboot的时候,都要涉及到服务的停止和启动,当我们停止服务的时候,很多时候大家都是kill -9 直接把程序进程杀掉,这样程序不会执行优雅的关闭.而且一些没有执行完的程序就会直接退出. 我们很多时候都需要安全的将服务停止,也就是把没有处理完的工作继续处理完成.比如停止一些依赖的服务,输出一些日志,发一些信号给其他的应用系统,这个在保证系统的高可用是非常有必要的.那么咱么就来看一下几种停止springboot的方法. 第一种就是Springboot提供的actuator的功能,它

「SpringBoot」如何优雅地管理SpringBoot项目

本文主要讲述一下如何优雅地管理SpringBoot项目. 背景 课堂上,当小明形如流水地回答完沐芳老师提出来的问题时,却被至今没有对象的胖虎无情嘲讽了? 沐芳老师:小明,你平时是如何启动.停止你的SpringBoot项目的? 小明(自信满满):启动时使用java -jar xxxx.jar命令启动,停止服务时,使用ps -ef找到服务的pid,然后再kill掉停止. 胖虎:就这? 这让小明很有挫败感,原计划按时放学回去陪隔壁小花打王者荣耀的小明,毅然决然留在教室潜心研究一番到底什么是Spring

停止Java线程,小心interrupt()方法

程序是很简易的.然而,在编程人员面前,多线程呈现出了一组新的难题,如果没有被恰当的解决,将导致意外的行为以及细微的.难以发现的错误. 在本篇文章中,我们针对这些难题之一:如何中断一个正在运行的线程. 背景     中断(Interrupt)一个线程意味着在该线程完成任务之前停止其正在进行的一切,有效地中止其当前的操作.线程是死亡.还是等待新的任务或是继续运行至下一步,就取决于这个程序.虽然初次看来它可能显得简单,但是,你必须进行一些预警以实现期望的结果.你最好还是牢记以下的几点告诫. 首先,忘掉

Hadoop伪分布式重启正确流程

既然是伪分布式,那就不可避免的设计到重启Hadoop服务或者重启Hadoop服务器的情况,正确的停止和重启是很有必要的. 首先是Hadoop服务的停止,使用 ./sbin/stop-all.sh脚本来停止所有的Hadoop服务,这个脚本包含了两个脚本的内容,一个是./sbin/stop-dfs.sh,另一个是./sbin/stop-yarn.sh,具体的细节请直接查看脚本内容 重启是件比较麻烦的事情,像这种开源软件,一般都把主要的精力放在了功能的实现上,使用非常不便. 服务器重启后,直接使用./

springboot文件上传报错

异常信息: org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request;nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.1978174608501890996.8083/work/Tomcat/localhost/pmap] is not vali

SpringBoot+Mysql 无法保存emoj表情?

尤记得很久以前,想存 emoj 表情到 mysql 中,需要额外的将 emoj 表情转码之后保存,每次读取时,再解码还原成一下:每次这种 sb 的操作,真心感觉心塞,那么有没有办法直接存呢? mysql 本身可以通过选择编码集(如 utfbmb4)来支持 emoj 表情,然而今天遇到了一个相当鬼畜的问题,表中可以直接写入 emoj 表情,但是通过 spring boot 代码塞入的 emoj 时,却抛出异常: Caused by: java.sql.SQLException: Incorrect

GC 算法(实现篇) - GC参考手册

您应该已经阅读了前面的章节: 垃圾收集简介 - GC参考手册 Java中的垃圾收集 - GC参考手册 GC 算法(基础篇) - GC参考手册 学习了GC算法的相关概念之后, 我们将介绍在JVM中这些算法的具体实现.首先要记住的是, 大多数JVM都需要使用两种不同的GC算法 -- 一种用来清理年轻代, 另一种用来清理老年代. 我们可以选择JVM内置的各种算法.如果不通过参数明确指定垃圾收集算法, 则会使用宿主平台的默认实现.本章会详细介绍各种算法的实现原理. 下面是关于Java 8中各种组合的垃圾