【框架】Spring Boot: 实现优雅退出

3 篇文章 0 订阅
3 篇文章 0 订阅

2018.11.18

前言

要求某个基于Spring Boot的调度器,能实现优雅退出,使得退出时正在运行时的作业能进行必要的回滚操作。为此,翻译某技术博客的总结1

方法

每个Spring应用都会在JVM里注册一个shutdown hook1,以保证ApplicationContext能实现优雅退出。以下的方法都是基于这一原理进行实现的。

方法一:Actuator的Endpoint机制1

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

默认配置下,shutdown端点是关闭的,需要在application.properties里配置:

management.endpoint.shutdown.enabled=true

Actuator的端点,支持通过JMX或HTTP进行远程访问。而shutdown默认配置下是不支持HTTP进行Web访问的,所以使用HTTP请求进行关闭,还需要配置:

management.endpoints.web.exposure.include=shutdown

最后,配合使用对应的URL就能让Spring Boot应用优雅退出:

curl -X POST localhost:port/actuator/shutdown

方法二:使用ApplicationContext#close()方法

ApplicationContext#close()亦能实现优雅退出,但要使得当前application context退出,就需要一个入口,从外部接收到退出的信号。一种方法就是上述的Endpoint端点,另一种方法适用于Spring MVC的Web应用,就是定制一个Controller实现ApplicationContextAware接口如下:

@RestController
public class ShutdownController implements ApplicationContextAware {
    private ApplicationContext context;
    
    @PostMapping("/shutdownContext")
    public void shutdownContext() {
        ((ConfigurableApplicationContext) context).close();
    }
    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        this.context = ctx;    
    }
}

同样地,配合使用对应的URL就能让Spring Boot应用优雅退出:

curl -X POST localhost:port/shutdownContext

方法三:@PreDestroy + kill <pid>

如果项目不是Spring MVC,又不想引入Actuator,可以直接采用ctrl + c或kill <pid>的方式。因为Spring应用在JVM里注册了一个shutdown hook,所以只要能接收到退出的信号(ctrl + c或kill <pid>,而kill -9 <pid>不行),那么应用就能正常地优雅退出。如果项目是通过nohup java -jar project.jar &方式启动的,那么就建议使用kill <pid>命令,给应用发送一个TERM信号,就能正常优雅退出。@PreDestroy注解允许方法完成必要的退出工作。

获取pid的方式可使用如下两种:

  1. Bash shell
ps -ef | grep project.jar | awk '{print $2}'
  1. Java代码
SpringApplicationBuilder app = new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE);
app.build().addListeners(new ApplicationPidFileWriter("./bin/shutdown.pid"));
app.run();

  1. Baeldung about Spring Boot shutdown ↩︎ ↩︎ ↩︎

  2. Actuator Endpoints
    Actuator提供了Endpoint端点,可能用于对Spring Boot应用进行监控和交互。其中有一个shutdown端点,就是用于优雅退出的。使用Actuator的端点,首先需要配置Actuator相关依赖2↩︎

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
spring boot中文文档,从安装到部署。 I. Spring Boot文件 1.关于文档 2.获得帮助 3.第一步 4.使用Spring Boot 5.了解Spring Boot功能 6.转向生产 7.高级主题 II。入门 8.介绍Spring Boot 9.系统要求 9.1.Servlet容器 10.安装Spring Boot 10.1.Java Developer的安装说明 10.1.1.Maven安装 10.1.2.Gradle安装 10.2.安装Spring Boot CLI 10.2.1.手动安装 10.2.2.使用SDKMAN安装! 10.2.3.OSX Homebrew安装 10.2.4.MacPorts安装 10.2.5.命令行完成 10.2.6.Windows Scoop安装 10.2.7.快速启动Spring CLI示例 10.3.从早期版本的Spring Boot升级 11.开发您的第一个Spring Boot应用程序 11.1.创建POM 11.2.添加Classpath依赖项 11.3.编写代码 11.3.1.@RestController和@RequestMapping Annotations 11.3.2.@EnableAutoConfiguration注释 11.3.3.“主要”方法 11.4.运行示例 11.5.创建一个可执行的Jar 12.接下来要阅读的内容 III。使用Spring Boot 13.构建系统 13.1.依赖管理 13.2.Maven 13.2.1.继承Starter Parent 13.2.2.在没有父POM的情况下使用Spring Boot 13.2.3.使用Spring Boot Maven插件 13.3.Gradle 13.4.Ant 13.5.Starters 14.构建您的代码 14.1.使用“默认”包 14.2.找到主应用程序类 15.配置类 15.1.导入其他配置类 15.2.导入XML配置 16.自动配置 16.1.逐步更换自动配置 16.2.禁用特定的自动配置类 17. Spring Beans和依赖注入 18.使用@SpringBootApplication Annotation 19.运行您的应用程序 19.1.从IDE运行 19.2.作为打包应用程序运行 19.3.使用Maven插件 19.4.使用Gradle插件 19.5.热插拔 20.开发人员工具 20.1.Property默认值 20.2.自动重启 20.2.1.记录条件评估中的更改 20.2.2.不包括资源 20.2.3.观看其他路径 20.2.4.禁用重启 20.2.5.使用触发器文件 20.2.6.自定义重新启动类加载器 20.2.7.已知限制 20.3.LiveReload 20.4.全局设置 20.5.远程应用 20.5.1.运行远程客户端应用程序 20.5.2.远程更新 21.包装您的生产
登录功能是Web应用程序中最基本的功能之一,Spring Boot 和 SSM框架可以很好地支持登录功能的实现。以下是一个简单的示例: 1. 首先,创建一个数据库表格来存储用户信息,包括用户名和密码。 ```sql CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(20) NOT NULL, `password` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; ``` 2. 在Spring Boot项目中,创建一个控制器类来处理登录请求和响应。 ```java @RestController public class LoginController { @Autowired private UserService userService; @PostMapping("/login") public String login(@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session) { User user = userService.getUser(username, password); if (user != null) { session.setAttribute("user", user); return "success"; } else { return "fail"; } } @GetMapping("/logout") public String logout(HttpSession session) { session.invalidate(); return "success"; } } ``` 3. 创建一个服务类来处理数据库操作。 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User getUser(String username, String password) { User user = userMapper.getUser(username, password); return user; } } ``` 4. 创建一个数据访问层接口和实现类来处理数据库操作。 ```java public interface UserMapper { User getUser(@Param("username") String username, @Param("password") String password); } @Mapper @Repository public interface UserMapper { User getUser(@Param("username") String username, @Param("password") String password); } ``` 5. 最后,在Spring Boot的application.properties文件中配置数据库连接信息。 ```properties spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 通过以上步骤,我们就可以实现一个基本的登录功能。当用户输入用户名和密码时,我们将在数据库中查找该用户信息。如果用户名和密码匹配,则将该用户信息存储在Session中,并返回“success”给客户端。如果没有匹配,则返回“fail”。在用户退出登录时,我们将清除Session中的用户信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值