Java Advent Calendar 2019 This is the article on the 24th day.
I'm free even before Christmas: rage: I compared the simple startup speed of Spring Boot, which is a framework based on the JVM language, and Micronaut.
Spring is a framework that everyone in the know knows, so I will omit the introduction
--A framework for microservices developed by OCI --JVM-based --1.0GA released in October 2018
Official site https://micronaut.io/
--Java / Groovy / Kotlin can be used as a program language --Compile Time DI & AOP is adopted --GraalVM and Native Image can also be used --CLI is provided --Fast startup --Small memory footprint
MacBook Pro
SpringBoot v2.2.2.RELEASE
Micronaut 1.2.7
--Implement one simple REST API --Package in jar and start (java -jar xxx.jar) --Start 10 times in each execution environment and take the average value --Spring Boot measures boot speed with both Tomcat and Jetty
SpringBoot
python
@RestController
public class HelloController {
@RequestMapping(value="/hello", method=RequestMethod.GET)
public String hello() {
return "Hello Spring";
}
}
Start tomcat
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.2.RELEASE)
2019-12-23 14:29:46.247 INFO 73041 --- [ main] com.example.sphelloapp.DemoApplication : Starting DemoApplication
2019-12-23 14:29:46.250 INFO 73041 --- [ main] com.example.sphelloapp.DemoApplication : No active profile set, falling back to default profiles: default
2019-12-23 14:29:46.925 INFO 73041 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-12-23 14:29:46.935 INFO 73041 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-12-23 14:29:46.935 INFO 73041 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.29]
2019-12-23 14:29:46.984 INFO 73041 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-12-23 14:29:46.984 INFO 73041 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 695 ms
2019-12-23 14:29:47.105 INFO 73041 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-12-23 14:29:47.214 INFO 73041 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-12-23 14:29:47.216 INFO 73041 --- [ main] com.example.sphelloapp.DemoApplication : Started DemoApplication in 1.233 seconds (JVM running for 1.556)
Jetty launch
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.2.RELEASE)
2019-12-23 14:22:39.036 INFO 72942 --- [ main] c.e.sphelloappjetty.DemoApplication : Starting DemoApplication
2019-12-23 14:22:39.038 INFO 72942 --- [ main] c.e.sphelloappjetty.DemoApplication : No active profile set, falling back to default profiles: default
2019-12-23 14:22:39.651 INFO 72942 --- [ main] org.eclipse.jetty.util.log : Logging initialized @1229ms to org.eclipse.jetty.util.log.Slf4jLog
2019-12-23 14:22:39.713 INFO 72942 --- [ main] o.s.b.w.e.j.JettyServletWebServerFactory : Server initialized with port: 8080
2019-12-23 14:22:39.716 INFO 72942 --- [ main] org.eclipse.jetty.server.Server : jetty-9.4.24.v20191120; built: 2019-11-20T21:37:49.771Z; git: 363d5f2df3a8a28de40604320230664b9c793c16; jvm 1.8.0_232-20191009173705.graal.jdk8u-src-tar-gz-b07
2019-12-23 14:22:39.738 INFO 72942 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring embedded WebApplicationContext
2019-12-23 14:22:39.739 INFO 72942 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 664 ms
2019-12-23 14:22:39.815 INFO 72942 --- [ main] org.eclipse.jetty.server.session : DefaultSessionIdManager workerName=node0
2019-12-23 14:22:39.815 INFO 72942 --- [ main] org.eclipse.jetty.server.session : No SessionScavenger set, using defaults
2019-12-23 14:22:39.816 INFO 72942 --- [ main] org.eclipse.jetty.server.session : node0 Scavenging every 660000ms
2019-12-23 14:22:39.821 INFO 72942 --- [ main] o.e.jetty.server.handler.ContextHandler : Started o.s.b.w.e.j.JettyEmbeddedWebAppContext@45f45fa1{application,/,[file:///private/var/folders/xk/q20_p4gd2xz1sfmtmngwjg380000gp/T/jetty-docbase.146795275059491819.8080/],AVAILABLE}
2019-12-23 14:22:39.822 INFO 72942 --- [ main] org.eclipse.jetty.server.Server : Started @1400ms
2019-12-23 14:22:39.922 INFO 72942 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-12-23 14:22:40.036 INFO 72942 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-12-23 14:22:40.036 INFO 72942 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-12-23 14:22:40.040 INFO 72942 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
2019-12-23 14:22:40.060 INFO 72942 --- [ main] o.e.jetty.server.AbstractConnector : Started ServerConnector@37574691{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2019-12-23 14:22:40.062 INFO 72942 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port(s) 8080 (http/1.1) with context path '/'
2019-12-23 14:22:40.064 INFO 72942 --- [ main] c.e.sphelloappjetty.DemoApplication : Started DemoApplication in 1.299 seconds (JVM running for 1.643)
(reference) Setting for jetty startup (gradle)
build.gradle
dependencies {
compile('org.springframework.boot:spring-boot-starter-web') {
exclude module: 'spring-boot-starter-tomcat'
}
compile('org.springframework.boot:spring-boot-starter-jetty')
}
Spring does not officially support Native Image yet (scheduled to support 2Q 2020) The experimental version is on github, so verify it with this (Tomcat only, no Jetty) https://github.com/spring-projects-experimental/spring-graal-native
procedure
./build-feature.sh
spring-graal-native-samples / springmvc-tomcat
./compile.sh
(1-2 minutes)
target
folder and make sure springmvc-tomcat
is generated./springmvc-tomcat
This completes the preparation on the spring side
Micronaut
HelloController.java
@Controller
public class HelloController{
@Get(value="/hello", produces = MediaType.TEXT_PLAIN)
public String index(){
return "Hello Micronaut";
}
}
Start-up
14:37:49.383 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 985ms. Server Running: http://localhost:8080
Micronaut supports Native Image as standard, but you can enjoy it by creating a project dedicated to Native Image.
$mn create-app hello-graal --features graal-native-image
HelloController.java
./gradlew build
$ native-image --no-server -cp build / libs / hello-graal-0.1-all.jar
(1 to 2 minutes)./hello-graal
This completes the preparation on the Micronaut side
--There is almost no difference in JDK (11, 8, GraalVM JIT). ――There is a difference of about 300ms between frameworks, but it depends on individual thoughts and cases whether this is regarded as large or small. In the case of the author, the difference is not particularly noticeable. --GraalVM AOT (Native Image) is overwhelmingly fast. --The question remains if it is said that there is a benefit to using Native Image even if the advantage of running on the JVM is abandoned. (I think it's okay because the JVM also starts in about 1 second) ――However, this time it was a super simple app, so if you have an app with a lot of class loads, you may feel the benefits of AOT even more in terms of startup time.
Since this time we are verifying with a simple app, the result may be different with an actual complex app, so we hope you can see it as a reference only. If I get the chance, I'll try to verify frameworks such as helidon and Quarkus.
Recommended Posts