Spring Cloud Bus Sinhala: Microservices වල Config Updates පහසුවෙන් කරන්න

Spring Cloud Bus Sinhala: Microservices වල Config Updates පහසුවෙන් කරන්න

ආයුබෝවන්! Spring Boot Microservices වල Dynamic Configuration Updates ගැන Sinhala Guide එකක්!

ඉතින් කොහොමද ඔයාලට? අද අපි කතා කරන්නේ Spring Boot Microservices develop කරන ඔයාලා හැමෝටම ගොඩක් වැදගත් වෙන, කාලය ඉතුරු කර දෙන සහ headaches අඩු කර දෙන topic එකක් ගැන. ඒ තමයි Spring Cloud Bus. Microservices කියන්නේ අද දවසේ ගොඩක් දියුණු වෙමින් පවතින architecture pattern එකක්. ඒත්, Microservices ගොඩක් තියෙන project එකක configuration manage කරන එක ටිකක් අමාරු වැඩක් වෙන්න පුළුවන්.

හිතන්න, ඔයාගේ system එකේ Microservices 10ක් 20ක් තියෙනවා කියලා. මේ services වලින් එකක් හෝ කීපයක් share කරන පොදු configuration එකක පොඩි වෙනසක් කරන්න වුණොත්? සාමාන්‍යයෙන් වෙන්නේ, ඒ configuration එක use කරන හැම service එකක්ම restart කරන එක. මේක production environment එකකදී කරනවා කියන්නේ downtime එකක්. ඒක කවදාවත් හොඳ දෙයක් නෙවෙයි, නේද? අන්න ඒ වගේ අවස්ථාවලදී අපේ උදව්වට එන හරිම වැදගත් tool එකක් තමයි Spring Cloud Bus කියන්නේ.

මේ blog post එකෙන් අපි Spring Cloud Bus කියන්නේ මොකක්ද, ඒක කොහොමද වැඩ කරන්නේ, ඒක අපේ Spring Boot Project එකකට add කරගන්නේ කොහොමද, සහ practical විදියට configuration updates broadcast කරන්නේ කොහොමද කියලා පියවරෙන් පියවර බලමු. මේක කියෙව්වට පස්සේ ඔයාට ඔයාගේ Microservices වල configuration dynamic විදියට update කරන එක ගැන හොඳ අවබෝධයක් ලැබෙයි කියලා මට විශ්වාසයි.

Spring Cloud Bus කියන්නේ මොකක්ද?

සරලවම කිව්වොත්, Spring Cloud Bus කියන්නේ Spring Cloud ecosystem එකේ තියෙන component එකක්. මේකෙන් කරන්නේ distributed system එකක තියෙන nodes (අපේ Microservices) අතර configuration changes වගේ management events publish කරන එක. ඒ කියන්නේ, එක service එකක configuration එකක් වෙනස් වුණාම, ඒ වෙනස අනිත් හැම service එකක්ටම දැනුම් දෙන එක.

මේක හරියට පණිවිඩකරුවෙක් වගේ වැඩ කරනවා. ඒ පණිවිඩකරු පණිවිඩ (messages) යවන්න Message Broker එකක් (උදාහරණයක් විදියට RabbitMQ නැත්නම් Apache Kafka) භාවිතා කරනවා. Config server එකට configuration update එකක් ආවම, ඒක message broker එකට message එකක් යවනවා. ඊට පස්සේ, ඒ message broker එකට subscribe කරලා ඉන්න අනිත් services ටික ඒ message එක receive කරගෙන තමන්ගේ configuration update කරගන්නවා. මේක නිසා අපිට services restart නොකරම configuration changes effective කරන්න පුළුවන් වෙනවා.

Spring Cloud Bus වල ප්‍රධානම advantage එක තමයි configuration changes manual විදියට propagate කරනවා වෙනුවට automated විදියට කරන්න පුළුවන් වීම. මේක නිසා downtime එකක් නැතුව, ඒ කියන්නේ users ලට කිසිම බලපෑමක් නැතුව configuration updates කරන්න පුළුවන් වෙනවා.

Spring Cloud Bus Setup කරමු: පියවරෙන් පියවර

හරි, දැන් අපි බලමු කොහොමද Spring Cloud Bus අපේ Spring Boot Project එකකට add කරගන්නේ කියලා. මේක කරන්න අපිට මූලිකවම Spring Cloud Config Server එකක් සහ Message Broker එකක් (මේ උදාහරණය සඳහා අපි RabbitMQ භාවිතා කරමු) අවශ්‍ය වෙනවා. ඔයාට RabbitMQ locally install කරගන්න පුළුවන්. නැත්නම් Docker භාවිතා කරන්නත් පුළුවන්.

1. Config Server එක සකස් කිරීම

මුලින්ම අපි Spring Cloud Config Server එකක් හදාගනිමු. මේ Config Server එක තමයි අපේ applications වල configurations Git repository එකකින් read කරලා provide කරන්නේ.

Dependencies (pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>lk.scguide</groupId>
    <artifactId>config-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>config-server</name>
    <description>Demo config server for Spring Cloud Bus</description>

    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2023.0.1</spring-cloud.version> <!-- Make sure this matches your Spring Boot version -->
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId> <!-- For RabbitMQ -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId> <!-- For /actuator/bus-refresh endpoint -->
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Configuration (application.yml)

ඔබගේ Git repository එකක ඇති configurations වෙත යොමු වන පරිදි application.yml file එක සකස් කරන්න. ඔබට Git repository එකක් නොමැතිනම්, GitHub එකේ public repository එකක් හදාගෙන එහි config-data folder එකක් තුළ configurations තබන්න.

server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-username/your-config-repo.git # ඔබගේ Git repository URL එක මෙතනට දාන්න
          search-paths: config-data # Git repo එකේ config files තියෙන folder එක
          default-label: main # default branch එක
    bus:
      enabled: true
  rabbitmq:
    host: localhost
    port: 5672

management:
  endpoints:
    web:
      exposure:
        include: "*" # සියලුම actuator endpoints expose කරන්න (bus-refresh ඇතුළුව)
  endpoint:
    bus-refresh:
      enabled: true
    restart:
      enabled: true # Config server එකටම refresh කරන්න ඕනිනම් මේකත් enable කරන්න

Main Application Class

Config server එක enable කරන්න @EnableConfigServer annotation එක add කරන්න.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

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

2. Client Service එක සකස් කිරීම (Greeting Service)

දැන් අපි Config Server එකෙන් configuration read කරන client service එකක් හදාගනිමු. මේ service එකට තමයි dynamic configuration updates ලැබෙන්න ඕනේ.

Dependencies (pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>lk.scguide</groupId>
    <artifactId>greeting-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>greeting-service</name>
    <description>Demo greeting service for Spring Cloud Bus</description>

    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2023.0.1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId> <!-- To connect to Config Server -->
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId> <!-- For RabbitMQ -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId> <!-- For /actuator/refresh -->
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Configuration (bootstrap.yml)

Spring Cloud Config Client එක භාවිතා කරන විට, service එක Config Server එකට connect වෙන්න අවශ්‍ය මූලික configurations bootstrap.yml file එකේ තියෙන්න ඕනේ. මොකද මේ file එක application.yml එකට කලින් load වෙනවා.

spring:
  application:
    name: greeting-service # මේක තමයි Git repo එකේ configuration file නාමය වෙන්නේ (e.g., greeting-service.yml)
  cloud:
    config:
      uri: http://localhost:8888 # Config Server එකේ URL එක
      profile: dev # භාවිතා කරන profile එක (ඔබේ Git repo එකේ greeting-service-dev.yml තිබිය හැක)

Configuration (application.yml)

server:
  port: 8080

spring:
  rabbitmq:
    host: localhost
    port: 5672

management:
  endpoints:
    web:
      exposure:
        include: "*" # සියලුම actuator endpoints expose කරන්න (refresh, bus-refresh ඇතුළුව)
  endpoint:
    refresh:
      enabled: true # /actuator/refresh endpoint එක enable කරන්න
    bus-refresh:
      enabled: true # Client side bus-refresh enable කරන්න (අවශ්‍ය නම්)

Main Application Class සහ Controller

@RefreshScope annotation එක තමයි මේ වැඩේට ප්‍රධානම දේ. මේක Spring Cloud Bus මගින් configuration update එකක් ලැබුණු විට, ඒ bean එක refresh කරන්න සලස්වනවා. ඒ කියන්නේ, ඒ bean එකේ තියෙන @Value annotations වලින් read කරන values අලුතෙන් update වෙනවා.

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
@RefreshScope // මේක අනිවාර්යයි! Config update වුණාම bean එක refresh වෙන්න.
public class GreetingServiceApplication {

    @Value("${greeting.message:Default Greeting Message}")
    private String greetingMessage; // Git repo එකෙන් එන value එක මෙතනට load වෙනවා.

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

    @GetMapping("/greet")
    public String greet() {
        return "The greeting is: " + greetingMessage;
    }
}

3. Git Repository එකේ Configuration File එක

ඔබගේ Git repository එකේ (උදා: your-username/your-config-repo/config-data/) greeting-service.yml නමින් file එකක් සාදන්න (client service එකේ spring.application.name එකට ගැලපෙන නමින්).

greeting:
  message: "ආයුබෝවන් ලෝකයට! (මුල් පණිවිඩය)"

ප්‍රායෝගික උදාහරණයක්: Dynamic Configuration Updates

දැන් අපි බලමු මේ හැමදේම එකට වැඩ කරන්නේ කොහොමද කියලා.

පියවර 1: සියලුම Services ආරම්භ කරන්න

  1. RabbitMQ Server එක ආරම්භ කරන්න. (ඔබ Docker භාවිතා කරන්නේ නම්: docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management)
  2. Config Server එක ආරම්භ කරන්න. (ConfigServerApplication එක run කරන්න)
  3. Greeting Service එක ආරම්භ කරන්න. (GreetingServiceApplication එක run කරන්න)

පියවර 2: මුල් Configuration එක පරීක්ෂා කරන්න

ඔබගේ web browser එකේ http://localhost:8080/greet කියන URL එකට යන්න. ඔබට මෙවැනි output එකක් ලැබිය යුතුයි:

The greeting is: ආයුබෝවන් ලෝකයට! (මුල් පණිවිඩය)

පියවර 3: Git Repository එකේ Configuration එක වෙනස් කරන්න

දැන් ඔබගේ Git repository එකේ greeting-service.yml file එක update කරන්න. උදාහරණයක් ලෙස:

greeting:
  message: "සුභ දවසක්! Configuration එක දැන් update කර ඇත!"

වෙනස්කම් save කරලා Git repository එකට commit කරලා push කරන්න.

පියවර 4: Config Updates Broadcast කරන්න

දැන් අපි Spring Cloud Bus එක භාවිතා කරලා, මේ වෙනස්කම් අපේ Greeting Service එකට දැනුම් දෙමු. මේකට අපි Config Server එකේ /actuator/bus-refresh endpoint එකට POST request එකක් යවනවා. ඔබට මේක curl, Postman, නැත්නම් Insomnia වගේ tool එකක් භාවිතා කරලා කරන්න පුළුවන්.

curl -X POST http://localhost:8888/actuator/bus-refresh

මේ request එක යැව්වට පස්සේ, Config Server එක message broker (RabbitMQ) එක හරහා refresh event එකක් publish කරනවා. ඒ event එකට subscribe කරලා ඉන්න හැම client service එකක්ම (අපේ Greeting Service එක) ඒ event එක receive කරගෙන තමන්ගේ configuration refresh කරගන්නවා.

පියවර 5: Updated Configuration එක පරීක්ෂා කරන්න

දැන් ආයෙත් http://localhost:8080/greet කියන URL එකට යන්න. Service එක restart නොකරම ඔබට මෙවැනි output එකක් ලැබිය යුතුයි:

The greeting is: සුභ දවසක්! Configuration එක දැන් update කර ඇත!

ආශ්චර්යමත් නේද? මේක තමයි Spring Cloud Bus වල බලය! Service එක restart නොකරම configuration update වුණා.

ප්‍රයෝජන සහ සැලකිලිමත් විය යුතු දේවල්

Spring Cloud Bus වල ප්‍රයෝජන:

  • Zero Downtime Updates: Configuration changes නිසා Services restart කරන්න අවශ්‍ය නැහැ, ඒ නිසා system downtime අවම වෙනවා.
  • Simplified Configuration Management: Distributed systems වල configuration management කරන එක ගොඩක් පහසු කරනවා.
  • Scalability: නව service instances එකතු වුණත්, ඒ service වලටත් ඉතා ඉක්මනින් latest configuration එක ලබාගන්න පුළුවන්.
  • Consistency: සියලුම service instances වලට එකම, latest configuration එක ලැබෙන බව සහතික කරනවා.

සැලකිලිමත් විය යුතු දේවල්:

  • Message Broker Reliability: RabbitMQ හෝ Kafka වැනි message broker එකක් reliable විදියට ක්‍රියාත්මක වීම අනිවාර්යයි. ඒක නැතිනම් configuration updates broadcast වෙන්නේ නැහැ.
  • Security: /actuator/bus-refresh වැනි endpoints expose කරන විට, ඒවා නිසි ලෙස secure කර තිබිය යුතුයි. අනවසර ප්‍රවේශයන් වලක්වා ගැනීමට authentication සහ authorization layers එකතු කරන්න.
  • Complexity: කුඩා project එකක් සඳහා Spring Cloud Bus භාවිතා කිරීමෙන් අනවශ්‍ය complexity එකතු විය හැකියි. නමුත් විශාල, distributed systems වලට මෙය ඉතාම සුදුසුයි.

නිගමනය

ඉතින්, මේ Spring Cloud Bus කියන්නේ Microservices architecture එකේ configuration management කරන අයට ඉතාම ප්‍රයෝජනවත් tool එකක් බව දැන් ඔබට පැහැදිලි ඇති. Dynamic configuration updates, zero downtime, සහ පහසු scalable solutions මේකෙන් අපිට ලබාගන්න පුළුවන්. මේ Guide එකේ තියෙන පියවරවල් follow කරලා ඔයාලගේ project වලටත් Spring Cloud Bus එක add කරලා බලන්න.

මේ වගේ system එකක් deploy කරනකොට, Git repository එකේ version control එකත්, message broker එකේ stability එකත් ගැන අවධානයෙන් ඉන්න එක ගොඩක් වැදගත්. ඒ වගේම, security ගැනත් අමතක කරන්න එපා. Actuator endpoints අනිවාර්යයෙන්ම secure කරන්න.

ඔබට මේ ගැන තවත් ප්‍රශ්න තියෙනවා නම්, නැත්නම් මේක implement කරනකොට ගැටලුවක් ආවොත්, පහලින් comment කරන්න. ඔබේ අත්දැකීම් ගැනත් අපිට කියන්න! මේ වගේ තවත් Guides එක්ක අපි ආයෙත් ඉක්මනින්ම හමුවෙමු! සුභ දවසක්!