-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Blog: Improve performance of your spring boot application with Virtua…
…l Threads
- Loading branch information
1 parent
47df5da
commit df292be
Showing
3 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
109 changes: 109 additions & 0 deletions
109
...log/improve-performance-of-your-spring-boot-application-with-virtual-threads.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
--- | ||
title: "Improving Performance of Your Spring Boot Application With Virtual Threads" | ||
date: 2024-02-12T15:14:28+05:30 | ||
draft: false | ||
tags: ["virtual-threads", "spring-boot", "throughput", "performance"] | ||
--- | ||
|
||
|
||
Do you know you can significantly improve the performance of your Spring Boot application in less than just two minutes? Yes, you heard it right! You can simply improve performance of your application by adding two configurations in your app. These configuration will enforce the use of **Virtual Threads** (in contrast to the default **Platform Threads**) on your Spring Boot application running on Tomcat Server. These changes will significantly improve the **throughput** of your Spring Boot application (and yes, I am not kidding!). | ||
|
||
If you have already enabled Virtual Threads in your application, and you know what it does behind the scenes, feel free to skip this article. However, if you curious about changes that can increase the throughput of your application, learn about Virtual Threads, and understand what's going on under the hood of these changes, you are at the right place. | ||
|
||
Okay, let's just cut to the chase and talk about the changes that can improve the throughput of your Spring Boot application. It's nothing but enabling the use of Virtual threads in Spring boot application. | ||
|
||
# Using Virtual Threads in a Spring Boot application | ||
|
||
If you are using Spring Boot version 3.2 or above and Java version 21+, you can simply add these two configuration in your app to enforce the use **Virtual Threads** | ||
|
||
```java | ||
@Bean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME) | ||
public AsyncTaskExecutor asyncTaskExecutor() { | ||
return new TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor()); | ||
} | ||
|
||
@Bean | ||
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() { | ||
return protocolHandler -> { | ||
protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor()); | ||
}; | ||
} | ||
``` | ||
|
||
If you just wanted to improve throughput of your application and don't want to deep dive into the theory, you are all good till here and can skip the rest of the article. | ||
|
||
If case you are still here, let's just buckle up and deep dive into some theory... | ||
|
||
# What are Virtual Threads? | ||
|
||
Before we deep dive into Virtual Threads it is important to understand what a platform thread is. | ||
|
||
## Platform Threads | ||
|
||
A Platform Thread is a thread that runs Java code on its underlying operating system (OS) thread. It is implemented as a thin wrapper around an OS thread and captures its OS thread for the platform thread's entire lifetime. Platform threads are suitable for running all types of tasks but are a limited resource due to the large runtime stack size. The diagram below shows 1-to-1 mapping of Platform threads with the OS Threads | ||
|
||
```mermaid | ||
--- | ||
config: | ||
sankey: | ||
showValues: false | ||
--- | ||
sankey-beta | ||
Platform-Thread-1,OS-Thread-1,1 | ||
Platform-Thread-2,OS-Thread-2,1 | ||
Platform-Thread-3,OS-Thread-3,1 | ||
Platform-Thread-4,OS-Thread-4,1 | ||
Platform-Thread-5,OS-Thread-5,1 | ||
Platform-Thread-6,OS-Thread-6,1 | ||
Platform-Thread-7,OS-Thread-7,1 | ||
Platform-Thread-8,OS-Thread-8,1 | ||
``` | ||
## Virtual Threads | ||
|
||
Virtual Threads, on the other hand, are user made threads scheduled by the Java Virtual Machine (JVM) rather than the underlying OS. Virtual threads introduce an abstraction layer between operating-system processes and application-level concurrency, allowing the JVM to mediate between the operating system and the program. This allows the JVM to manage more threads than the ones available on the underlying OS. | ||
|
||
Virtual Threads are suitable for executing tasks that spend most of the time blocked, often waiting for the I/O operation to complete. Virtual Threads are not intended for long running CPU intensive operation. | ||
|
||
The diagram below shows how virtual threads are mapped to OS threads via JVM orchestration. | ||
|
||
```mermaid | ||
--- | ||
config: | ||
sankey: | ||
showValues: false | ||
--- | ||
sankey-beta | ||
Virtual-Thread-1,JVM-Orchestration,1 | ||
Virtual-Thread-2,JVM-Orchestration,1 | ||
Virtual-Thread-3,JVM-Orchestration,1 | ||
Virtual-Thread-4,JVM-Orchestration,1 | ||
Virtual-Thread-5,JVM-Orchestration,1 | ||
Virtual-Thread-6,JVM-Orchestration,1 | ||
Virtual-Thread-7,JVM-Orchestration,1 | ||
Virtual-Thread-8,JVM-Orchestration,1 | ||
JVM-Orchestration,OS-Thread-1,1 | ||
JVM-Orchestration,OS-Thread-2,1 | ||
JVM-Orchestration,OS-Thread-3,1 | ||
JVM-Orchestration,OS-Thread-4,1 | ||
JVM-Orchestration,OS-Thread-5,1 | ||
JVM-Orchestration,OS-Thread-6,1 | ||
JVM-Orchestration,OS-Thread-7,1 | ||
JVM-Orchestration,OS-Thread-8,1 | ||
``` | ||
|
||
## Benefit of using Virtual Threads | ||
|
||
The main advantage of using Virtual Thread is that your application would now be able to **use greater number of threads** than they were able to use before. This is because the Java Virtual Machine (JVM) would assume responsibility of coordinating requests to and from the Operating System, managing them efficiently. As a result, numerous Virtual threads can bypass the waiting period associated with I/O operations and the Operating System, making them accessible to the next task. | ||
|
||
# So why is our application faster now? | ||
|
||
The configuration we added earlier, simply update the executors of Tomcat to use **Virtual Threads** rather than the default Platform Threads. By default, Tomcat associates one HTTP request with one Platform thread. However, with the Virtual Threads configuration, Tomcat can efficiently manage multiple concurrent requests per underlying Thread within each worker pool, enabling more effective handling of background tasks. | ||
|
||
# References | ||
|
||
1. [Embracing Virtual Threads](https://spring.io/blog/2022/10/11/embracing-virtual-threads) | ||
2. [Platform Threads and Virtual Threads](https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<pre class="mermaid"> | ||
{{- .Inner | safeHTML }} | ||
</pre> | ||
{{ .Page.Store.Set "hasMermaid" true }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
{{- define "main" }} | ||
|
||
<article class="post-single"> | ||
<header class="post-header"> | ||
{{ partial "breadcrumbs.html" . }} | ||
<h1 class="post-title entry-hint-parent"> | ||
{{ .Title }} | ||
{{- if .Draft }} | ||
<span class="entry-hint" title="Draft"> | ||
<svg xmlns="http://www.w3.org/2000/svg" height="35" viewBox="0 -960 960 960" fill="currentColor"> | ||
<path | ||
d="M160-410v-60h300v60H160Zm0-165v-60h470v60H160Zm0-165v-60h470v60H160Zm360 580v-123l221-220q9-9 20-13t22-4q12 0 23 4.5t20 13.5l37 37q9 9 13 20t4 22q0 11-4.5 22.5T862.09-380L643-160H520Zm300-263-37-37 37 37ZM580-220h38l121-122-18-19-19-18-122 121v38Zm141-141-19-18 37 37-18-19Z" /> | ||
</svg> | ||
</span> | ||
{{- end }} | ||
</h1> | ||
{{- if .Description }} | ||
<div class="post-description"> | ||
{{ .Description }} | ||
</div> | ||
{{- end }} | ||
{{- if not (.Param "hideMeta") }} | ||
<div class="post-meta"> | ||
{{- partial "post_meta.html" . -}} | ||
{{- partial "translation_list.html" . -}} | ||
{{- partial "edit_post.html" . -}} | ||
{{- partial "post_canonical.html" . -}} | ||
</div> | ||
{{- end }} | ||
</header> | ||
{{- $isHidden := (.Param "cover.hiddenInSingle") | default (.Param "cover.hidden") | default false }} | ||
{{- partial "cover.html" (dict "cxt" . "IsSingle" true "isHidden" $isHidden) }} | ||
{{- if (.Param "ShowToc") }} | ||
{{- partial "toc.html" . }} | ||
{{- end }} | ||
|
||
{{- if .Content }} | ||
<div class="post-content"> | ||
{{- if not (.Param "disableAnchoredHeadings") }} | ||
{{- partial "anchored_headings.html" .Content -}} | ||
{{- else }}{{ .Content }}{{ end }} | ||
</div> | ||
{{- end }} | ||
{{ if .Page.Store.Get "hasMermaid" }} | ||
<script type="module"> | ||
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs'; | ||
const config = { | ||
startOnLoad: true, | ||
securityLevel: 'loose', | ||
sankey: { | ||
width: 800, | ||
height: 400, | ||
linkColor: 'gradient', | ||
nodeAlignment: 'center', | ||
}, | ||
}; | ||
mermaid.initialize(config); | ||
</script> | ||
{{ end }} | ||
|
||
|
||
<footer class="post-footer"> | ||
{{- $tags := .Language.Params.Taxonomies.tag | default "tags" }} | ||
<ul class="post-tags"> | ||
{{- range ($.GetTerms $tags) }} | ||
<li><a href="{{ .Permalink }}">{{ .LinkTitle }}</a></li> | ||
{{- end }} | ||
</ul> | ||
{{- if (.Param "ShowPostNavLinks") }} | ||
{{- partial "post_nav_links.html" . }} | ||
{{- end }} | ||
{{- if (and site.Params.ShowShareButtons (ne .Params.disableShare true)) }} | ||
{{- partial "share_icons.html" . -}} | ||
{{- end }} | ||
</footer> | ||
|
||
{{- if (.Param "comments") }} | ||
{{- partial "comments.html" . }} | ||
{{- end }} | ||
</article> | ||
|
||
{{- end }}{{/* end main */}} |