Spring Boot Serverless: AWS Lambda, GCP Functions | සිංහලෙන් SC Guide

Spring Boot Serverless: AWS Lambda, GCP Functions | සිංහලෙන් SC Guide

ආයුබෝවන් කොල්ලෝ කෙල්ලෝ ටික! කොහොමද ඉතින්? අද අපි කතා කරන්න යන්නේ ගොඩක් අයගේ ඔලුවේ තියෙන, හැබැයි හරියටම තේරුම් ගන්න ටිකක් අමාරු මාතෘකාවක් ගැන. ඒ තමයි Spring Boot Application එකක් Serverless Architecture එකකට deploy කරන විදිහ. විශේෂයෙන්ම AWS Lambda සහ Google Cloud Functions වගේ Platforms වලට.

දැන් ඔයාලා දන්නවා, සාමාන්‍යයෙන් අපේ Spring Boot Project එකක් හදලා deploy කරනවා කියන්නේ, server එකක් අරගෙන, ඒකට JVM එක install කරලා, අපේ JAR file එක දාලා run කරන එකනේ. ඒත්, අද වෙනකොට ලෝකේ trend එක වෙනස් වෙලා. Servers manage කරන එකේ ඔලුව කනවා කියලා, ගොඩක් අය යොමු වෙන්නේ Serverless පැත්තට. මොකද, server එක ගැන හිතන්නේ නැතුව, අපේ code එක ගැන විතරක් හිතන්න ලැබෙන නිසා.

මේ Article එකෙන් අපි බලාපොරොත්තු වෙන්නේ, Spring Boot වගේ heavyweight framework එකක් කොහොමද මේ lightweight Serverless environment එකකට ගලපගන්නේ කියලා පැහැදිලි කරන්න. එහෙනම්, වැඩි කතා නැතුව අපි පටන් ගමු!

Serverless infrastructure with code and clouds

මොකක්ද මේ Serverless කියන්නේ?

මුලින්ම, මේ Serverless කියන්නේ මොකක්ද කියලා හරියටම තේරුම් ගමු. Serverless කියන්නේ servers නැහැ කියන එක නෙවෙයි. අප්පා! ඒක ලොකු වැරදි මතයක්. Serverless කියන්නේ, servers manage කරන වැඩේ අපිට අයිති නැහැ කියන එක. ඒක Cloud Provider (AWS, Google Cloud, Azure වගේ) බලාගන්නවා. අපිට කරන්න තියෙන්නේ අපේ code එක දීලා, ඒක execute කරන්න කියලා කියන එක විතරයි.

මේක සාමාන්‍යයෙන් Functions as a Service (FaaS) කියලා හඳුන්වනවා. AWS Lambda, Google Cloud Functions, Azure Functions මේ category එකට අයිතියි. ඔයාගේ code එක run වෙන්නේ යම්කිසි event එකක් trigger වුණාම විතරයි. (උදා: HTTP request එකක්, Database එකකට record එකක් add වුණාම, file එකක් upload වුණාම).

Serverless වල වාසි මොනවද?

  • No Server Management: Servers patch කරන්න, update කරන්න, maintain කරන්න ඕනේ නැහැ. ඔක්කොම Cloud Provider බලාගන්නවා. ගොඩක් ලොකු බරක් ඔලුවෙන් අයින් වෙනවා.
  • Auto-Scaling: ඔයාගේ application එකට කොච්චර traffic ආවත්, ඒකට ඔරොත්තු දෙන්න automatically scale වෙනවා. User 10ක් ආවත්, 100,000ක් ආවත් වැඩේ සිද්ධ වෙනවා.
  • Pay-per-Execution: ඔයාගේ code එක run වෙන වෙලාවට විතරයි සල්ලි යන්නේ. Idle වෙලාවට සල්ලි යන්නේ නැහැ. සාමාන්‍ය server එකක් නම්, run වෙනකන් හැම තත්පරේකටම බිල් යනවා. මේක නම් පට්ටම වාසියක්.
  • Faster Development & Deployment: Infrastructure ගැන හිතන්නේ නැති නිසා, code කරන එකට වැඩි වෙලාවක් දෙන්න පුලුවන්. Deployment process එකත් ගොඩක් සරලයි.

Serverless වල අවාසි මොනවද?

  • Cold Starts: ඔයාගේ function එක ටික වෙලාවක් activate වෙලා නැති වුණොත්, ඊලඟ request එකට response දෙන්න ටිකක් වෙලා යනවා. මේකට තමයි Cold Start එකක් කියන්නේ. Java වගේ JVM languages වලට මේක ටිකක් ලොකු ප්‍රශ්නයක්, මොකද JVM එක load වෙන්නත් වෙලාවක් යන නිසා.
  • Vendor Lock-in: Cloud Provider කෙනෙක්ගේ platform එකක් use කරන නිසා, ඒ platform එකෙන් වෙනත් platform එකකට මාරු වෙන එක ටිකක් අමාරු වෙන්න පුලුවන්.
  • Debugging & Monitoring: Distributed system එකක් නිසා, problems trace කරන එක ටිකක් අමාරු වෙන්න පුලුවන්.
  • Resource Limits: Functions වලට memory, CPU, execution time වගේ දේවල් වලට limits තියෙනවා.

Spring Boot Application එකක් Serverless වලට ගලපගන්නේ කොහොමද?

සාමාන්‍යයෙන් Spring Boot කියන්නේ monolithic applications හදන්න ගොඩක් දෙනෙක් use කරන framework එකක්. ඒකේ startup time එක ටිකක් වැඩියි. Serverless environment එකක් කියන්නේ, functions වලට, ඒවා quick start වෙන්න ඕනේ. ඉතින්, මේ දෙක එකට ගලපගන්න විවිධ ක්‍රම තියෙනවා.

Spring Cloud Function

මේක තමයි Spring Boot application එකක් Serverless වලට deploy කරන්න තියෙන official විදිහ. Spring Cloud Function එකෙන් ඔයාට საშუალ్యයක් දෙනවා, ඔයාගේ code එක function එකක් විදිහට ලියන්න. මේක Cloud Provider එකට agnostic (ප්ලැට්ෆෝම් එකට විශේෂ නැති) විදිහට වැඩ කරනවා.

සරලවම, ඔයාගේ Spring Boot application එකේ REST controller එකක් වෙනුවට, java.util.function.Function, Consumer, හෝ Supplier එකක් විදිහට logic එක ලියන්න පුලුවන්. මේවා Spring Boot application context එක ඇතුලේ initialize වෙනවා. පළමු request එක එද්දි, Spring Boot context එක initialize වෙනවා, ඊට පස්සේ request ආවම, අර function එක විතරක් execute වෙනවා.

Dependency එක:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-function-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-function-context</artifactId>
</dependency>

Function එකක් ලියන විදිහ:

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    @Bean
    public Function<String, String> uppercase() {
        return value -> value.toUpperCase();
    }

    @Bean
    public Consumer<String> logMessage() {
        return value -> System.out.println("Received: " + value);
    }

    @Bean
    public Supplier<String> greeting() {
        return () -> "Hello from Spring Boot Serverless!";
    }
}

මේ වගේ functions Spring Cloud Function එකෙන් expose කරනවා. HTTP request එකක් ආවම, ඒක මේ functions වලට route කරන්න පුලුවන්.

GraalVM Native Images

Spring Boot application එකක් Serverless වලට deploy කරනකොට තියෙන ලොකුම ප්‍රශ්නයක් තමයි Cold Start එක. ඒකට හොඳම විසඳුමක් තමයි GraalVM Native Images. GraalVM වලින් ඔයාගේ Java application එක Native executable එකක් බවට compile කරන්න පුලුවන්. මේ native executable එකට JVM එකක් අවශ්‍ය නැහැ, ඒ නිසා startup time එක ගොඩක් අඩුයි, memory footprint එකත් ගොඩක් පොඩියි.

Spring Boot 3.x ඉඳන් මේකට හොඳට support කරනවා. ඒත් හැම dependency එකක්ම GraalVM compatible නැති වෙන්න පුලුවන්. අනිත් එක, compile කරන්න ගොඩක් වෙලා යනවා.

AWS Lambda වලට Deploy කරමු!

දැන් අපි බලමු අපේ Spring Boot application එකක් AWS Lambda වලට deploy කරන්නේ කොහොමද කියලා. මේකට අපි Spring Cloud Function, AWS Adapter එක use කරනවා.

1. Dependencies එකතු කිරීම:

ඔයාගේ pom.xml (Maven නම්) හෝ build.gradle (Gradle නම්) file එකට මේ dependency එක එකතු කරන්න:

<!-- For Maven -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-function-adapter-aws</artifactId>
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-events</artifactId>
    <version>3.11.0</version> <!-- නවතම version එක බලන්න -->
</dependency>
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-core</artifactId>
    <version>1.2.1</version> <!-- නවතම version එක බලන්න -->
</dependency>

2. Lambda Handler එකක් හැදීම:

සාමාන්‍යයෙන් Spring Boot Main class එක run කරනවා වගේ නෙවෙයි. AWS Lambda එකට ඔයාගේ function එක invoke කරන්න පුලුවන් handler class එකක් ඕනේ. Spring Cloud Function AWS Adapter එකෙන් ඒකට පහසුකම් සලසනවා. ඔයාට පුලුවන් SpringBootRequestHandler හෝ SpringBootStreamHandler extend කරන්න.

// Request/Response body එක String එකක් විදිහට handle කරනවා නම්
public class UppercaseHandler extends SpringBootRequestHandler<String, String> {

}

// Stream based operations (binary data වගේ දේවල්) කරනවා නම්
public class UppercaseStreamHandler extends SpringBootStreamHandler {

}

මේ handler class එකට ඔයාගේ Spring Boot application context එක load කරන්න පුලුවන්. මේක ඇතුලේ තමයි ඔයාගේ @Bean functions locate වෙන්නේ.

3. Application Properties (application.yml):

ඔයාගේ Lambda function එකට අවශ්ය Spring Cloud Function bean එක specific කරන්න application.yml එකට මේක එකතු කරන්න:

spring:
  cloud:
    function:
      definition: uppercase # ඔයාගේ @Bean function එකේ නම

4. Fat JAR එකක් Build කිරීම:

AWS Lambda එකට deploy කරන්න නම්, ඔයාට ඔයාගේ application එකත්, ඒකේ dependencies ඔක්කොමත් එකතු කරපු “fat JAR” එකක් ඕනේ. Maven Shade Plugin එක මේකට use කරන්න පුලුවන්.

<!-- For Maven -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.4</version>
    <configuration>
        <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <artifactSet>
                    <excludes>
                        <exclude>com.amazonaws:aws-lambda-java-events</exclude>
                        <exclude>com.amazonaws:aws-lambda-java-core</exclude>
                    </excludes>
                </artifactSet>
            </configuration>
        </execution>
    </executions>
</plugin>

Build කරන්න: mvn clean package

5. AWS Lambda වලට Deploy කිරීම:

දැන් ඔයාට පුලුවන් AWS Management Console එකෙන් හෝ AWS CLI එකෙන් deploy කරන්න.

Console එකෙන්:

  • AWS Lambda service එකට යන්න.
  • “Create function” ක්ලික් කරන්න.
  • “Author from scratch” තෝරන්න.
  • Function Name එක දෙන්න.
  • Runtime එකට “Java 11” හෝ “Java 17” තෝරන්න.
  • Architecture “x86_64” (සාමාන්‍යයෙන්).
  • Execution role එකක් (permissions තියෙන) create කරන්න හෝ existing එකක් තෝරන්න.
  • Function එක create කරාට පස්සේ, code tab එකේ “Upload from” -> “.jar file” තෝරලා, ඔයාගේ fat JAR එක upload කරන්න.
  • Handler: මෙතනට ඔයා හදපු handler class එකේ full path එක දෙන්න. (උදා: com.example.UppercaseHandler::handleRequest). ::handleRequest කියන්නේ invoke කරන්න ඕනේ method එක. Spring Cloud Function adapter එකෙන් මේක automate කරනවා.
  • Memory සහ Timeout settings adjust කරන්න. Spring Boot application එකකට සාමාන්‍යයෙන් වැඩි Memory (උදා: 512MB-1GB) සහ වැඩි Timeout (උදා: 30-60 seconds) ඕනේ වෙනවා, මොකද Cold Start එකට ටිකක් වෙලා යන නිසා.
  • SnapStart (Java 11/17 වලට): Lambda settings වල, Configurations tab එකේ, General configuration යටතේ SnapStart enable කරන්න. මේකෙන් Cold Start එක ගොඩක් අඩු කරගන්න පුලුවන්.

6. API Gateway එකක් Configure කිරීම:

ඔයාගේ Lambda function එක HTTP request එකකින් trigger කරන්න නම්, API Gateway එකක් හදන්න ඕනේ. Lambda Console එකේ “Add Trigger” ගිහින් “API Gateway” තෝරලා, “REST API” එකක් create කරලා, deploy කරන්න.

Google Cloud Functions වලටත් පුලුවන්ද?

ඔව්, පුලුවන්! Google Cloud Functions වලටත් Spring Boot application එකක් deploy කරන්න පුලුවන්. ක්‍රියාවලිය AWS Lambda එකට ගොඩක් සමානයි.

1. Dependency එකතු කිරීම:

<!-- For Maven -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-function-adapter-gcp</artifactId>
</dependency>

2. GCP Function Handler එකක් හැදීම:

Google Cloud Functions වලට specific interfaces තියෙනවා (HttpFunction, BackgroundFunction). Spring Cloud Function Adapter එකෙන් මේවාට support කරනවා. ඔයාට පුලුවන් ඔයාගේ Spring Boot Application එක SpringBootHttpFunction හෝ SpringBootBackgroundFunction extend කරන්න.

// HTTP Function එකක් නම්
public class GcpHttpUppercaseFunction extends SpringBootHttpFunction {
    // No custom code needed if you have @Bean functions defined in your main app
}

// Background Function එකක් නම් (Pub/Sub, Storage events වගේ)
public class GcpBackgroundLogMessageFunction extends SpringBootBackgroundFunction {
    // No custom code needed
}

3. deploy කිරීම:

GCP Console එකෙන් හෝ gcloud CLI එකෙන් deploy කරන්න පුලුවන්.

gcloud functions deploy GcpHttpUppercaseFunction \
    --trigger-http \
    --runtime java11 \ # Or java17
    --entry-point com.example.GcpHttpUppercaseFunction \ # ඔයාගේ handler class එක
    --source target/your-app.jar \ # ඔයාගේ fat JAR එක
    --memory 512MB \ # Memory
    --timeout 60s # Timeout

මෙහිදීත් Cold Start එක ගැන සැලකිලිමත් වෙන්න ඕනේ. Spring Boot startup time එක නිසා, පළමු invocation එකට වැඩි වෙලාවක් යන්න පුලුවන්.

ප්‍රායෝගික උපදෙස් සහ හොඳම ක්‍රම

Spring Boot application එකක් Serverless වලට deploy කරනකොට, හොඳ performance එකක් සහ cost-effectiveness එකක් ගන්න මේ tips ටික ගොඩක් වැදගත් වෙයි:

  • Cold Starts minimize කරන්න:
    • GraalVM Native Images: මේක තමයි හොඳම විසඳුම. Startup time එක milliseconds ගානට අඩු කරගන්න පුලුවන්.
    • AWS Lambda SnapStart: Java 11/17 runtimes වලට මේක support කරනවා. Lambda function එකේ snapshot එකක් අරගෙන, Cold Start එකකදී ඒකෙන් resume වෙනවා. මේක අනිවාර්යයෙන්ම use කරන්න.
    • Memory Allocation: Lambda function එකට වැඩි memory (e.g., 512MB-1GB) දෙන්න. Memory වැඩි වෙනකොට CPU power එකත් වැඩි වෙනවා, ඒ නිසා startup time එක අඩු වෙන්න පුලුවන්.
    • Keep warm: Periodically (every 5-10 minutes) ඔයාගේ function එක invoke කරන්න (CloudWatch Event Rules/Cloud Scheduler වගේ දේවල් use කරලා). මේකෙන් Cold Start එක අඩු කරගන්න පුලුවන්, හැබැයි මේකට පොඩි cost එකක් යනවා.
  • JAR Size එක අඩු කරන්න:
    • ඔයාගේ application එකට අවශ්‍ය dependencies විතරක් use කරන්න. අනවශ්‍ය libraries remove කරන්න. JAR size එක අඩු වෙන තරමට, upload කරන්නයි, load කරන්නයි යන වෙලාව අඩු වෙනවා.
  • Logging සහ Monitoring:
    • Serverless functions වලට සාමාන්‍ය debugging tools use කරන්න අමාරුයි. ඒ නිසා CloudWatch (AWS) හෝ Cloud Logging (GCP) වගේ services වලින් logs check කරන්න පුරුදු වෙන්න. Distributed Tracing tools (X-Ray, Cloud Trace) use කරන්න.
  • Stateless වෙන්න:
    • Serverless functions stateless වෙන්න ඕනේ. ඒ කියන්නේ, එක invocation එකක state එක ඊලඟ invocation එකට බලපාන්න බැහැ. State manage කරන්න DynamoDB, Aurora Serverless (AWS), Firestore, Cloud SQL (GCP) වගේ external databases use කරන්න.
  • Cost Optimization:
    • ඔයාගේ function එකට අවශ්‍ය අවම memory සහ timeout එක තෝරන්න. අනවශ්‍ය විදිහට වැඩි memory හෝ timeout දාලා, bill එක වැඩි කරගන්න එපා.

ගොඩක් කමයි, Wrap කරමු!

ඉතින්, අද අපි කතා කළේ Spring Boot application එකක් Serverless environment එකකට ගලපගන්න පුලුවන් කොහොමද කියන එක ගැන. මුලින් අමාරු වගේ පෙනුනත්, Spring Cloud Function වගේ දේවල් නිසා මේක එච්චරටම සංකීර්ණ නැහැ. Cold Start එක, memory footprint එක වගේ challenges තියෙනවා තමයි, හැබැයි GraalVM Native Images, AWS Lambda SnapStart වගේ technologies මේකට හොඳ solutions දීලා තියෙනවා.

Serverless කියන්නේ අනාගතයේ technology trend එකක්. මේකෙන් infrastructure management එකේ headaches අඩු කරගෙන, code කරන එකට වැඩි focus එකක් දෙන්න පුලුවන්. Cost-effective, scalable, සහ maintain කරන්න පහසු applications හදන්න මේක හොඳ විකල්පයක්.

ඔයාලත් අනිවාර්යයෙන්ම මේ concepts ගැන තවදුරටත් හොයලා බලලා, ඔයාලගේම Spring Boot Project එකක් Serverless වලට deploy කරලා බලන්න. එතකොට තමයි හරියටම feel එක එන්නේ!

මේ Article එක ගැන ඔයාලගේ අදහස් මොනවද කියලා පහල Comment Section එකේ දාන්න. තව මොනවා ගැනද දැනගන්න ඕනේ, එහෙමත් අපිට කියන්න. අපි ඊලඟ Article එකෙන් හම්බවෙමු! තෙරුවන් සරණයි!