Spring Boot Consul Tutorial Sinhala | Service Discovery Config Sri Lanka

Spring Boot Consul Tutorial Sinhala | Service Discovery Config Sri Lanka

Spring Boot with Consul: Service Discovery & Configuration Sinhala Guide

ආයුබෝවන් යාළුවනේ! අද අපි කතා කරන්නේ නවීන Software Development ලෝකයේ ගොඩක් වැදගත් මාතෘකාවක් ගැන. ඒ තමයි Spring Boot එක්ක Consul පාවිච්චි කරලා Microservices හොඳට Manage කරගන්න විදිය. මේක ගොඩක් දෙනෙක්ට තියෙන ගැටලුවක්, ඒ වගේම ඕනෑම විශාල Application එකකට අත්‍යවශ්‍ය දෙයක්. ඉතින් අපි බලමු මේ දෙන්නා එකට වැඩ කරන්නේ කොහොමද කියලා.

අද අපි මේ Guide එකෙන් මොනවද ඉගෙන ගන්නේ?

  • Consul කියන්නේ මොකක්ද? ඇයි අපිට ඒක ඕනේ?
  • Service Discovery කියන්නේ මොකක්ද සහ Consul ඒකට උදව් කරන්නේ කොහොමද?
  • Distributed Configuration කියන්නේ මොකක්ද සහ Consul ඒකට සහයෝගය දෙන්නේ කොහොමද?
  • අපේ Spring Boot Application එක Consul එකට Register කරන්නේ කොහොමද? (Practical Example!)
  • තව Microservice එකක් හොයාගෙන ඒකට Connect වෙන්නේ කොහොමද?
  • Consul එකෙන් Configuration Load කරගන්නේ කොහොමද?

මේ හැමදේම අපි ලංකාවේ අපිට තේරෙන විදියට සරලව කතා කරමු. එහෙනම්, අපි පටන් ගමු!

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

ඉතින්, Consul කියන්නේ HashiCorp කියන සමාගමෙන් හදපු Service Mesh එකක්. ඒක මූලිකවම Microservices Architecture එකක තියෙන සේවාවන් (services) කළමනාකරණය කරන්න උදව් වෙනවා. නිකමට හිතන්න, අපේ ගෙදර තියෙන phones, TVs, laptops හැම එකටම ඒගොල්ලන්ගේම IP addresses තියෙනවා නේද? දැන් මේවා අතර කතා බහ කරන්න නම්, එකක් අනිකාගේ IP එක දැනගෙන ඉන්න ඕනේ.

Microservices වලදීත් මේක ඒ වගේම තමයි. අපිට සේවාවන් දහයක්, විස්සක්, සමහරවිට සිය ගණනක් තියෙන්න පුළුවන්. මේ හැම සේවාවක්ම Start වෙනකොට වෙනස් IP එකක්, වෙනස් Port එකක් ගන්න පුළුවන්. එතකොට, User Service එකට Order Service එකට කතා කරන්න ඕනේ නම්, Order Service එකේ IP එක සහ Port එක කොහොමද දැනගන්නේ? මෙතන තමයි Consul වගේ Service Discovery Tool එකක වැදගත්කම තියෙන්නේ.

Consul වල ප්‍රධාන Features කිහිපයක් තියෙනවා:

  1. Service Discovery: මේක තමයි ප්‍රධානම feature එක. අලුතින් deploy කරන හැම service එකක්ම Consul එකේ Register වෙනවා. ඒ වගේම, තව service එකකට වෙන service එකක් ඕනේ වුනාම, Consul එකෙන් ඒක හොයාගන්න පුළුවන්. IP addresses හෝ Ports ගැන කරදර වෙන්න ඕනේ නෑ.
  2. Health Checking: Consul එකට පුළුවන් Register වෙලා තියෙන services Alive ද කියලා check කරන්න. මොකක් හරි service එකක් down වුනොත්, Consul එකට ඒක අඳුරගන්න පුළුවන්. එතකොට, dead service එකකට requests යවන එක නවත්වන්න පුළුවන්.
  3. Key-Value Store (Distributed Configuration): Consul එකේ තියෙනවා Global Key-Value Store එකක්. අපිට පුළුවන් Common Configurations, Feature Flags වගේ දේවල් මේකේ තියාගන්න. එතකොට, අපේ Microservices වලට මේ configurations dynamic විදියට load කරගන්න පුළුවන්. එක තැනකින් හැමදේම manage කරන්න පුළුවන්.
  4. Multi Datacenter: Consul එකට පුළුවන් දත්ත මධ්‍යස්ථාන කිහිපයක් හරහා වැඩ කරන්න, Global Architectures වලට ගොඩක් වැදගත්.

Spring Boot & Consul එකට ගලපමු (Integrating Spring Boot & Consul)

දැන් අපි බලමු Spring Boot Application එකක් Consul එක්ක සම්බන්ධ කරගන්නේ කොහොමද කියලා. මේකට අපිට Spring Cloud Consul කියන Project එක උදව් වෙනවා.

පියවර 1: අවශ්‍ය Dependencies එකතු කරගමු (Add Dependencies)

අපේ pom.xml (Maven නම්) හෝ build.gradle (Gradle නම්) ෆයිල් එකට මේ dependencies එකතු කරන්න ඕනේ. මම මෙතන Maven උදාහරණය පාවිච්චි කරනවා.


<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>

මේ dependencies දෙකට අමතරව, Spring Cloud dependencies ටිකත් තියෙන්න ඕනේ. ඒක spring-cloud-dependencies BOM එකෙන් manage කරන්න පුළුවන්. මේක ඔබේ pom.xml එකේ dependencyManagement section එකට දාන්න:


<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2023.0.0</version> <!-- ඔබේ Spring Cloud version එකට අනුව වෙනස් කරන්න -->
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

පියවර 2: Spring Boot Application එක Consul එකට Register කරමු (Register Application with Consul)

දැන් අපේ Application එක Consul එකට Register කරන්න application.yml (හෝ application.properties) ෆයිල් එකේ පහත Settings එකතු කරන්න ඕනේ. මේක සාමාන්‍යයෙන් src/main/resources ෆෝල්ඩර් එකේ තියෙනවා.


spring:
  application:
    name: my-first-service # ඔබේ සේවාවේ නම
  cloud:
    consul:
      host: localhost # Consul Server එකේ IP එක/Host එක. Local නම් localhost
      port: 8500 # Consul Server එකේ Port එක
      discovery:
        instance-id: ${spring.application.name}:${random.value} # සේවාවේ unique ID එක
        prefer-ip-address: true # IP Address එක Use කරන්න
        health-check-interval: 10s # Consul එක සේවාව check කරන වාර ගණන
        health-check-path: /actuator/health # සේවාවේ health endpoint එක
server:
  port: 8081 # ඔබේ සේවාව Run වෙන Port එක

management:
  endpoints:
    web:
      exposure:
        include: 'health' # Health endpoint එක expose කරන්න

වැදගත්: ඔබ Consul Server එකක් run කරලා තියෙන්න ඕනේ. Local Environment එකේ නම්, Docker පාවිච්චි කරලා පහසුවෙන් run කරගන්න පුළුවන්:


docker run -d --name consul -p 8500:8500 consul

දැන් ඔබේ Spring Boot Application එක run කරන්න. Application එක start වුනාම, Consul UI එක (http://localhost:8500) එකට ගිහින් බලන්න පුडवन, ඔබේ my-first-service කියන සේවාව එහි Register වෙලා තියෙනවාද කියලා. එහෙමනම්, වැඩේ සාර්ථකයි!

Service Discovery - සේවාවන් හොයාගමු (Finding Services)

අපේ my-first-service එක Consul එකට Register වුනාට පස්සේ, වෙනත් සේවාවකට මේක හොයාගන්න පුළුවන්. උදාහරණයක් විදියට, my-second-service කියන සේවාවට my-first-service එකට කතා කරන්න ඕනේ නම්, ඒකට Consul එකෙන් my-first-service එකේ IP එක සහ Port එක හොයාගන්න පුළුවන්.

මේකට Spring Cloud එකේ තියෙන DiscoveryClient Interface එක පාවිච්චි කරන්න පුළුවන්. නැත්නම්, Load-Balanced RestTemplate/WebClient එකක් හදාගන්නත් පුළුවන්.

උදාහරණය: DiscoveryClient පාවිච්චි කරලා Service එකක් හොයාගමු

මුලින්ම, ඔබේ client service එකටත් spring-cloud-starter-consul-discovery dependency එක එකතු කරලා, application.yml එකේ Consul Host/Port ටික configure කරන්න.

දැන්, ඔබට මෙහෙම Controller එකක් හදාගන්න පුළුවන්:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class DiscoveryController {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/services")
    public String getServices() {
        StringBuilder sb = new StringBuilder();
        // Consul එකෙන් my-first-service එකේ instances හොයාගන්නවා
        List<ServiceInstance> instances = discoveryClient.getInstances("my-first-service");

        if (instances != null && !instances.isEmpty()) {
            sb.append("Found instances of 'my-first-service':\n");
            for (ServiceInstance instance : instances) {
                sb.append("Host: ").append(instance.getHost())
                  .append(", Port: ").append(instance.getPort())
                  .append(", URI: ").append(instance.getUri())
                  .append("\n");
            }
        } else {
            sb.append("No instances of 'my-first-service' found.");
        }
        return sb.toString();
    }

    // Load-Balanced RestTemplate/WebClient
    @Autowired(required = false)
    private RestTemplate restTemplate; // Spring Boot 2.x වලට

    @Autowired(required = false)
    private WebClient.Builder webClientBuilder; // Spring Boot 3.x වලට

    @GetMapping("/call-first-service")
    public String callFirstService() {
        // RestTemplate (පැරණි ක්‍රමය)
        // String response = restTemplate.getForObject("http://my-first-service/hello", String.class);

        // WebClient (නවීන ක්‍රමය)
        if (webClientBuilder != null) {
            return webClientBuilder.build().get()
                    .uri("http://my-first-service/hello") // Service ID එක ನೇರವಾಗಿ දෙන්න පුළුවන්
                    .retrieve()
                    .bodyToMono(String.class)
                    .block();
        } else if (restTemplate != null) {
            return restTemplate.getForObject("http://my-first-service/hello", String.class);
        } else {
            return "No suitable HTTP client found.";
        }
    }
}

@LoadBalanced ඇනෝටේෂන් එක RestTemplate හෝ WebClient.Builder එකට එකතු කිරීමෙන් Spring Cloud එකට පුළුවන් Consul එකෙන් සේවාවන් හොයාගෙන, ඒවා අතරට requests Load Balance කරන්න. මේකට, ඔබේ Main Application Class එකේ @EnableDiscoveryClient ඇනෝටේෂන් එකත් දාන්න අමතක කරන්න එපා. ඒ වගේම RestTemplate එක Bean එකක් විදියට හදාගන්න ඕනේ:


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;

@SpringBootApplication
@EnableDiscoveryClient // මේක වැදගත්
public class MySecondServiceApplication {

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

    @Bean
    @LoadBalanced // මේක වැදගත්
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    @LoadBalanced // WebClient පාවිච්චි කරනවා නම්
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}

දැන් my-first-service එකේ /hello කියලා Endpoint එකක් තියෙනවා නම්, my-second-service එකේ /call-first-service endpoint එකට request එකක් යැව්වම, ඒක සාර්ථකව my-first-service එකට requests යවයි.

Distributed Configuration - සැකසුම් බෙදාගමු (Sharing Configurations)

Consul එකේ තියෙන Key-Value Store එක Configuration Management වලට ගොඩක් ප්‍රයෝජනවත්. Microservices ගොඩක තියෙන Common configurations (උදා: Database credentials, API Keys, Feature Flags) එක තැනකින් manage කරන්න මේකෙන් පුළුවන්. ඒ වගේම, Application එක Restart නොකරම Configurations update කරන්නත් පුළුවන්.

පියවර 1: Consul Key-Value Store එකට Configuration එකතු කරමු

මුලින්ම, Consul UI එකට (http://localhost:8500) ගිහින් Key-Value ටැබ් එකට යන්න. මෙතනදී ඔබට Keys හදාගන්න පුළුවන්. Spring Cloud Consul Config එකෙන් Configurations Load කරන්නේ config/application/ හෝ config/your-service-name/ වගේ Path එකකින්.

අපේ my-first-service එකට Configuration එකක් දාමු. Key එක config/my-first-service/message කියලා දීලා, Value එක "Hello from Consul Config!" කියලා දෙන්න.


Key: config/my-first-service/message
Value: Hello from Consul Config!

පියවර 2: Spring Boot Application එකෙන් Consul Config Load කරගමු

ඔබේ my-first-service Application එකේ application.yml ෆයිල් එකේ, පහත Settings එකතු කරන්න (spring-cloud-starter-consul-config dependency එක තියෙන්න ඕනේ).


spring:
  application:
    name: my-first-service
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        enabled: true # Consul Config enable කරනවා
        prefix: config # Consul KV Store එකේ root path එක
        data-key: data # Default data key එක (optional)

# ... අනිත් settings ...

prefix: config කියන්නේ Consul KV Store එකේ config/ කියන path එකෙන් configurations Load කරන්න කියලා. data-key: data කියන්නේ config/your-service-name/data වගේ path එකකින් configurations ගන්න කියලා. මේකෙන් පුළුවන් data: { message: "..." } වගේ YAML ව්‍යුහයක් KV Store එකේ තියන්න. අපි දැන් කෙලින්ම config/my-first-service/message කියලා හදපු නිසා data-key එක අත්‍යවශ්‍ය නැහැ, නමුත් complex configs වලට මේක ප්‍රයෝජනවත්.

දැන් Application එකේ Controller එකක මේ Value එක Access කරන්න පුළුවන් @Value ඇනෝටේෂන් එක පාවිච්චි කරලා:


import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyServiceController {

    // Consul KV Store එකෙන් එන message එක @Value එකෙන් ගන්නවා
    @Value("${message:Default Message}") 
    private String consulMessage;

    @GetMapping("/hello")
    public String hello() {
        return "Hello from My First Service! Config Message: " + consulMessage;
    }
}

දැන් my-first-service එක run කරලා /hello endpoint එකට යන්න. ඔබට Consul එකෙන් එන Message එක පෙනෙයි. ඊට පස්සේ, Consul UI එකේ Key එකේ Value එක වෙනස් කරලා බලන්න. (උදා: "Updated Message from Consul!"). Application එක refresh කරන්න (/actuator/refresh endpoint එකට POST request එකක් යවන්න පුස්තකලා නම්) නැත්නම් ටික වෙලාවකින් Automatically update වෙන්නත් පුළුවන්.

නිගමනය (Conclusion)

ඉතින් යාළුවනේ, අපි මේ Spring Boot with Consul Sinhala Guide එකෙන් Microservices Architecture එකක තියෙන ප්‍රධානම ගැටලු දෙකක් විසඳගන්න පුළුවන් විදියක් ගැන ඉගෙන ගත්තා. ඒ තමයි Service Discovery සහ Distributed Configuration. Consul කියන්නේ මේ සඳහා තියෙන ගොඩක් බලවත්, Open Source Tool එකක්.

ඔබගේ Application එකේ Microservices ගණන වැඩිවෙද්දී, මේ වගේ Tool එකක් අත්‍යවශ්‍ය වෙනවා. Spring Cloud Consul එකෙන් මේ integration එක ගොඩක් පහසු කරලා තියෙනවා. මේක මම කියපු විදියටම ඔබේ Project එකක Try කරලා බලන්න. අතින් කරද්දී තමයි ගොඩක් දේවල් පැහැදිලි වෙන්නේ.

ඔබට මේ Tutorial එකෙන් අලුත් දෙයක් ඉගෙන ගන්න ලැබුණා නම්, අනිවාර්යයෙන්ම පහතින් Comment එකක් දාලා යන්න. ඒ වගේම, මේ ගැන තියෙන ප්‍රශ්න හෝ අදහස් Share කරන්නත් පුළුවන්. ඔබේ අත්දැකීම් ගැන දැනගන්න අපි කැමතියි!

එහෙනම්, තවත් අලුත් Tutorial එකකින් හමුවෙමු! සුභ දවසක්!