Spring Boot Microservices ගමන: ලංකාවේ Developers ලට Practical Guide එකක්

Spring Boot Microservices: Monolithic එකක් Microservices වලට කඩමු! SC Guide
ආයුබෝවන් යාළුවනේ! කොහොමද? අද අපි කතා කරන්න යන්නේ මේ දවස්වල Software Engineering ලෝකේ හරිම ජනප්රිය වෙලා තියෙන මාතෘකාවක් ගැන - ඒ තමයි Microservices. ඔයාලා දන්නවා ඇතිනේ, කාලෙකට කලින් අපි හැමෝම වගේ කරේ Monolithic Applications හදන එක. ඒ කියන්නේ අපේ මුළු Project එකම තනි බෝලයක් වගේ එක ගොඩට හදන එක. ඒත් දැන් එහෙම නෙමෙයි, ලොකු Systems හදනකොට හැමෝම වගේ යොමු වෙලා තියෙන්නේ Microservices Architecture එකට. විශේෂයෙන්ම Java Ecosystem එකේදී Spring Boot කියන්නේ මේ Microservices හදන්න තියෙන Super Tool එකක්. අද අපි බලමු, මේ සංකීර්ණ Microservices ලෝකේට Spring Boot වලින් කොහොම ලේසියෙන්ම ඇතුල් වෙන්නද කියලා. ඒ වගේම, ඔයාලගේ දැනට තියෙන Application එකක් කොහොමද Microservices වලට කඩන්නේ (Split කරන්නේ) කියලත් අපි පොඩ්ඩක් කතා කරමු. එහෙනම් අපි පටන් ගමු නේද?
මොකක්ද මේ Microservices කියන්නේ?
සරලවම කියනවා නම්, Microservices කියන්නේ අපේ ලොකු Application එක පොඩි පොඩි, ස්වාධීන කොටස් වලට කඩලා හදන ක්රමයක්. හරියට අපේ ගමේ තියෙන හැම අවශ්යතාවයකටම පොඩි පොඩි කඩ ටිකක් තියෙනවා වගේ. Grocery ගන්න එක කඩයක්, Bakery එකක් වෙනම, Hardware Shop එකක් වෙනම. හැම කඩයක්ම තමන්ගේ වැඩේ විතරක් කරනවා, ඒත් එකට එකතු වෙලා ගමට අවශ්ය හැම දෙයක්ම සපයනවා. මේක තමයි Monolithic Architecture එකෙන් වෙනස් වෙන්නේ. Monolithic වලදී නම් මේ හැම කඩේම එකම ලොකු Supermarket එකක වගේ තියෙන්නේ. හැම දෙයක්ම එක ගොඩේ.
Monolithic Architecture එකේ ප්රශ්න:
- ලොකු Codebase එකක් නිසා Maintain කරන්න අමාරුයි.
- පුංචි වෙනසක් කරන්නත් මුළු Application එකම Deploy කරන්න වෙනවා.
- එක කොටසක පොඩි Error එකක් ආවොත් මුළු System එකම Down වෙන්න පුළුවන්.
- Scalability එක කරන්න අමාරුයි – අපිට වැඩිපුර අවශ්ය වෙන්නේ එක Module එකකට විතරක් වුණත් මුළු Application එකම Scale කරන්න වෙනවා.
- අලුත් Technology එකක් Try කරන්න බැහැ. මුළු Application එකම එකම Technology එකක හිරවෙනවා.
Microservices වලින් ලැබෙන වාසි:
- Scalability: අපිට ඕන කරන Service එක විතරක් Scale කරන්න පුළුවන්. උදාහරණයක් විදියට, Order Service එකට විතරක් Request වැඩි නම්, ඒ Service එක විතරක් තව Instances දාලා Scale කරන්න පුළුවන්.
- Independent Deployment: එක Service එකක් වෙනස් කළාම අනිත් Services වලට බලපාන්නේ නැහැ. ඒ Service එක විතරක් Deploy කරන්න පුළුවන්.
- Technology Diversity: අපිට ඕන Service එකක් ඕනෑම Programming Language එකකින් හදන්න පුළුවන්. Java, Python, Go වගේ.
- Resilience: එක Service එකක් Fail වුණත් අනිත් Services වැඩ කරනවා. මුළු System එකම Down වෙන්නේ නැහැ.
- Easier to Understand and Maintain: Codebase එක කුඩා නිසා Developer කෙනෙකුට තේරුම් ගන්න, Maintain කරන්න පහසුයි.
අභියෝග (Challenges):
- Complexity: System එකක Components ගණන වැඩි වෙනවා. Manage කරන්න අමාරුයි.
- Distributed Debugging: Error එකක් ආවම හොයාගන්න අමාරුයි.
- Data Consistency: Data එක Services කිහිපයක් අතර බෙදී යන නිසා Data Consistency එක Maintain කරන එක අභියෝගයක්.
- Inter-service Communication: Services අතර Communication එක Manage කරන එක.
Spring Bootයි Microservicesයි - ඇයි මේ Combination එක Perfect?
Spring Boot කියන්නේ Microservices හදන්න දක්ෂම Tool එකක් කිව්වොත් වැරැද්දක් නැහැ. ඒකට හේතු කිහිපයක්ම තියෙනවා:
- Rapid Development: Spring Boot වල Auto-configuration, Starter dependencies වගේ දේවල් නිසා ඉක්මනින්ම Production ready Application එකක් හදාගන්න පුළුවන්. Boilerplate code ගොඩක් අඩුයි.
- Embedded Servers: Tomcat, Jetty වගේ Servers Built-in එන නිසා වෙනම Deploy කරන්න දෙයක් නැහැ. Jar file එකක් විදියට Run කරන්න පුළුවන්.
- Spring Cloud Ecosystem: මේක තමයි Microservices වලට Spring Boot කොච්චර වටිනවද කියලා තීරණය කරන ප්රධානම හේතුව. Spring Cloud කියන්නේ Microservices Architecture එකේදී එන ගොඩක් Challenges වලට Solutions දෙන Project set එකක්.
- Service Discovery (Eureka, Consul): Services එකිනෙකා හොයාගන්න උදව් කරනවා.
- API Gateway (Spring Cloud Gateway, Zuul): Clients ලට එකම Entry Point එකක් දෙනවා. Request Routing, Security වගේ දේවල් මෙතනදී Manage කරන්න පුළුවන්.
- Distributed Configuration (Spring Cloud Config): Services ගණනාවක් තියෙනකොට Configurations Manage කරන්න උදව් කරනවා.
- Load Balancing (Ribbon - Client side, or API Gateway): Request ටික Services අතර බෙදා හරින්න උදව් කරනවා.
- Circuit Breaker (Resilience4j): එක Service එකක් Fail වුණාම අනිත් Services වලට බලපාන්නේ නැතුව Maintain කරන්න උදව් කරනවා.
- Spring Security: Security implement කරන එක ඉතා පහසුයි.
- Integrations: Databases, Messaging Queues (Kafka, RabbitMQ) වගේ දේවල් එක්ක පහසුවෙන් Integrate කරන්න පුළුවන්.
මේ හැම දෙයක්ම නිසා Spring Boot කියන්නේ Microservices හදන Developer කෙනෙකුට ජීවිතේ ගොඩක් පහසු කරන Framework එකක්.
Project එකක් Microservices වලට කඩමු (Let's Split a Project into Microservices)
හරි, දැන් අපි බලමු මේ වැඩේ practical විදියට කරන්නේ කොහොමද කියලා. හිතමු අපිට තියෙනවා E-commerce Application එකක්. මේක දැනට තියෙන්නේ එක Monolithic Application එකක් විදියට. මේකේ Modules තියෙනවා Product, Order, User කියලා.
Monolithic E-commerce App එකේ Modules:
- Product Module: Products Add කරන, Update කරන, Delete කරන, View කරන Functions.
- Order Module: Orders Place කරන, Order Status Update කරන Functions.
- User Module: User Registration, Login, User Profiles Manage කරන Functions.
මේ Application එකට Customers ගොඩක් එනකොට, Order Module එකට විතරක් වැඩිපුර Load එකක් එනවා. ඒත් Monolithic නිසා මුළු Application එකම Scale කරන්න වෙනවා. දැන් අපි මේක Microservices වලට කඩමු.
Microservices වලට බෙදන ආකාරය:
සාමාන්යයෙන් Microservices වලට බෙදනකොට Business Domain එක අනුව බෙදනවා. ඒ කියන්නේ, Product වලට අදාළ හැම දේම Product Service එකට, Order වලට අදාළ හැම දේම Order Service එකට, User වලට අදාළ හැම දේම User Service එකට කියලා. මෙහෙම බෙදනකොට, ஒவ்வொரு Service එකක්ම තමන්ගේම Database එකක් තියාගන්න පුළුවන්. ඒක තමයි Best Practice එක.
අපේ Services ටික:
- Product Service:
- Products Manage කරයි. (Create, Read, Update, Delete)
- තමන්ගේම Product Database එකක් තියා ගනී.
- Order Service:
- Orders Manage කරයි. (Place Order, Update Status)
- Order එකක් Place කරනකොට Product Service එකෙන් Product Details ගන්න පුළුවන්.
- තමන්ගේම Order Database එකක් තියා ගනී.
- User Service:
- Users Manage කරයි. (Register, Login, Profile)
- තමන්ගේම User Database එකක් තියා ගනී.
- Service Discovery (Eureka Server):
- අනිත් Services ටික Register වෙන Server එක.
- Services එකිනෙකා හොයාගන්න උදව් කරනවා.
- API Gateway (Spring Cloud Gateway):
- Clients ලට එකම Entry Point එකක්.
- Incoming Requests ටික නිවැරදි Service එකට Route කරයි.
- Security, Rate Limiting වගේ දේවල් මෙතනින් කරන්න පුළුවන්.
Practical Step-by-Step (Simplified):
Step 1: Parent Project එකක් හදමු (Maven Multi-Module Project)
මුලින්ම අපේ Services ටිකට Parent Maven Project එකක් හදාගමු. මේකෙන් අපිට Dependencies Manage කරන එක පහසු වෙනවා.
<!-- pom.xml for parent project -->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>lk.scguide</groupId>
<artifactId>ecommerce-microservices</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>product-service</module>
<module>order-service</module>
<module>user-service</module>
<module>eureka-server</module>
<module>api-gateway</module>
</modules>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.4</spring-cloud.version>
</properties>
<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>
<!-- ... other common dependencies ... -->
</project>
Step 2: Service Discovery Server (Eureka Server) හදමු
මේක තමයි අපේ Microservices Architecture එකේ හදවත වගේ. හැම Service එකක්ම මේ Server එකේ Register වෙනවා.
// EurekaServerApplication.java
package lk.scguide.ecom.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer // මේ Annotation එක අනිවාර්යයි
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
# application.properties for Eureka Server
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
Step 3: Individual Services හදමු (e.g., Product Service)
දැන් Product Service එක වගේ එක Service එකක් හදමු. මේකත් සාමාන්ය Spring Boot Project එකක් වගේමයි, හැබැයි Eureka Server එකත් එක්ක Register වෙන්න Configuration එකක් දාන්න ඕනේ.
// ProductServiceApplication.java
package lk.scguide.ecom.productservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; // මේක අනිවාර්යයි
@SpringBootApplication
@EnableDiscoveryClient // Service Discovery Client එකක් විදියට හැසිරෙන්න
public class ProductServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
# application.properties for Product Service
server.port=8081 # මේක වෙනස් වෙන්න පුළුවන්
spring.application.name=product-service # මේ නම තමයි Eureka එකට Register වෙන්නේ
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
මේ වගේම Order Service, User Service වගේ අනිත් Services ටිකත් හදාගන්න පුළුවන්.
Step 4: Inter-Service Communication
Service එකිනෙකාට කතා කරන්නේ කොහොමද? සාමාන්යයෙන් REST API Calls මගින්. Spring Framework එකේදී RestTemplate
හෝ WebClient
පාවිච්චි කරන්න පුළුවන්. Service Discovery එකත් එක්ක වැඩ කරනකොට RestTemplate
එකට @LoadBalanced
Annotation එක දාන්න අමතක කරන්න එපා. ඒකෙන් Client-side Load Balancing එකක් ලැබෙනවා.
// Example: OrderService එක ProductService එකට කතා කරන හැටි
package lk.scguide.ecom.orderservice.service;
import lk.scguide.ecom.orderservice.model.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; // මේක තමයි key එක
@Service
public class OrderService {
@Autowired
private RestTemplate restTemplate; // @LoadBalanced Annotation එක තියෙන RestTemplate bean එකක් Auto-wire කරගන්න
public Order placeOrder(Order order) {
// Product Service එකෙන් Product එකේ විස්තර ගන්න
// "product-service" කියන්නේ Eureka එකේ Register වෙලා තියෙන Product Service එකේ නම
String productDetails = restTemplate.getForObject("http://product-service/products/" + order.getProductId(), String.class);
System.out.println("Product Details: " + productDetails);
// ... Order එක Database එකට Save කරන logic එක ...
return order;
}
}
// OrderServiceApplication.java (Main class)
// RestTemplate Bean එක මෙහෙම configure කරන්න
@SpringBootApplication
@EnableDiscoveryClient
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
@Bean
@LoadBalanced // මේක අනිවාර්යයි!
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Step 5: API Gateway (Spring Cloud Gateway) හදමු
Client ලා කෙලින්ම Services වලට කතා කරන්නේ නැහැ. API Gateway එකක් හරහා තමයි කතා කරන්නේ. ඒක Security, Request Routing වගේ දේවල් Manage කරනවා.
// ApiGatewayApplication.java
package lk.scguide.ecom.apigateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}n
// Routing Rules Define කරනවා
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("product-service", r -> r.path("/api/products/**")
.uri("lb://product-service")) // "lb://" කියන්නේ Load Balanced කියන එක
.route("order-service", r -> r.path("/api/orders/**")
.uri("lb://order-service"))
.route("user-service", r -> r.path("/api/users/**")
.uri("lb://user-service"))
.build();
}
}
# application.properties for API Gateway
server.port=8080
spring.application.name=api-gateway
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
මේ විදියට අපි අපේ Monolithic Application එක Microservices Architecture එකකට සාර්ථකව කඩනවා. මේක ඉතාමත් සරල උදාහරණයක් විතරයි, real-world scenario වලදී මේකට තව ගොඩක් දේවල් එකතු වෙනවා.
Microservices වල Challenges සහ Solutions
Microservices වලින් වාසි ගොඩක් තිබුණට, ඒවා Deploy කරලා Manage කරන එකට වෙනමම Skills set එකක් අවශ්ය වෙනවා. එන ප්රධාන Challenges කිහිපයකුයි ඒවට Solutions ටිකකුයි අපි බලමු:
- Data Consistency:
- Challenge: Services වලට තමන්ගේම Databases තියෙන නිසා, එක් Service එකක Data වෙනස් වෙනකොට අනිත් Services වල Data Consistent වෙන්න ඕනේ. Distributed transactions කරන එක අමාරුයි.
- Solution: Saga Pattern, Eventual Consistency, Message Queues (Kafka, RabbitMQ) පාවිච්චි කිරීම. (උදා: Order එකක් Place කරාම Event එකක් Publish කරලා Product Service එකට Stock Update කරන්න පුළුවන්).
- Inter-Service Communication:
- Challenge: Services අතර Communication එක Effective විදියට Maintain කරන එක.
- Solution: Synchronous Communication (REST APIs with
RestTemplate
/WebClient
), Asynchronous Communication (Message Queues, Event-Driven Architecture). GRPC වගේ Protocols පාවිච්චි කරන්නත් පුළුවන්.
- Monitoring and Logging:
- Challenge: Services ගණනාවක් තියෙනකොට Error එකක් ආවම හොයාගන්න, System එකේ Health එක බලන්න අමාරුයි.
- Solution: Centralized Logging (ELK Stack - Elasticsearch, Logstash, Kibana), Distributed Tracing (Spring Cloud Sleuth with Zipkin), Metrics (Prometheus, Grafana).
- Deployment and Orchestration:
- Challenge: Services ගණනාවක් Deploy කරන එක, Manage කරන එක.
- Solution: Containerization (Docker), Container Orchestration (Kubernetes). මේවා මගින් Services Auto-scale කරන්න, Fault tolerance වැඩි කරන්න, Deploy කරන එක පහසු කරන්න පුළුවන්.
- Security:
- Challenge: Services ගණනාවකට Security යොදන එක.
- Solution: API Gateway එක හරහා Centralized Security Implement කරන එක (OAuth2, JWT). Each Service එකටත් Microservice-specific Security rules දාන්න පුළුවන්.
මේ Challenges වලට Solutions තියෙනවා වගේම, මේවා Implement කරන්න වෙනමම Tools සහ Knowledge එකක් අවශ්ය වෙනවා.
Conclusion: Microservices ගමනට අත්වැලක්
ඉතින් යාළුවනේ, මේ ලිපියෙන් අපි Spring Boot පාවිච්චි කරලා Microservices Architecture එකක් කොහොමද හදන්නේ කියලත්, Monolithic Application එකක් Microservices වලට Split කරන්නේ කොහොමද කියලත්, ඒ වගේම ඒකේ Challenges මොනවද කියලත් සරලව කතා කළා. Microservices කියන්නේ අද Software Development ලෝකයේ නැතුවම බැරි Concept එකක්. ඒකෙන් Scalability, Resilience, Agility වගේ වාසි ගොඩක් ලැබෙනවා. ඒත් ඒකේ තියෙන Complexity එකත් තේරුම් ගන්න ඕනේ.
අපි අද කතා කරපු E-commerce Project එක Split කරන Exercise එක ඔයාලට පුළුවන් නම් ඔයාලගේ Machine එකේ හදලා බලන්න. Spring Initializr පාවිච්චි කරලා ඉක්මනින්ම Services හදාගන්න පුළුවන්. Spring Boot සහ Spring Cloud වල Documentation බැලුවොත් මේ ගැන තවත් ගොඩක් දේවල් ඉගෙන ගන්න පුළුවන්.
ඔයාලගේ අදහස්, ප්රශ්න, මේ ලිපියේ වැඩි දියුණු කරන්න ඕන දේවල්, පහළින් Comment කරන්න අමතක කරන්න එපා. ඔයාලගේ Feedback අපිට ගොඩක් වටිනවා. එහෙනම්, තවත් මෙවැනිම ලිපියකින් හමුවෙමු! සුභ දවසක්!