When the micro-service scale becomes larger, the docker image of traditional build will be very bloated, slow to start and large in size, which is not conducive to scale and consumes large resources. The general way to improve this is to use lightweight module injection, use what, add what, and do not use a large framework like Spring, Spring Boot is not recommended for services.

After the above optimization, the performance will be better, but nothing surprising, because base Image is still OpenJDK, dependency injection, reflection, annotations and so on will still slow startup.

GraalVM (www.graalvm.org/).

GraalVM is a new general-purpose virtual machine, no nonsense, straight to the problem, 50 times faster startup, 5 times less memory consumption.

Why is it so awesome, because it uses AHEAD-of-time (AHEAD-of-time) compilation, fast boot and low memory consumption. Advantages of the official column:

  • efficient
  • AOT compilation (Quick start)
  • multilingual
  • Advanced tools (debugging, monitoring, profiles, etc.)

The latter two have not been particularly felt, because the company’s background is mainly Java/Kotlin/Grrovy, there is no multi-language problem. These advanced tools, the company has a unified stack, is not available.

Micronaut (Github.com/micronaut-p…

Micronaut is a modern, JVM-based, full-stack Java framework for modular build, easy to test JVM applications, supporting Java, Kotlin and Groovy. It provides compile-time dependency injection and AOP processing capabilities and minimizes the use of reflection and dynamic proxies. It has a faster startup speed and a lower memory footprint.

Micronaut + GraalVM (POC)

  1. Create an App with Micronaut Template

    • Version: 2.3.3
    • language: Java 11
    • build: gradle
    • test: jUnit
    • Feature: netty – server
  2. Create a simple API, /hello

    @Controller("/hello") public class HelloController { @Get("/") public String index() { return "hello from Micronaut + GraalVM"; }}Copy the code
  3. Add lib to build.gradle

    annotationProcessor("io.micronaut:micronaut-graal")
    compileOnly("org.graalvm.nativeimage:svm")
    Copy the code
  4. Create a new file SRC /main/resources/ meta-INF /native image/native image.properties

    Args= -H:IncludeResources=logback.xml|application.yml \
          -H:Name=mn-graalvm \
          -H:Class=com.sz.App \
          --report-unsupported-elements-at-runtime
    Copy the code
  5. Dockerfile

    # this image is only used in building, not for runtime FROM ghcr.io/graalvm/graalvm-ce:latest as graalvm # gu = graal updater RUN gu install native-image COPY . /home/app/mn-graalvm WORKDIR /home/app/mn-graalvm RUN native-image --no-server -cp build/libs/mn-graalvm-*-all.jar Frolvlad /alpine-glibc:alpine-3.12 RUN apk update && apk add libstdc++ EXPOSE 8080 COPY -- FROM =graalvm /home/app/mn-graalvm/mn-graalvm /app/mn-graalvm ENTRYPOINT ["/app/mn-graalvm"]Copy the code
  6. Build

    • ./gradlew clean assemble
    • docker build . -t mn-graalvm

This process consumes time and resources. It is recommended to allocate 6 ~ 8GB memory to Docker, otherwise it is easy to report errors

The results of

Start time comparison
  • GraalVM Native (32 ms)

  • Non-native (961 ms)

Image size
  • Native 81MB, non-native 251MB

Memory usage
  • Native (7.64 MB)

  • Non-native (47.27 MB)

Compared to summarize
native The non-native
The startup time 32 ms 961 ms
Image size 81 MB 251MB
Memory usage 7 MB 47MB

Compared to the simplest Web app, GraalVM performance is good, and startup time and memory usage are attractive. The next step is to use large projects for further comparison and analysis of performance.

Source: github.com/shubozhang/…