Skip to content

Commit 7e64ac3

Browse files
committed
added WebServer using Virtual Threads in Java 19
1 parent a3a1997 commit 7e64ac3

9 files changed

+214
-0
lines changed

java-19/WebServer-StressTest.jmx

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.3">
3+
<hashTree>
4+
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Java 19 - WebServer with Virtual Threads" enabled="true">
5+
<stringProp name="TestPlan.comments"></stringProp>
6+
<boolProp name="TestPlan.functional_mode">false</boolProp>
7+
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
8+
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
9+
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
10+
<collectionProp name="Arguments.arguments"/>
11+
</elementProp>
12+
<stringProp name="TestPlan.user_define_classpath"></stringProp>
13+
</TestPlan>
14+
<hashTree>
15+
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
16+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
17+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
18+
<boolProp name="LoopController.continue_forever">false</boolProp>
19+
<intProp name="LoopController.loops">-1</intProp>
20+
</elementProp>
21+
<stringProp name="ThreadGroup.num_threads">500</stringProp>
22+
<stringProp name="ThreadGroup.ramp_time">10</stringProp>
23+
<boolProp name="ThreadGroup.scheduler">true</boolProp>
24+
<stringProp name="ThreadGroup.duration">300</stringProp>
25+
<stringProp name="ThreadGroup.delay"></stringProp>
26+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
27+
</ThreadGroup>
28+
<hashTree>
29+
<ConfigTestElement guiclass="HttpDefaultsGui" testclass="ConfigTestElement" testname="HTTP Request Defaults" enabled="true">
30+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="Variables pr�-d�finies" enabled="true">
31+
<collectionProp name="Arguments.arguments"/>
32+
</elementProp>
33+
<stringProp name="HTTPSampler.domain">localhost</stringProp>
34+
<stringProp name="HTTPSampler.port">8000</stringProp>
35+
<stringProp name="HTTPSampler.protocol"></stringProp>
36+
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
37+
<stringProp name="HTTPSampler.path"></stringProp>
38+
<stringProp name="HTTPSampler.concurrentPool">6</stringProp>
39+
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
40+
<stringProp name="HTTPSampler.response_timeout"></stringProp>
41+
</ConfigTestElement>
42+
<hashTree/>
43+
<HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
44+
<collectionProp name="HeaderManager.headers">
45+
<elementProp name="" elementType="Header">
46+
<stringProp name="Header.name">Content-type</stringProp>
47+
<stringProp name="Header.value">application/json</stringProp>
48+
</elementProp>
49+
</collectionProp>
50+
</HeaderManager>
51+
<hashTree/>
52+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Get" enabled="true">
53+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
54+
<collectionProp name="Arguments.arguments"/>
55+
</elementProp>
56+
<stringProp name="HTTPSampler.domain"></stringProp>
57+
<stringProp name="HTTPSampler.port"></stringProp>
58+
<stringProp name="HTTPSampler.protocol"></stringProp>
59+
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
60+
<stringProp name="HTTPSampler.path">/</stringProp>
61+
<stringProp name="HTTPSampler.method">GET</stringProp>
62+
<boolProp name="HTTPSampler.follow_redirects">false</boolProp>
63+
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
64+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
65+
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
66+
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
67+
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
68+
<stringProp name="HTTPSampler.response_timeout"></stringProp>
69+
</HTTPSamplerProxy>
70+
<hashTree>
71+
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
72+
<collectionProp name="Asserion.test_strings">
73+
<stringProp name="66712709">Handled!</stringProp>
74+
</collectionProp>
75+
<stringProp name="Assertion.custom_message"></stringProp>
76+
<stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
77+
<boolProp name="Assertion.assume_success">false</boolProp>
78+
<intProp name="Assertion.test_type">1</intProp>
79+
</ResponseAssertion>
80+
<hashTree/>
81+
</hashTree>
82+
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
83+
<boolProp name="ResultCollector.error_logging">false</boolProp>
84+
<objProp>
85+
<name>saveConfig</name>
86+
<value class="SampleSaveConfiguration">
87+
<time>true</time>
88+
<latency>true</latency>
89+
<timestamp>true</timestamp>
90+
<success>true</success>
91+
<label>true</label>
92+
<code>true</code>
93+
<message>true</message>
94+
<threadName>true</threadName>
95+
<dataType>true</dataType>
96+
<encoding>false</encoding>
97+
<assertions>true</assertions>
98+
<subresults>true</subresults>
99+
<responseData>false</responseData>
100+
<samplerData>false</samplerData>
101+
<xml>false</xml>
102+
<fieldNames>true</fieldNames>
103+
<responseHeaders>false</responseHeaders>
104+
<requestHeaders>false</requestHeaders>
105+
<responseDataOnError>false</responseDataOnError>
106+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
107+
<assertionsResultsToSave>0</assertionsResultsToSave>
108+
<bytes>true</bytes>
109+
<sentBytes>true</sentBytes>
110+
<url>true</url>
111+
<threadCounts>true</threadCounts>
112+
<idleTime>true</idleTime>
113+
<connectTime>true</connectTime>
114+
</value>
115+
</objProp>
116+
<stringProp name="filename"></stringProp>
117+
</ResultCollector>
118+
<hashTree/>
119+
<ResultCollector guiclass="RespTimeGraphVisualizer" testclass="ResultCollector" testname="Response Time Graph" enabled="true">
120+
<boolProp name="ResultCollector.error_logging">false</boolProp>
121+
<objProp>
122+
<name>saveConfig</name>
123+
<value class="SampleSaveConfiguration">
124+
<time>true</time>
125+
<latency>true</latency>
126+
<timestamp>true</timestamp>
127+
<success>true</success>
128+
<label>true</label>
129+
<code>true</code>
130+
<message>true</message>
131+
<threadName>true</threadName>
132+
<dataType>true</dataType>
133+
<encoding>false</encoding>
134+
<assertions>true</assertions>
135+
<subresults>true</subresults>
136+
<responseData>false</responseData>
137+
<samplerData>false</samplerData>
138+
<xml>false</xml>
139+
<fieldNames>true</fieldNames>
140+
<responseHeaders>false</responseHeaders>
141+
<requestHeaders>false</requestHeaders>
142+
<responseDataOnError>false</responseDataOnError>
143+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
144+
<assertionsResultsToSave>0</assertionsResultsToSave>
145+
<bytes>true</bytes>
146+
<sentBytes>true</sentBytes>
147+
<url>true</url>
148+
<threadCounts>true</threadCounts>
149+
<idleTime>true</idleTime>
150+
<connectTime>true</connectTime>
151+
</value>
152+
</objProp>
153+
<stringProp name="filename"></stringProp>
154+
</ResultCollector>
155+
<hashTree/>
156+
</hashTree>
157+
</hashTree>
158+
</hashTree>
159+
</jmeterTestPlan>

java-19/WebServerThreads.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import com.sun.net.httpserver.*;
2+
import java.net.*;
3+
import java.io.*;
4+
import java.nio.file.*;
5+
import java.util.function.Predicate;
6+
import java.util.concurrent.Executors;
7+
8+
/**
9+
* Run: `java --enable-preview --source 19 WebServerThreads.java`
10+
*/
11+
public class WebServerThreads {
12+
public static void main(String[] args) throws IOException {
13+
var server = HttpServer.create(new InetSocketAddress(8000), 0);
14+
server.createContext("/", HttpHandlers.of(200, new Headers(), "Handled!"));
15+
16+
// server.setExecutor(Executors.newCachedThreadPool());
17+
server.setExecutor(Executors.newThreadPerTaskExecutor(Thread.ofVirtual().factory()));
18+
19+
server.start();
20+
System.out.println("Server started at " + server.getAddress());
21+
}
22+
}
Loading
Loading
Loading
Loading
Loading
Loading

java-19/platform-thread-vs-virtual-thread.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,36 @@ Time taken to run:
114114
| Monitor | Timeline |
115115
|---|---|
116116
| ![](img/virtual-thread-fibreq-monitor.png) | ![](img/virtual-thread-fibreq-timeline.png) |
117+
118+
## WebServer
119+
120+
The code in `WebServerThreads` shows how to use Virtual Thread to handle HTTP requests using `HttpServer` from Java 18.
121+
122+
The goal here is to show resources usage in VisualVM, the response was a simple text message.
123+
124+
The response time and throughput aren't much different here as the processing is a simple message write.
125+
We should see some difference if the processing was making some IO-bound work.
126+
127+
To run stress test: `jmeter -n -t WebServer-StressTest.jmx -l jmeter_requests_logs.csv -e -o jmeter-report/`
128+
129+
### Platform Thread
130+
131+
JMeter Summary
132+
133+
![](img/webserver-platform-thread-jmeter-summary.png)
134+
135+
| Response Time | Monitor |
136+
|---|---|
137+
| ![](img/webserver-platform-thread-response-time.png) | ![](img/webserver-platform-thread-monitor.png) |
138+
139+
### Virtual Thread
140+
141+
JMeter Summary
142+
143+
![](img/webserver-virtual-thread-jmeter-summary.png)
144+
145+
| Response Time | Monitor |
146+
|---|---|
147+
| ![](img/webserver-virtual-thread-response-time.png) | ![](img/webserver-virtual-thread-monitor.png) |
148+
149+

0 commit comments

Comments
 (0)