All Projects → gesellix → Graceful Shutdown Spring Boot

gesellix / Graceful Shutdown Spring Boot

Graceful Shutdown with Spring Boot (Demo)

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to Graceful Shutdown Spring Boot

Cookbook
🎉🎉🎉JAVA高级架构师技术栈==任何技能通过 “刻意练习” 都可以达到融会贯通的境界,就像烹饪一样,这里有一份JAVA开发技术手册,只需要增加自己练习的次数。🏃🏃🏃
Stars: ✭ 428 (+739.22%)
Mutual labels:  spring-boot, jvm, tomcat
Joinfaces
JoinFaces: JSF Spring Boot Starters - JSF inside Spring Boot Application
Stars: ✭ 295 (+478.43%)
Mutual labels:  spring-boot, tomcat
deploy-docker-swarm-using-terraform-ansible
No description or website provided.
Stars: ✭ 20 (-60.78%)
Mutual labels:  deployment, docker-swarm
Jruby Rack
Rack for JRuby and Java appservers
Stars: ✭ 393 (+670.59%)
Mutual labels:  deployment, tomcat
Quickperf
QuickPerf is a testing library for Java to quickly evaluate and improve some performance-related properties
Stars: ✭ 231 (+352.94%)
Mutual labels:  spring-boot, jvm
Java-CS-Record
记录准备春招实习过程中,学习与复习的知识(模块化整理,非面试题速成)。注:暂停更新,后续请移步博客
Stars: ✭ 73 (+43.14%)
Mutual labels:  jvm, tomcat
Trampoline
Admin Spring Boot Locally
Stars: ✭ 325 (+537.25%)
Mutual labels:  spring-boot, deployment
Whatsmars
Java生态研究(Spring Boot + Redis + Dubbo + RocketMQ + Elasticsearch)🔥🔥🔥🔥🔥
Stars: ✭ 1,389 (+2623.53%)
Mutual labels:  spring-boot, tomcat
Gradle Tomcat Plugin
Gradle plugin supporting deployment of your web application to an embedded Tomcat web container
Stars: ✭ 516 (+911.76%)
Mutual labels:  deployment, tomcat
Graphql Java Tools
A schema-first tool for graphql-java inspired by graphql-tools for JS
Stars: ✭ 667 (+1207.84%)
Mutual labels:  spring-boot, jvm
Subnode.org
SubNode: Social Media App
Stars: ✭ 25 (-50.98%)
Mutual labels:  spring-boot, tomcat
Spring Microservice Sample
Spring Boot based Mircoservice sample
Stars: ✭ 199 (+290.2%)
Mutual labels:  spring-boot, docker-swarm
Study
全栈工程师学习笔记;Spring登录、shiro登录、CAS单点登录和Spring boot oauth2单点登录;Spring data cache 缓存,支持Redis和EHcahce; web安全,常见web安全漏洞以及解决思路;常规组件,比如redis、mq等;quartz定时任务,支持持久化数据库,动态维护启动暂停关闭;docker基本用法,常用image镜像使用,Docker-MySQL、docker-Postgres、Docker-nginx、Docker-nexus、Docker-Redis、Docker-RabbitMQ、Docker-zookeeper、Docker-es、Docker-zipkin、Docker-ELK等;mybatis实践、spring实践、spring boot实践等常用集成;基于redis的分布式锁;基于shared-jdbc的分库分表,支持原生jdbc和Spring Boot Mybatis
Stars: ✭ 159 (+211.76%)
Mutual labels:  spring-boot, tomcat
SwarmManagement
Swarm Management is a python application, installed with pip. The application makes it easy to manage a Docker Swarm by configuring a single *.yml file describing which stacks to deploy, and which networks, configs or secrets to create.
Stars: ✭ 25 (-50.98%)
Mutual labels:  deployment, docker-swarm
Nimrod
Nimrod - 基于 Spring Boot 构建 的 Java Web 平台企业级单体应用快速开发框架,适合中小型项目的应用和开发。所采用的技术栈包括 Spring Boot、Spring、Spring Web MVC、MyBatis、Thymeleaf 等,遵守阿里巴巴 Java 开发规约,帮助养成良好的编码习惯。整体采用 RBAC ( Role-Based Access Control ,基于角色的访问控制),具有严格的权限控制模块,支持系统与模块分离开发。最后希望这个项目能够对你有所帮助。Nimrod 开发交流群:547252502(QQ 群)
Stars: ✭ 125 (+145.1%)
Mutual labels:  spring-boot, tomcat
Micro Company
Rest-full, Hipermedia-based distributed application. Spring boot & cloud. Angular. CQRS. Eventsourcing. Axonframework. Microservices. Docker. CloudFoundry
Stars: ✭ 307 (+501.96%)
Mutual labels:  spring-boot, docker-swarm
Fxshop
基于SpringBoot+SpringCloud微服务的商城项目(demo版 不可用于生产)
Stars: ✭ 82 (+60.78%)
Mutual labels:  spring-boot, tomcat
Jplusone
Tool for automatic detection and asserting "N+1 SELECT problem" occurences in JPA based Spring Boot Java applications and finding origin of JPA issued SQL statements in general
Stars: ✭ 91 (+78.43%)
Mutual labels:  spring-boot, jvm
Caprover
Scalable PaaS (automated Docker+nginx) - aka Heroku on Steroids
Stars: ✭ 7,964 (+15515.69%)
Mutual labels:  deployment, docker-swarm
Javaok
必看!java后端,亮剑诛仙。java发展路线技术要点。
Stars: ✭ 867 (+1600%)
Mutual labels:  spring-boot, jvm

This concept has been made available in Spring Boot 2.3.+

See https://github.com/spring-projects/spring-boot/releases/tag/v2.3.0.RELEASE and https://github.com/spring-projects/spring-boot/issues/21325 for details.


Graceful Shutdown with Spring Boot

In a modern world, we expect webapps to always be available. Yet, deployments trigger downtimes, which is why we're talking about zero downtime.

Yeah, it's easy to put a proxy in front of your services and let it balance across multiple instances of your service. Now you can take them down one at a time, and deploy your fancy new version.

But how would you handle long running requests which are directly connected to a specific instance?

This project is a showcase for an example of how to gracefully shut down a Spring Boot app. The code is more or less a plain copy from https://github.com/spring-projects/spring-boot/issues/4657#issuecomment-161354811 with the only difference that I wanted to use Kotlin instead of standard Java.

I also wrote a more detailed article about our motivation for this example demo app at my blog.

Usage

Basics

Clone (or download) this repository:

git clone https://github.com/gesellix/graceful-shutdown-spring-boot
cd graceful-shutdown-spring-boot

You'll need a Java Runtime Environment (JRE) to run the example without Docker.

Without Docker (really?)

  • run the app, e.g. via ./gradlew bootRun
  • perform a looooong download: curl -X GET "http://localhost:8080/endless" > /dev/null
  • send SIGTERM to the Spring process (you can find the <pid> in the application logs): kill <pid>

Docker Stack/Service

Some background information

Using Docker Stack or Docker Services, you'll need to be aware of the underlying mechanics of a rolling update. You can find a detailed discussion about that topic at github.com/moby/moby/issues/30321.

In a Spring Boot world, you'll need to tweak the following settings:

  • Your Spring Boot webapp needs to register a shutdown hook to pause/prevent the JVM shutdown. The example application shows how an implementation looks like in an Apache Tomcat environment. You can tweak the shutdown timeout with the example application property catalina.threadpool.execution.timeout.seconds.
  • During a service update Docker will send the TERM signal to your container and wait for 10 seconds until Docker sends the KILL signal to finally stop your container. If you want your downloads to keep running longer than 10 seconds, you'll need to configure the stop-grace-period to match your needs. Since the Spring Boot app defaults to wait 30s, I chose 60 seconds as services.app.stop_grace_period in the stack.yml.
  • Your replicated service tasks shouldn't be shutdown simultaneously. That's why the stack.yml configures the services.app.deploy.update_config.parallelism to be sequentially. Additionally, I configured the services.app.deploy.update_config.delay to be 60s.

Perform a zero downtime deployment

Now the exciting part: you may want to update your app to use a fresh image or add some environment parameter. Such updates would trigger a short downtime of your running containers, which effectively would stop your running download. Depending on your needs, that's what you actually want. But maybe you would like to give running downloads a chance to finish. The grace period needs to be configurable, because only you know how long a typical download should be kept running in your individual service.

Deploy a minimal stack with reverse proxy and two instances of the example app:

docker swarm init # you may add more worker nodes, but that's not necessary for the demo.
docker stack deploy -c stack.yml grace

We can now start the demo scenario by first starting a download and then trying to update the app service. Open your browser at http://localhost and click go for it, or use your shell to perform an endless download: curl -X GET "http://localhost/endless" > /dev/null.

You can watch your service logs with docker service logs -f grace_app. The browser will also show you the increasing number of downloaded bytes.

An update with task downtime can easily be triggered:

docker service update --env-add "foo=bar" --detach=false grace_app

Now keep your eye on the browser download "stats" and the service logs where you can see the Docker service update shutting down your tasks one by one. We also use the detach option --detach=false to watch the service update states in real-time from the cli. One of your tasks will be shut down instantly, because it won't be "locked" by your download. But the other task shutdown should be prevented to approximately 30 seconds. Only then the Spring Boot shutdown will continue and Docker won't enforce the shutdown through SIGKILL.

Long story short: you should catch the TERM signal to prevent an instant process shutdown, Docker needs to wait long enough before actually killing your process, and you should configure the parallelism with a value smaller than your number of replicas.

How does it work?

The GracefulShutdown class listens to application events of type ContextClosedEvent. It waits 30 seconds (or whatever you configured) for the Tomcat ThreadPoolExecutor to be shut down. Essentially, it blocks the JVM shutdown to wait for the Tomcat to be finished with pending requests.

Please note that you won't get any guarantees that the JVM will wait endlessly for your shutdown hook to return. It might interrupt your shutdown hook without further notice. My JVM implementation on macOS and the one in an alpine container seem to be patient enough :)

Bonus

Please note that there are two additional Spring Boot info contributors, whose results will be visible at /info:

  • Docker Info contributor: provides the output of the docker info. Expects the Docker engine to be available at /var/run/docker.sock.
  • Docker Secrets contributor: dumps the configured secrets and their contents. See the official docs for details. A default example secret is already configured for your convenience.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].