GraalVM සහ Spring Boot: Super Fast Native Apps හදමු! | SC Guide

GraalVM සහ Spring Boot: Super Fast Native Apps හදමු! | SC Guide

GraalVM සහ Spring Boot: අහස උසට වේගවත් Native Apps හදමු! SC Guide

අයියෝ, මේ Java Application එක load වෙන්න ගන්න වෙලාව! ඔයාලත් කීප වතාවක් මේක හිතලා ඇති, නේද? විශේෂයෙන්ම Microservices වගේ දේවල් හදනකොට, Spring Boot Application එකක් start වෙන්න ගන්න වෙලාව, ඒකෙන් ගන්න Memory එක ලොකු හිසරදයක් වෙන්න පුළුවන්. Cloud Native ලෝකේ (Serverless, Containerization) වගේ තැන් වලට මේක ලොකු ප්‍රශ්නයක්. හැබැයි අද අපි මේ ප්‍රශ්නෙට පට්ටම විසඳුමක් ගැන කතා කරනවා! ඒ තමයි GraalVM එකත් එක්ක Spring Boot App එකක් Native Image එකක් විදියට Compile කරන එක.

මේක හරියට, සාමාන්‍ය වාහනයක් Formula 1 Race Car එකක් බවට පත් කරනවා වගේ වැඩක්. අද අපි බලමු කොහොමද අපේ Spring Boot Project එකකට GraalVM දාලා, ඒක Light-Weight, Super Fast Native Image එකක් බවට පත් කරගන්නේ කියලා. මේකෙන් අපේ applications වල Performance එක ඉහළ දාන්නත්, Memory Usage එක අඩු කරන්නත් පුළුවන්. මේකෙන් අපිට Cloud Bills අඩු කරගන්නත් පුළුවන් කියන එක අමතක කරන්න එපා!

GraalVM කියන්නේ මොකක්ද? (What is GraalVM?)

සරලවම කිව්වොත්, GraalVM කියන්නේ Oracle Labs වලින් හදපු, Universal Virtual Machine එකක්. සාමාන්‍යයෙන් Java Application එකක් run වෙන්නේ Java Virtual Machine (JVM) එකක් මතනේ. ඒක Just-In-Time (JIT) Compilation කියන ක්‍රමවේදය පාවිච්චි කරනවා. ඒ කියන්නේ, code එක run වෙනකොට තමයි compile කරලා machine code බවට පත් කරන්නේ.

හැබැයි GraalVM එකේ Native Image කියන Feature එක තියෙනවා. මේකෙන් පුළුවන් අපේ Java Application එක සම්පූර්ණයෙන්ම Ahead-Of-Time (AOT) Compile කරලා, standalone executable file එකක් විදියට හදන්න. ඒ කියන්නේ, JVM එකක් නැතුව, ඒ executable file එක ඕනෑම තැනක run කරන්න පුළුවන්. හිතාගන්න පුළුවන් නේ ඒකෙන් ලැබෙන වාසි?

Native Image එකක වාසි:

  • Rocket-Fast Startup Times: Application එක start වෙන්න ගන්න වෙලාව Milliseconds ගානට අඩු වෙනවා.
  • Low Memory Footprint: Memory එකත් අඩුවෙන් පමා කරනවා. සාමාන්‍යයෙන් JVM එකකට වඩා 10 ගුණයකින් විතර අඩු වෙන්න පුළුවන්.
  • Smaller Executables/Docker Images: සාමාන්‍ය JAR එකකට වඩා executable file එකේ size එක කුඩායි. ඒ නිසා Docker Images වල size එකත් ගොඩක් අඩු වෙනවා. Cloud එකේදී මේකෙන් bandwidth සහ storage cost අඩු කරගන්න පුළුවන්.
  • No JVM Required: Application එක run කරන්න වෙනම JVM එකක් install කරන්න ඕනේ නෑ. ඒක standalone executable එකක්.

මේක Java විතරක් නෙවෙයි, JavaScript, Python, Ruby, R වගේ ගොඩක් භාෂාවන් වලටත් support කරනවා. ඒකයි මේකට “Universal VM” කියලා කියන්නේ.

Spring Boot Native ඇයි වැදගත්? (Why Spring Boot Native is Important?)

ඔයාලා දන්නවා Spring Boot කියන්නේ Java ලෝකේ ජනප්‍රියම Framework එකක් කියලා. Microservices, Web Applications, Batch Processing වගේ ගොඩක් දේවල් වලට මේක පාවිච්චි කරනවා. ඒත්, Spring Boot වලටත් පොඩි අඩුපාඩුවක් තියෙනවා. ඒ තමයි startup time එක සහ memory consumption එක. විශේෂයෙන්ම:

  • Cloud Environments: AWS Lambda වගේ Serverless Functions වල, Application එක cold-start වෙනකොට ගොඩක් වෙලා යනවා. GraalVM Native Image එකක් මේ cold-start delay එක නැති කරනවා. Kubernetes වගේ Container Orchestration platforms වලදී, අඩු Memory එකක් පාවිච්චි කරන එකෙන් resource optimization එකක් කරගන්න පුළුවන්.
  • Microservices: Microservices Architecture එකේදී අපිට ගොඩක් කුඩා, ඉක්මනින් start වෙන services ඕනේ. GraalVM මේ අවශ්‍යතාවය හොඳටම සපුරනවා.
  • Cost Savings: Cloud එකේදී CPU සහ Memory usage එක අනුව තමයි ගාස්තු අය කරන්නේ. GraalVM පාවිච්චි කරන එකෙන් මේ operating costs සැලකිය යුතු මට්ටමකින් අඩු කරගන්න පුළුවන්.

Spring Boot 3.x ඉඳන්, Spring Framework එක GraalVM Native Image support එකට ගොඩක් හොඳින් optimize වෙලා තියෙනවා. ඒ නිසා අපිට ගොඩක් පහසුවෙන් Native Images හදන්න පුළුවන්.

පටන් ගමු! GraalVM සහ Spring Boot සෙට් කරගන්නේ කොහොමද? (Getting Started: How to Setup GraalVM and Spring Boot?)

Native Image එකක් හදන්න කලින් අපිට GraalVM JDK එකක් install කරගන්න ඕනේ. ඒ වගේම Spring Boot Project එකක් හදාගන්නත් ඕනේ.

පළමු පියවර: GraalVM JDK ස්ථාපනය (Install GraalVM JDK)

මේකට පහසුම ක්‍රමය තමයි SDKMAN! පාවිච්චි කරන එක. ඔයාලට SDKMAN! install කරලා නැත්නම්, මේ link එකට ගිහින් install කරගන්න: https://sdkman.io/install

SDKMAN! install කරාට පස්සේ, GraalVM JDK එකක් install කරන්න මේ command එක run කරන්න:

sdk install java 21-graal

මේකෙන් GraalVM 21 (හෝ අලුත්ම stable version එකක්) install වෙයි. install වුනාට පස්සේ, ඔයාලට පුළුවන් මේක default Java version එක විදියට set කරන්න:

sdk default java 21-graal

ඔයාලට මේක verify කරන්න පුළුවන් මේ command එකෙන්:

java -version

Output එකේ GraalVM කියලා තිබිය යුතුයි.

දෙවන පියවර: Spring Boot Project එකක් හදමු (Create a Spring Boot Project)

අපි Spring Initializr (https://start.spring.io/) පාවිච්චි කරලා අලුත් Spring Boot Project එකක් හදමු. මේක හදනකොට මේ දේවල් මතක තියාගන්න:

  • Project: Maven Project
  • Language: Java
  • Spring Boot Version: 3.2.x (හෝ ඊට වැඩි අලුත් version එකක්)
  • Dependencies:
    • Spring Web: REST APIs හදන්න.
    • Spring Native: මේක තමයි GraalVM Native Image Support එක දෙන්නේ. (Spring Boot 3.x වලට මේක automatic add වෙනවා. නැත්නම් manually add කරන්න පුළුවන්.)
    • Spring Actuator (Optional): Application health, metrics වගේ දේවල් බලන්න. Native Images වල Performance බලන්න උදව් වෙයි.

Project එක Generate කරලා, Download කරලා, ඔයාලගේ IDE එකේ (IntelliJ IDEA, VS Code වගේ) Open කරගන්න.

Project එකේ pom.xml file එකේ spring-boot-maven-plugin එක ඇතුලේ true සහ වගේ configurations තියෙනවද කියලා බලන්න. ඒ වගේම spring-boot-starter-web සහ spring-boot-starter-actuator (තියෙනවා නම්) dependencies තියෙනවද කියලා බලන්න.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <image>
                    <name>${project.artifactId}:native</name>
                    <builder>paketobuildpacks/builder-jammy-tiny:latest</builder>
                </image>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>build-info</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

මෙහි

tag එකෙන් අපිට Docker image එකක් build කරන්න පුළුවන්. ඒත් අපි මුලින්ම native executable එකක් හදමු.

අපි Native Image එකක් හදමු! (Let's Build a Native Image!)

දැන් අපි අපේ Spring Boot Project එකට පොඩි REST Controller එකක් එකතු කරමු. මේකෙන් අපිට App එක start වුනාට පස්සේ හරියට වැඩ කරනවද කියලා බලන්න පුළුවන්.

// src/main/java/com/example/graalvmguide/HelloController.java

package com.example.graalvmguide;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello from GraalVM Native Spring Boot App!";
    }
}

දැන් අපි මේ Project එක compile කරලා, Native Image එකක් හදමු. Project එකේ root directory එකට ගිහින්, Command Line එක open කරගන්න.

සාමාන්‍ය JAR එකක් Build කරලා Run කරමු (Build and Run a Regular JAR)

මුලින්ම අපි සාමාන්‍ය JAR file එකක් build කරලා, ඒක start වෙන්න ගන්න වෙලාව බලමු. මේකෙන් අපිට Native Image එකේ Performance එක සාපේක්ෂව බලන්න පුළුවන්.

mvn clean package

මේකෙන් target/graalvm-guide-0.0.1-SNAPSHOT.jar වගේ file එකක් හැදෙයි. දැන් ඒක run කරන්න:

java -jar target/graalvm-guide-0.0.1-SNAPSHOT.jar

Console එකේ බලන්න Application එක start වෙන්න කොච්චර වෙලා ගියාද කියලා. සාමාන්‍යයෙන් තප්පර 2-5ත් අතර වෙලාවක් ගන්නවා.

Native Executable එකක් Build කරලා Run කරමු (Build and Run a Native Executable)

දැන් අපි ඇත්තම වැඩේට බහිමු! Native Image එකක් build කරන්න Spring Boot 3.x වලට Maven එකේ මේ plugin goal එක තියෙනවා:

mvn clean package -Pnative

මේ command එකෙන් ඔබේ Spring Boot application එක GraalVM Native Executable එකක් විදියට compile කරනවා. මේකට ටිකක් වෙලා යයි (සමහරවිට විනාඩි කිහිපයක්). Build process එකේදී GraalVM එක application එකේ static analysis කරලා, run time එකේදී අවශ්‍ය වෙන components විතරක් bundle කරලා executable එක හදනවා.

Build එක සාර්ථක වුනාට පස්සේ, target/ folder එක ඇතුලේ graalvm-guide (Windows නම් graalvm-guide.exe) වගේ executable file එකක් හැදිලා තියේවි. මේක තමයි අපේ Native Image එක!

දැන් ඒක run කරලා බලමු:

./target/graalvm-guide

දැන් Console එකේ බලන්න Application එක start වෙන්න කොච්චර වෙලා ගියාද කියලා. පුදුමයි නේද? මේක Milliseconds ගානකින් start වෙනවා. තප්පර ගානකින් start වුන App එක Milliseconds ගානට ආවා කියන්නේ, පට්ට වැඩක් නේද? ඒ වගේම, memory footprint එකත් ගොඩක් අඩුයි.

දැන් Browser එකේ http://localhost:8080/hello කියලා ගිහින් බලන්න. “Hello from GraalVM Native Spring Boot App!” කියලා Message එකක් පෙන්නයි.

Docker Image එකක් විදියට Build කරමු (Build as a Docker Image)

Cloud Native deployments වලට මේක ගොඩක් වැදගත්. Spring Boot එකට Built-in support එකක් තියෙනවා Docker Image එකක් විදියට Native Image එකක් build කරන්න:

mvn spring-boot:build-image

මේකෙන් buildpack එකක් පාවිච්චි කරලා Docker Image එකක් හදනවා. මේ Image එක සාමාන්‍ය Spring Boot Docker Image එකකට වඩා ගොඩක් කුඩායි. Build වුනාට පස්සේ, Docker Desktop එකේ බලන්න පුළුවන් Image එකේ size එක. ඒක 50MB වගේ කුඩා වෙන්න පුළුවන්!

Tips සහ Tricks / පොදු ගැටළු (Tips and Tricks / Common Issues)

GraalVM Native Image එකක් Build කරන එක හැමවෙලේම පහසු වෙන්නේ නෑ. සමහර වෙලාවට අපිට පොඩි පොඩි Tips and Tricks ටිකක් පාවිච්චි කරන්න වෙනවා. මොකද GraalVM AOT Compile කරනකොට, Application එකේ runtime එකේදී අවශ්‍ය වෙන හැම class එකක්, resource එකක්, proxy එකක් වගේ දේවල් ගැනම දැනගෙන ඉන්න ඕනේ.

Debugging:

Native Executable එකක් Debug කරන එක සාමාන්‍ය Java Application එකක් Debug කරනවට වඩා ටිකක් සංකීර්ණයි. ඒත් GraalVM එකේ Debugging tools තියෙනවා. සාමාන්‍යයෙන් development phase එකේදී Hot-reload වගේ දේවල් වලට JAR එකක් පාවිච්චි කරලා, production ready කරනකොට Native Image එකක් build කරන එක හොඳයි.

3rd Party Libraries Compatibility:

සමහර 3rd party libraries වලට GraalVM Native Image Support එක තවම නෑ. ඒ නිසා project එකට library එකක් add කරන්න කලින් ඒක GraalVM එක්ක compatible ද කියලා බලන්න. GraalVM Native Image Reachability Metadata Repository (GitHub එකේ තියෙනවා) එක බලන එක ගොඩක් වටිනවා.

Build Time:

Native Image Compilation එක සාමාන්‍ය JAR compilation එකට වඩා ගොඩක් වෙලා ගන්නවා. ඒක සාමාන්‍ය දෙයක්. Build environment එකේ RAM එක සහ CPU එක හොඳට තියෙන්න ඕනේ.

Reflection, Serialization, Dynamic Proxies:

Java Application එකක් runtime එකේදී Reflection, Serialization, හෝ Dynamic Proxies පාවිච්චි කරනවා නම්, GraalVM එකට ඒ ගැන compile-time එකේදී දැනගන්න විදියක් නෑ. Spring Boot 3.x මේවායින් ගොඩක් දේවල් auto-configure කරනවා. ඒත් සමහර 3rd party libraries වලට මේවා හඳුනාගන්න බෑ.මේකට විසඳුම තමයි src/main/resources/META-INF/native-image/your-app-id/ කියන folder එක ඇතුලේ special configuration files හදන එක. මේවා reflect-config.json, resource-config.json, proxy-config.json වගේ files.උදාහරණයක් විදියට, SomeClass එකක් Reflection වලින් පාවිච්චි කරනවා නම්, reflect-config.json එකට මේ වගේ entry එකක් දාන්න පුළුවන්:

[
  {
    "name": "com.example.graalvmguide.SomeClass",
    "allDeclaredMethods": true,
    "allDeclaredFields": true
  }
]

Spring Boot application එක run කරනකොට -agentlib:native-image-agent=config-output-dir=/path/to/output වගේ command එකක් දීලා, runtime එකේදී පාවිච්චි වෙන Reflection data අල්ලගෙන auto-generate කරගන්නත් පුළුවන්.

නිගමනය (Conclusion)

GraalVM Native Image එකත් එක්ක Spring Boot Application එකක් Build කරන එකෙන් ලැබෙන වාසි අති විශාලයි. Fast startup, අඩු Memory footprint, සහ කුඩා Executable files කියන්නේ Cloud-Native ලෝකේදී අත්‍යවශ්‍ය දේවල්. මේකෙන් අපිට Cloud එකේදී Resource Usage එක අඩු කරගෙන, මුදල් ඉතුරු කරගන්නත් පුළුවන්.

ඔයාලත් මේක උත්සාහ කරලා බලන්න. විශේෂයෙන්ම Microservices හෝ Serverless functions වගේ දේවල් කරනවා නම්, GraalVM කියන්නේ අනිවාර්යෙන්ම explore කරන්න ඕනේ Technology එකක්. මොනවා හරි ගැටළුවක් ආවොත්, නැත්නම් මේ ගැන අලුත් අදහසක් තියෙනවා නම්, Comment section එකේ දාන්න. අපි ඒ ගැන කතා කරමු.

අපි මේ වගේ තවත් තාක්ෂණික දේවල් ගැන ඉදිරියේදී කතා කරමු! ජය වේවා!