DZone
Cloud Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Cloud Zone > Microservice and Serverless With Micronaut + GraalVM

Microservice and Serverless With Micronaut + GraalVM

GraalVM and Micronauts - frenzy way to MicroServices, Serverless: Part2

Pratik Prakash user avatar by
Pratik Prakash
CORE ·
Sep. 24, 20 · Cloud Zone · Tutorial
Like (9)
Save
Tweet
6.95K Views

Join the DZone community and get the full member experience.

Join For Free

Micronaut® framework is creating a buzz around cloud-native (microservice, serverless ) application development due to its enriched features and optimizations based out of modern Polyglot JVM — GraalVM optimizers.

For GraalVM optimizers go thought Part1 of this series — GraalVM — Byte Code to Bit Code.

Why Micronaut® and what makes it the next level stuff as a framework for Cloud-Native development :

  • Natively Cloud Native 
    Micronaut®'s cloud support is built right in, including support for common discovery services, distributed tracing tools, cloud runtimes and leading vendors ( AWS, AZURE, GCP).
  • Ready for Serverless Development
    Micronaut® low overhead compile-time DI and AOP make it perfect for writing functions for serverless environments like AWS Lambda, Azure Functions etc.
  • Fast Start Time — Low Memory Consumption
    Reflection-based IoC framework load and cache reflection data for every single field, method, and constructor in your code. Whereas with Micronaut®, your application startup time and memory consumption are not bound to the size of your codebase. Micronaut® build around GraalVM. Micronaut features a dependency injection and aspect-oriented programming runtime that uses no reflection. This makes it easier for Micronaut applications to run on GraalVM.
    Micronaut apps start in a tenth of millisecond with GraalVM!
  • Built with Non-Blocking Http Server on Netty
    With a smooth learning curve, Micronaut’s HTTP server makes it as easy as possible to expose APIs that can be consumed by HTTP clients.
  • Design for Building Resilient Microservices
    Distributed environments require planning for failure. Micronaut’s built-in support for retry, circuit breaker, and fallbacks help you plan.
  • Faster Data Layer Configuration 
    Micronaut provides sensible defaults that automatically configure your favorite data access toolkit and APIs to make it easy to write your own integrations. Supports like Caching, SQL, NoSQL, and different DB vendor products are readily available.
  • Fast and Easy Testing
    Easily spin up servers and clients in your unit tests, and run them instantaneously with mostly auto-generated test stuff for main source code.
  • Reloading (or “hot-loading”)
    Out of box excellent support of hot reloading, restart, and reinitialization with build-in JVM agent support rather than relying on classloader reloading or proprietary JVM agents like JRebel etc. It is an important feature to make the development cycle efficient and fast.
  • Refreshable feature
    @Refreshable is another interesting scope offered by Micronaut. You can refresh the state of a bean by calling the HTTP endpoint /refresh or by publishing RefreshEvent to the application context.

How to Get Started Along Microservice With Micronaut

Create an app using the Micronaut Command Line Interface.

Installing Micronaut® manually comes with a super-rich & intuitive CLI that we will be using for the rest of the project lifecycle ( its power-pack CLI features add to developers productivity). We will be doing 3case studies with Micronaut® to compare and benchmark its potential relative to today’s Cloud-Native de-facto framework — SpringBoot.

Case A :  Micronaut ®  app on GraalVM optimised JIT
Case B :  Micronaut ®  app on GraalVM “Native-Image”
Case C : SpringBoot on openJDK HotSpotVM JIT — conventional way

Let’s get to the suspense straight-in with below depiction of different benchmarking results :
Benchmarking Micronaut


Micronaut application benchmarking

Step 1: Install Micronaut® nm and test its installation with below steps:

Shell
 




x


 
1
$ brew install micronaut   (using MacOS)
2
$ mn --version (testing installation success)



Step2: Simple command can create an app framework with all features generally required for microservice along with Dockerization.# creating an application with name demo-mn-jit

Shell
 




xxxxxxxxxx
1
10


 
1
# creating application with name demo-mn-jit
2
$ mn create-app demo-mn-jit  --build=maven --lang=kotlin -t=junit
3
-l, --lang e.g. -l kotlin
4
-t, --test e.g. -t junit
5
-b, --build. e.g. -b gradle
6
-f, --features e.g. -f annotation-api, app-name, docker, file-watch, netty-server, readme, yaml
7
# creating aws lambda serverless function named demo-lambda
8
$ mn create-function-app demo-lambda --lang=kotlin --test=spook --build=gradle
9
# generic mn taxonomy 
10
mn create-app [-hivVx] [ - list-features] [-b=BUILD-TOOL] [ - jdk=<javaVersion>] [-l=LANG]


creating app with CLI

Step 3: Open the generated project in your IDE (IntelliJ in my case) to see the complete project structure and files. Micronaut® has close resemblance with Spring Boot that developers can relate to when starting with it. Hence minimize the learning curve of getting on to Micronaut® and its super-rich features.

Complete generated project structure, similar to spring boot conventions

Step 4: Adding programming constructs like Controller, Beans, Interceptor, Security config, profilers, etc with cli.

Shell
 




xxxxxxxxxx
1
11


 
1
$ cd ~/<mn project directory>
2
# then use below cli command to create most of construct
3
$ mn create-controller Creates a controller and associated test
4
$ mn create-websocket-server Creates a Websocket server
5
$ mn create-bean Creates a singleton bean
6
$ mn create-websocket-client 
7
$ mn create-test Creates a test for the project's testing framework
8
$ mn create-job Creates a job with scheduled method
9
$ mn create-client Creates a client interface
10
Example : 
11
$ mn  create-controller Customer



Adding Customer controller

Customer controller class

Case A : Micronaut® app on GraalVM optimised JIT  
Shell
 




xxxxxxxxxx
1


 
1
$ cd ~/< Workspace dir>
2
# using CLI to generate Micronaut® app on GraalVM optimised JIT ( without native-image)
3
mn create-app demo-mn-jit -b=maven -jdk=11 -l=kotlin -f=graalvm
4
# then add controller to it 
5
$ cd ~/< mn project dir>
6
$ mn  create-controller CustomerHandler
7
$ mn  create-bean Customer


Created JAR file

Memory Space : 13.64MB — App + 265MB HotSpotVM/JRE = 278MB approx.
Start-up time = 1.01Sec = 1001ms

Server running on port 8081

GitHub url for refrence demo app generated above used for stats :
https://github.com/scanpratik/micronauts-GraalVM--JIT 
Case B : Micronaut® app on GraalVM - Native-Image   

This is the main case study curiosity to way forward to modern cloud-native, lets observe it closely: Micronaut native image

GitHub url for demo app generated above used for benchmarking :
https://github.com/scanpratik/micronauts-nativeImage-GraalVM 

One can build a native image directly with Maven using the mvn packagecommand without running the native-imageplugin.

XML
 




xxxxxxxxxx
1
20


 
1
<plugin>
2
    <groupId>org.graalvm.nativeimage</groupId>
3
    <artifactId>native-image-maven-plugin</artifactId>
4
    <version>${graalvm.version}</version>
5
    <executions>
6
        <execution>
7
            <goals>
8
                <goal>native-image</goal>
9
            </goals>
10
            <phase>package</phase>
11
        </execution>
12
    </executions>
13
    <configuration>
14
        <skip>false</skip>
15
        <imageName>example</imageName>
16
        <buildArgs>
17
            --no-fallback
18
        </buildArgs>
19
    </configuration>
20
</plugin>


demo native image

GraalVM Native-Image with Micronaut® — app binary generated with SubstrateVM as run time executable

Memory Space: 62MB only— App + native runtime

Start-up time = .022Sec = 22ms
Application startup time

GraalVM native-image with Micronaut® start-up time blazing-fast — 22ms
Case C : SpringBoot on openJDK HotSpotVM JIT — conventional way

Leaving details of SpringBoot with HotSpot VM app generation as it has the de-facto framework and enough material is floating on the internet for reference

GitHub url for demo app generated above used for benchmarking :
https://github.com/scanpratik/graalVM-SpringBoot2.X

Spring Boot + HotSpotVM JIT
SpringBoot + HotSpotVm JIT

SpringBoot + HotSpotVm JIT

Memory Space : 16.51MB — App + 320MB HotSpotVM/JRE = 338MB approx.
Start-up time = 1.81 Sec = 1810ms
1.81 second startup

start-up time ~ 1.81 sec


Seems, HotSpotVM + SpringBoot (proxy and reflection based) has hit bottom-line benchmark for memory footprint and execution startup time.

Design Decision — GraalVM Native-Image vs GraalVM JIT vs HotspotVM JIT :
Sometimes good performance means good throughput, sometimes it means low memory usage, and sometimes it means a fast cold-start startup time.

Benefits of a “Native-Image” aren’t for free — they come with a cost. Obviously, the native executable can only run on a single platform. Another limitation is caused by missing metadata during runtime. Since by default a native image doesn’t retain information about classes and methods, hence one’s ability to perform reflection is limited. As there are many Java frameworks that rely on reflective access, getting them to run on a Native Image may require additional configuration. 

Having said that, it's obvious GraalVM is the way forward and will be encouraged over HotSpotVM. Micronaut® is a goto framework, to be used in conjunction with GraalVM based JIT or Native-Image for cloud-native development. Below flow chart will help in understanding the decision making logic.



GraalVM decision making chart

Ref : GraalVM WhitePaper
GraalVM microservice app Spring Framework Framework application Memory (storage engine) Spring Boot Aspect-oriented programming Dependency injection

Published at DZone with permission of Pratik Prakash. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Datafaker: An Alternative to Using Production Data
  • Creating an Event-Driven Architecture in a Microservices Setting
  • Streaming ETL with Apache Kafka in the Healthcare Industry
  • Progressive Web Apps vs Native Apps: Differences and Similarities

Comments

Cloud Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo