Spring Boot සහ Kafka: Real-time Messaging System හදමු! - SC Guide

අප්පච්චියේ, මේ දවස්වල traffic එක කියන්නේ හිතාගන්න බැරි දෙයක් නේද? වැඩට යන්න උදේට පාරට බැස්සොත් ඉතින් පැය ගාණක් පාරෙම තමයි. ඔය වගේ වෙලාවට අපිට හිතෙන්නේ නැද්ද, මේ හැමදෙයක්ම systematic විදියට, real-time update වෙන්න පටන් ගත්තොත් කොච්චර හොඳද කියලා? හරියට වාහනයක් පාරට ආව ගමන් අනිත් හැමෝටම ඒක update වෙනවා වගේ. ඇත්තටම, අපේ software ලෝකෙත් මේ වගේ situation ගොඩක් තියෙනවා. විශාල data ප්රමාණයක් real-time distribute කරන්න, වෙනස් වෙන system components අතර communication establish කරන්න, event-driven architectures හදන්න අපිට නිතරම ඕනේ වෙනවා.
අද මම ඔයාලත් එක්ක කතා කරන්න යන්නේ මේ වගේ complex problems වලට solution එකක් දෙන, data streaming වල රජ්ජුරුවෝ වගේ ඉන්න technology එකක් ගැන - ඒ තමයි Apache Kafka! ඒ වගේම, අපේ ප්රියතම Java framework එක වන Spring Boot එක්ක Kafka කොහොමද ලේසියෙන්ම integrate කරලා powerful real-time messaging applications හදන්නේ කියලත් මම explain කරන්නම්.
ඉතින්, coding වලට ආස අපේ කට්ටිය සූදානම්ද මේ අලුත් journey එකට?
1. Kafka කියන්නේ මොකක්ද? (What is Apache Kafka?)
ඉස්සෙල්ලම අපි බලමු මොකක්ද මේ Kafka කියන්නේ කියලා. සරලවම කිව්වොත්, Kafka කියන්නේ distributed streaming platform එකක්. Distributed කියන්නේ server ගොඩක් අතර විසිරිලා තියෙනවා කියන එක. Streaming කියන්නේ data එක දිගට flow වෙනවා කියන එක. හිතන්නකෝ, අපේ ගෙදරට වතුර එන pipe system එකක් වගේ. වතුර එක දිගට ගලාගෙන එනවා, ඒ වගේම අපිට අවශ්ය තැනට වතුර ගන්න පුළුවන්. Kafkaත් ඒ වගේ තමයි, විශාල data ප්රමාණයක් high throughput එකකින් එහාට මෙහාට යවනවා.
Key Concepts:
- Producer: Data create කරලා Kafka වලට යවන අය. (Data sender)
- Consumer: Kafka එකේ තියෙන data කියවන අය. (Data receiver)
- Broker: Kafka server එකක්. මේක තමයි data ගබඩා කරගෙන producers ලගෙන් data අරගෙන consumers ලට data දෙන්නේ. මේ brokers ලා ගොඩක් එකතු වෙලා Kafka cluster එකක් හදනවා.
- Topic: Data organize කරන category එකක්. හිතන්නකෝ, news paper එකේ sports, politics, weather වගේ sections වගේ. Producers ලා යවන data යම්කිසි Topic එකකට යවනවා, consumers ලා ඒ Topic එකෙන් data ගන්නවා.
- Partition: Topic එකක් ඇතුළේ තියෙන data organize කරන sub-division එකක්. එක Topic එකකට partitions ගොඩක් තියෙන්න පුළුවන්. මේකෙන් තමයි Kafka වල scalability එකයි, fault tolerance එකයි එන්නේ.
- Offset: Partition එකක් ඇතුළේ තියෙන message එකක unique id එකක්. Consumer කෙනෙක් මේ id එකෙන් තමයි එයා කීවෙනි message එකද කියෙව්වේ කියලා මතක තියාගන්නේ.
ඇයි මේ Kafka අපිට වැදගත් වෙන්නේ? Real-time analytics, log aggregation, event sourcing, microservices communication වගේ දේවල් වලට Kafka වගේ powerful tool එකක් නැතුවම බැහැ. සාමාන්යයෙන් භාවිතා කරන REST API calls වලට වඩා Kafka ගොඩක් advantageous වන්නේ asynchronous communication, decoupling services, and high scalability ලබාදෙන නිසායි.
2. Spring Bootයි Kafkaයි එකතු කරමු! (Let's Integrate Spring Boot and Kafka!)
Apache Kafka එකත් එක්ක වැඩ කරන්න පුළුවන් programming languages ගොඩක් තියෙනවා. ඒ අතරින් Java වලට Spring Framework එකෙන් සුවිශේෂී පහසුකම් ලබාදෙනවා. Spring Boot එක්ක Kafka integrate කරන එක හරිම ලේසියි. Spring for Apache Kafka project එකෙන් අපිට ඕන කරන හැම utility එකක්ම ලබාදෙනවා.
Project Setup:
ඉස්සෙල්ලම අපි Spring Boot project එකක් හදාගමු. ඔයාලට පුළුවන් Spring Initializr එකට ගිහින් පහත dependencies add කරලා project එක generate කරගන්න:
- Spring Web: REST endpoints හදාගන්න.
- Spring for Apache Kafka: Kafka integrate කරන්න.
ඔයාලගේ pom.xml
එකේ මේ වගේ dependencies තියෙන්න ඕනේ:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Kafka Configuration:
ඊළඟට, අපි application.properties
(නැත්නම් application.yml
) එකට Kafka broker details add කරන්න ඕනේ. සාමාන්යයෙන් Kafka default port එක 9092. ඔයාලා local එකේ Kafka run කරනවා නම්, මේ විදියට configure කරන්න පුළුවන්:
# application.properties
spring.kafka.bootstrap-servers=localhost:9092
Production environment එකක නම්, මේක Kafka cluster එකේ addresses වෙන්න පුළුවන්.
3. Message Send කරන්නේ කොහොමද? (How to Send Messages?) - Producer
Producer කියන්නේ Kafka Topic එකකට messages send කරන application එකට. Spring Boot වලදී, අපිට KafkaTemplate
කියන class එක භාවිතයෙන් හරිම ලේසියෙන් messages send කරන්න පුළුවන්.
Kafka Producer Service:
මුලින්ම, message send කරන්න service class එකක් හදාගමු:
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
@Service
public class KafkaProducerService {
private final KafkaTemplate<String, String> kafkaTemplate;
private static final String TOPIC_NAME = "my-first-kafka-topic";
public KafkaProducerService(KafkaTemplate<String, String> kafkaTemplate) {
this.kafkaTemplate = kafkaTemplate;
}
public void sendMessage(String message) {
System.out.println(String.format("Producing message to topic %s: %s", TOPIC_NAME, message));
this.kafkaTemplate.send(TOPIC_NAME, message);
}
}
මෙහිදී KafkaTemplate<String, String>
කියන්නේ, Key සහ Value දෙකම String type එකේ messages send කරන්න පුළුවන් template එකක්. TOPIC_NAME
කියන්නේ අපි messages යවන්න බලාපොරොත්තු වෙන Kafka Topic එකේ නම.
REST Controller for Testing:
මේ service එක test කරන්න අපි simple REST Controller එකක් හදාගමු:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/kafka")
public class KafkaProducerController {
private final KafkaProducerService kafkaProducerService;
public KafkaProducerController(KafkaProducerService kafkaProducerService) {
this.kafkaProducerService = kafkaProducerService;
}
@GetMapping("/publish")
public String publishMessage(@RequestParam("message") String message) {
kafkaProducerService.sendMessage(message);
return "Message published to Kafka successfully!";
}
}
දැන් ඔයාලට පුළුවන් මේ Spring Boot application එක run කරලා, browser එකේ හෝ Postman වගේ tool එකකින් http://localhost:8080/kafka/publish?message=Hello%20Kafka%20from%20Sri%20Lanka!
වගේ URL එකකට request එකක් යවලා messages send කරන්න.
Note: Messages send කරන්න කලින්, Kafka Broker එක run වෙලා තියෙන්න ඕනේ.
4. Message Receive කරන්නේ කොහොමද? (How to Receive Messages?) - Consumer
Consumer කියන්නේ Kafka Topics වලින් messages කියවන application එකට. Spring Boot වලදී, අපිට @KafkaListener
annotation එක භාවිතයෙන් හරිම ලේසියෙන් messages receive කරන්න පුළුවන්.
Kafka Consumer Service:
Messages receive කරන්න service class එකක් හදාගමු:
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Service;
@Service
public class KafkaConsumerService {
@KafkaListener(topics = "my-first-kafka-topic", groupId = "my-group-id")
public void consume(String message) {
System.out.println(String.format("Consumed message from topic my-first-kafka-topic (Group ID: my-group-id): %s", message));
}
}
මෙහිදී @KafkaListener
annotation එක හරිම වැදගත්. ඒකෙන් Spring Boot එකට කියනවා මේ method එක Kafka Topic එකකින් messages listen කරන්න ඕනේ කියලා.
topics = "my-first-kafka-topic"
: මේ consumer එක listen කරන Kafka Topic එකේ නම. Producers ලා messages යවන topic එකම වෙන්න ඕනේ.groupId = "my-group-id"
: මේ consumer එක අයිති consumer group එකේ id එක. එකමgroupId
එකට අයිති consumers ලා එකම message එක receive කරන්නේ නැහැ. ඒකෙන් තමයි scaling achieve කරන්නේ.
දැන් ඔයාලා producer එකෙන් message එකක් send කලොත්, මේ consumer එක console එකේ ඒ message එක print කරයි.
5. ප්රායෝගික උපදෙස් සහ හොඳම ක්රම (Practical Tips & Best Practices)
දැන් අපි Spring Boot එක්ක Kafka කොහොමද use කරන්නේ කියලා basic idea එකක් ගත්තා. හැබැයි real-world applications වලදී මේ ටිකට අමතරව තව ගොඩක් දේවල් ගැන හිතන්න වෙනවා. මෙන්න ටිකක් වැදගත් practical tips ටිකක්:
අ. Message Serialization/Deserialization:
අපි මේ උදාහරණයේදී String messages use කළා. හැබැයි real applications වලදී සාමාන්යයෙන් complex Java objects (POJOs) තමයි messages විදියට send කරන්නේ. Kafka වලට messages යවන්න කලින් ඒ objects bytes බවට convert කරන්න (serialize) ඕනේ, ඒ වගේම receive කරද්දී bytes ආපහු objects බවට convert කරන්න (deserialize) ඕනේ.
JSON, Avro, Protobuf වගේ formats මේකට use කරනවා. Spring Kafka වලට JSON serialization/deserialization පහසුකම් built-in තියෙනවා. ඒ සඳහා, application.properties
එකට පහත properties එකතු කරන්න පුළුවන්:
spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
spring.kafka.consumer.value-deserializer=org.springframework.kafka.support.serializer.JsonDeserializer
spring.kafka.consumer.properties.spring.json.value.default.type=com.yourcompany.YourMessageClass
YourMessageClass
කියන්නේ ඔයාලා send කරන object එකේ class name එක.
ආ. Error Handling:
Kafka messages process කරද්දී errors එන්න පුළුවන්. උදාහරණයක් විදියට, message එකේ format එක වැරදි වෙන්න පුළුවන්, නැත්නම් downstream system එක offline වෙලා තියෙන්න පුළුවන්. මේ වගේ වෙලාවට සාමාන්යයෙන් Dead Letter Topic (DLT) එකක් use කරනවා. Error එකක් ආවොත්, ඒ message එක DLT එකට යවලා පස්සේ examine කරන්න පුළුවන්. Spring Kafka වල DLT mechanism එකක් built-in තියෙනවා.
ඉ. Consumer Group සහ Scalability:
එකම groupId
එකට අයිති consumers ලා කිහිප දෙනෙක් එකම topic එකෙන් messages receive කරනවා නම්, Kafka ඒ messages partitions වලට අනුව distribute කරනවා. මේකෙන් messages parallel processing කරන්න පුළුවන්. උදාහරණයක් විදියට, my-first-kafka-topic
එකට partitions 3ක් තියෙනවා නම්, එකම groupId
එකට අයිති consumers ලා 3 දෙනෙක් ඒ partitions 3 distribute කරගෙන messages process කරනවා. ඒ වගේම, consumer කෙනෙක් fail වුණොත්, අනිත් consumers ලා එයාගේ workload එක automatically handle කරනවා. මේක තමයි Kafka වල තියෙන high availability එකේ රහස.
ඊ. Local Kafka Setup:
ඔයාලගේ development environment එකේ Kafka run කරන්න Docker Compose වගේ tools use කරන එක හරිම ලේසියි. මේක docker-compose.yml
එකක උදාහරණයක්:
version: '3'
services:
zookeeper:
image: 'bitnami/zookeeper:latest'
ports:
- '2181:2181'
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
kafka:
image: 'bitnami/kafka:latest'
ports:
- '9092:9092'
environment:
- KAFKA_BROKER_ID=1
- KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
- KAFKA_CFG_LISTENERS=PLAINTEXT://:9092
- KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://127.0.0.1:9092
- ALLOW_PLAINTEXT_LISTENER=yes
depends_on:
- zookeeper
මේක save කරලා docker-compose up -d
කියලා run කළොත්, ඔයාලට local එකේම Kafka cluster එකක් ready කරගන්න පුළුවන්.
අවසන් වචනය:
ඉතින්, අද අපි Spring Boot එක්ක Apache Kafka integrate කරන්නේ කොහොමද කියන එක ගැන ලොකු දැනුමක් ගත්තා. Kafka කියන්නේ විශාල පරිමාණයෙන් real-time data process කරන්න පුළුවන් ඉතාම බලවත් tool එකක්. ඒ වගේම Spring Boot වගේ framework එකක් එක්ක එකතු වුණාම, මේ වගේ distributed messaging systems හදන එක හරිම පහසු වෙනවා.
දැන් ඔයාලාට පුළුවන් මේ concepts ඔයාලගේ project වලට add කරලා බලන්න. පොඩි පොඩි applications හදලා, producer, consumer දෙකම run කරලා test කරලා බලන්න. එතකොට තමයි මේකේ අත්දැකීම හරියටම දැනෙන්නේ.
මතක තියාගන්න, software development කියන්නේ නිරන්තරයෙන් ඉගෙන ගන්න ඕන journey එකක්. මේ වගේ අලුත් technologies ගැන ඉගෙන ගන්න එක ඔයාලගේ skillset එකට ලොකු වටිනාකමක් එකතු කරයි. මේ article එක ගැන ඔයාලගේ අදහස්, ප්රශ්න පහළින් comment section එකේ දාගෙන යන්න. මම පුළුවන් හැම වෙලාවෙම උත්තර දෙන්නම්.
එහෙනම්, තවත් අලුත් knowledge එකක් එක්ක නැවත හමුවෙමු! Happy Coding!