Spring Boot Consul Tutorial Sinhala | Service Discovery and Centralized Configuration

Spring Boot Consul Tutorial Sinhala | Service Discovery and Centralized Configuration

මයික්‍රෝ සර්විසස් (Microservices) ගැන කතා කරනකොට, සර්විස් (services) ගොඩක් එක්ක වැඩ කරන එක අභියෝගාත්මකයි නේද? සර්විස් ටික එකිනෙකා හොයාගන්නේ කොහොමද? එහෙමත් නැත්නම් හැම සර්විස් එකකටම වෙන වෙනම configuration management කරන්නේ නැතුව, එක තැනකින් ඒවා control කරන්නේ කොහොමද? මේ වගේ ප්‍රශ්න වලට උත්තර තමයි සර්විස් ඩිස්කවරි (Service Discovery) සහ සෙන්ට්‍රලයිස්ඩ් කන්ෆිගරේෂන් (Centralized Configuration) කියන්නේ. මේ ප්‍රශ්න වලට තියෙන හොඳම විසඳුමක් තමයි HashiCorp Consul.

අද අපි මේ tutorial එකෙන්, Spring Boot application එකක් Consul එක්ක කොහොමද වැඩ කරන්නේ කියලා පියවරෙන් පියවර ඉගෙන ගනිමු. විශේෂයෙන්ම, Service Discovery සහ Centralized Configuration කියන අංග දෙක ගැන අපි ගැඹුරින් කතා කරනවා. ඔයා දැනටමත් Spring Boot එක්ක වැඩ කරන කෙනෙක් නම්, මේක ඔයාගේ දැනුමට හොඳ addition එකක් වේවි!

සර්විස් ඩිස්කවරි (Service Discovery) සහ කොන්සල් (Consul) කියන්නේ මොනවද?

සර්විස් ඩිස්කවරි (Service Discovery)

මයික්‍රෝ සර්විසස් ආකෘතියක (architecture) දී, අපිට service instances ගොඩක් තියෙන්න පුළුවන්. උදාහරණයක් විදියට, User Service එකට Order Service එකේ function එකක් call කරන්න ඕනේ කියලා හිතමු. සාමාන්‍ය විදියට නම්, Order Service එකේ IP address එකයි, Port එකයි අපිට User Service එකේ hardcode කරන්න වෙනවා. නමුත්, Order Service එකේ IP එක වෙනස් වුනොත්, එහෙමත් නැත්නම් අලුත් instance එකක් add වුනොත් මොකද වෙන්නේ? හැම වෙලේම code එක වෙනස් කරන්න බැහැනේ?

මේකට විසඳුම තමයි Service Discovery. Service Discovery කියන්නේ, client application වලට, තමන්ට අවශ්‍ය service instances වල network locations (IP, Port) dynamically හොයාගන්න පුළුවන් කරන mechanism එකක්. මේක ප්‍රධාන වශයෙන් කොටස් දෙකකට බෙදෙනවා:

  • Service Registration: Services (ඔයාගේ Spring Boot application) තමන්ව Service Registry එකේ register කරනවා.
  • Service Lookup: Clients (ඒ කියන්නේ වෙනත් services) Service Registry එකෙන් තමන්ට අවශ්‍ය services වල locations ඉල්ලගන්නවා.

කොන්සල් (Consul)

Consul කියන්නේ HashiCorp ආයතනය විසින් හදපු, distribute වුන, highly available tool එකක්. මේක ප්‍රධාන වශයෙන්ම Service Discovery, Health Checking, Key/Value Store (KV Store) සහ Multi-Datacenter Federation වගේ දේවල් වලට පාවිච්චි කරනවා.

Consul වල Service Discovery කියන feature එක තමයි අපි මේකේදී වැඩියෙන්ම focus කරන්නේ. අපේ Spring Boot application එක Consul එකට register කරලා, වෙනත් applications වලට ඒක හොයාගන්න පුළුවන් විදියට අපි හදමු.

ඇයි Spring Boot එක්ක Consul පාවිච්චි කරන්නේ?

Spring Boot කියන්නේ Java එකේ microservices හදන්න තියෙන ජනප්‍රියම framework එකක්. ඒ වගේම Spring Cloud කියන්නේ Spring Boot application වලට cloud-native features එකතු කරන්න හදපු project collection එකක්. Spring Cloud එකේ Spring Cloud Consul කියන module එකෙන්, Spring Boot application එකක් Consul එක්ක ඉතා පහසුවෙන් integrate කරන්න පුළුවන්.

මේකෙන් ලැබෙන වාසි:

  • සරල බව: Spring Boot application එකක් Consul එක්ක register කරන එක ඉතාම සරලයි. අර පොඩි dependency ටිකක් add කරලා properties ටිකක් configure කලාම වැඩේ හරි.
  • ගතිකත්වය (Dynamism): Services add වෙනකොට හෝ remove වෙනකොට, clients වලට ඒ බව දැනගෙන, අලුත් instances එක්ක වැඩ කරන්න පුළුවන්.
  • මධ්‍යගත Configuration (Centralized Configuration): Consul වල තියෙන Key/Value Store එක පාවිච්චි කරලා, අපිට අපේ application වල configuration properties එක තැනකින් manage කරන්න පුළුවන්. Application එක redeploy නොකරම runtime එකේදී පවා configuration update කරන්න පුළුවන් හැකියාවකුත් තියෙනවා.
  • Health Checks: Consul වලට පුළුවන් services වල health check කරන්න. අසනීප (unhealthy) service instances automatic remove කරන්න මේක උදව් වෙනවා.

කොන්සල් සෙටප් කරගමු (Setting Up Consul)

අපේ Spring Boot application එක Consul එක්ක වැඩ කරන්න නම්, අපිට Consul agent එකක් run වෙන්න ඕනේ. මේක local machine එකේම run කරන්න පුළුවන්, නැත්නම් remote server එකක run කරන්න පුළුවන්.

ලෝකල් සෙටප් එක (Local Setup)

Consul local machine එකේ run කරන්න තියෙන පහසුම ක්‍රමය තමයි Docker පාවිච්චි කරන එක. ඔයාගේ machine එකේ Docker install කරලා නැත්නම්, මුලින්ම ඒක install කරගන්න.

terminal එක open කරලා මේ command එක run කරන්න:

docker run -d --name consul -p 8500:8500 -p 8600:8600/udp consul agent -dev -client 0.0.0.0

මේ command එකෙන් වෙන්නේ Consul agent එක developer mode (-dev) එකේ run කරන එක. ඒ වගේම 8500 port එකෙන් Consul UI එකට access කරන්න පුළුවන්. http://localhost:8500 කියලා browser එකේ ගහලා Consul UI එක බලන්න පුළුවන්.

ඔයාගේ machine එකේ Docker නැත්නම්, Consul binary එක download කරලා run කරන්නත් පුළුවන්. විස්තර මේ ලින්ක් එකෙන් බලන්න පුළුවන්: https://developer.hashicorp.com/consul/downloads.

Spring Boot එක්ක කොන්සල් සර්විස් ඩිස්කවරි වලට සම්බන්ධ කරමු

දැන් අපි බලමු Spring Boot application එකක් Consul Service Registry එකේ register කරන්නේ කොහොමද කියලා.

පියවර 1: Dependencies Add කරමු

ඔයාගේ pom.xml file එකට පහත dependencies එකතු කරන්න. (ඔයා Maven පාවිච්චි කරනවා නම්):

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId> <!-- Required for Spring Cloud config in older versions, good practice for consistency -->
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId> <!-- For health checks -->
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.1</version> <!-- Replace with your Spring Cloud version (e.g., 2023.0.0 for Spring Boot 3.x) -->
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Note: spring-cloud-dependencies version එක ඔයාගේ Spring Boot version එකට ගැලපෙන විදියට දාන්න. (උදා: Spring Boot 2.x වලට 2021.0.x, Spring Boot 3.x වලට 2022.0.x හෝ 2023.0.x).

පියවර 2: Application Properties Configure කරමු

දැන් src/main/resources/application.yml (හෝ application.properties) file එකට පහත configuration එකතු කරන්න:

spring:
  application:
    name: my-spring-consul-service
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        instance-id: ${spring.application.name}:${random.value}
        health-check-path: /actuator/health
        health-check-interval: 10s
        prefer-ip-address: true # Recommended for Docker/cloud environments
management:
  endpoints:
    web:
      exposure:
        include: 'health' # Expose health endpoint for Consul health checks
  • spring.application.name: මේක තමයි ඔයාගේ service එක Consul එකේ register වෙන්නේ මේ නමින්.
  • spring.cloud.consul.host සහ port: Consul agent එක run වෙන location එක. අපි local machine එකේ 8500 port එකේ run කරන නිසා localhost:8500.
  • discovery.instance-id: Consul එකේ service instance එක identify කරන්න unique ID එකක්. ${random.value} එකතු කරේ service එකේ multiple instances run කරනකොට conflict නොවෙන්න.
  • health-check-path: Spring Boot Actuator health endpoint එක. Consul මේක පාවිච්චි කරලා service එක active ද කියලා check කරනවා.
  • health-check-interval: කොච්චර වෙලාවකට සැරයක්ද health check එක කරන්න ඕනේ කියලා.
  • prefer-ip-address: සමහර environments වල hostname එක වෙනුවට IP address එකෙන් register කරන එක හොඳයි.
  • management.endpoints.web.exposure.include: 'health': Consul health check කරන්න /actuator/health endpoint එක expose කරන්න ඕනේ.

පියවර 3: සරල REST Controller එකක් හදමු

දැන් අපි සරල Spring Boot application එකක් හදලා බලමු. MySpringConsulServiceApplication.java file එකට මේ code එක දාන්න:

package com.example.consuldemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@RestController
@EnableDiscoveryClient // This annotation enables service discovery
public class MySpringConsulServiceApplication {

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

    @GetMapping("/hello")
    public String helloConsul() {
        return "Hello from my-spring-consul-service!";
    }
}

අමතක කරන්න එපා @EnableDiscoveryClient annotation එක add කරන්න. මේක තමයි Spring Cloud එකට කියන්නේ මේ application එක service discovery client කෙනෙක් විදියට වැඩ කරන්න ඕනේ කියලා.

දැන් application එක run කරන්න. mvn spring-boot:run command එකෙන් හෝ IDE එකෙන් run කරන්න පුළුවන්. Application එක start වුනාට පස්සේ, http://localhost:8500 ගිහින් Consul UI එකේ Services tab එක බලන්න. ඔයාගේ my-spring-consul-service කියන service එක green පාටින් දැක්කොත්, ඒ කියන්නේ ඒක Consul එකේ successfully register වෙලා කියලා.

ඔයාගේ browser එකේ http://localhost:8080/hello (Spring Boot default port එක 8080 නම්) ගිහින් බලන්න පුළුවන් application එක වැඩ කරනවද කියලා.

කොන්සල් සෙන්ට්‍රලයිස්ඩ් කන්ෆිගරේෂන් වලට පාවිච්චි කරමු

Consul වල තියෙන Key/Value Store (KV Store) එක, අපේ application වල configuration properties manage කරන්න පුළුවන් ඉතාම බලවත් feature එකක්. මේකෙන් අපිට application restart නොකරම configuration update කරන්න පවා පුළුවන්.

පියවර 1: Configuration Dependencies Add කරමු

pom.xml file එකට පහත dependency එකතු කරන්න:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId> <!-- For refreshing configuration -->
</dependency>

spring-boot-starter-actuator dependency එක එකතු කරේ runtime එකේදී configuration refresh කරන්න අවශ්‍ය tools ටික ලබා ගන්න.

පියවර 2: bootstrap.yml Configure කරමු

Spring Cloud Config client එකට application properties load කරන්න කලින් Consul එක්ක සම්බන්ධ වෙන්න අවශ්‍යයි. ඒ නිසා අපි application.yml එකට කලින් load වෙන bootstrap.yml file එකක් හදනවා (src/main/resources/ folder එකේ). Spring Boot 2.4+ වලදී bootstrap.yml වෙනුවට application.yml එකේම spring.config.import යොදා ගන්න පුළුවන් වුණත්, Consul config වලට bootstrap.yml තවමත් පොදු භාවිතයක්.

spring:
  application:
    name: my-spring-consul-service
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        enabled: true
        prefix: config
        default-context: application
        profile-specific-contexts: true # Load config based on active profile (e.g., config/my-spring-consul-service, config/my-spring-consul-service,development)
management:
  endpoints:
    web:
      exposure:
        include: 'health,refresh' # Expose refresh endpoint for config updates
  • config.enabled: true: Consul Configuration enable කරනවා.
  • prefix: config: Consul KV store එකේ config properties තියෙන root path එක. (උදා: config/my-spring-consul-service/my.property)
  • default-context: application: මේකෙන් කියන්නේ config/application කියන path එකේ තියෙන config load කරන්න කියලා.
  • profile-specific-contexts: true: මේකෙන් enables වෙනවා profile-specific configurations load කරන්න (උදා: config/my-spring-consul-service,development/my.property).
  • management.endpoints.web.exposure.include: 'health,refresh': configuration refresh කරන්න /actuator/refresh endpoint එක expose කරන්න ඕනේ.

පියවර 3: Consul KV Store එකට Configuration එකතු කරමු

Consul UI එකට (http://localhost:8500) ගිහින් Key/Value tab එකට යන්න. මෙතන තමයි අපි අපේ config properties add කරන්නේ.

config/my-spring-consul-service/message කියලා Key එකක් හදලා, Value එකට "Hello from Consul Configuration!" කියලා දාන්න. Remember, Keys are paths, and values are strings.

ඔයා profile-specific-contexts: true enable කරලා තියෙන නිසා, config/my-spring-consul-service,development/message වගේ key එකක් හදලා development environment එකට විතරක් වෙනස් value එකක් දෙන්නත් පුළුවන්.

පියවර 4: Application එකෙන් Configuration Access කරමු

දැන් අපිට MySpringConsulServiceApplication.java එකේ මේ message property එක access කරන්න පුළුවන්. @Value annotation එක පාවිච්චි කරමු.

package com.example.consuldemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope; // For dynamic refresh

@SpringBootApplication
@RestController
@EnableDiscoveryClient
@RefreshScope // Allows configuration to be refreshed at runtime
public class MySpringConsulServiceApplication {

    @Value("${message:Default Message}") // Default value if not found in Consul
    private String message;

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

    @GetMapping("/hello")
    public String helloConsul() {
        return "Hello from my-spring-consul-service! " + message;
    }

    @GetMapping("/config")
    public String getConfig() {
        return "Current message from Consul: " + message;
    }
}

මෙහි @RefreshScope annotation එක ඉතා වැදගත්. මේකෙන් වෙන්නේ Consul වල configuration එක update වුනොත්, application එක restart නොකරම, අලුත් values reload කරගන්න පුළුවන් වෙන එක. නමුත් මේක automatic වෙන්නේ නැහැ. අපිට /actuator/refresh endpoint එකට POST request එකක් යවන්න ඕනේ.

Configuration Refresh කරමු

ඔයාගේ application එක run කරලා, http://localhost:8080/config (හෝ ඔයාගේ port එක) access කරලා message එක බලන්න. දැන් Consul UI එකට ගිහින් config/my-spring-consul-service/message කියන key එකේ value එක වෙනස් කරන්න. (උදා: "Updated message from Consul!").

දැන් ආයෙත් http://localhost:8080/config access කලොත්, තාම පරණ message එකම පෙනේවි. ඒක update කරන්න අපි refresh කරන්න ඕනේ.

terminal එක open කරලා මේ curl command එක run කරන්න:

curl -X POST http://localhost:8080/actuator/refresh

මේකෙන් Actuator refresh endpoint එකට request එකක් යනවා. ඒ request එක ගියාට පස්සේ, Spring Cloud Consul config client එක Consul KV store එකෙන් අලුත් values load කරගෙන, @RefreshScope annotations තියෙන beans update කරනවා.

දැන් ආයෙත් http://localhost:8080/config access කලොත්, අලුත් message එක ("Updated message from Consul!") පෙනේවි. Application එක restart නොකරම config update වුනා නේද? මේක තමයි Centralized Configuration වල තියෙන ලොකුම වාසියක්!

අවසන් වශයෙන් (Conclusion)

අද අපි Spring Boot applications Consul එක්ක Service Discovery සහ Centralized Configuration කරන්නෙ කොහොමද කියලා විස්තරාත්මකව ඉගෙන ගත්තා. මේකෙන් ඔයාගේ microservices වල maintainability එකයි, scalability එකයි, reliability එකයි ගොඩක් වැඩි වෙනවා.

  • Service Discovery එකෙන් services වලට එකිනෙකා පහසුවෙන් හොයාගන්න පුළුවන් බව.
  • Centralized Configuration එකෙන් configuration management එක සරල කරගන්න පුළුවන් බව.
  • Consul KV Store එක පාවිච්චි කරලා runtime එකේදී config update කරන්න පුළුවන් බව.

මේ concepts ගැන හොඳ අවබෝධයක් ලැබුනා කියලා මම හිතනවා. ඔයාගේ ඊළඟ Spring Boot microservices project එකේදී මේක implement කරලා බලන්න. මොකද, theory දැනගෙන ඉන්නවට වඩා, practical experience එක තමයි වැදගත්! මොනවා හරි ප්‍රශ්න තියෙනවා නම්, පහළින් comment කරන්න. අපි කතා කරමු!

තවත් අලුත් දෙයක් එක්ක ඉක්මනින්ම හමුවෙමු! Happy Coding!