In moderne systeemontwerp richt Event-Driven Architecture (EDA) zich op het creëren, detecteren, gebruiken en reageren op gebeurtenissen binnen een systeem. Gebeurtenissen zijn belangrijke gebeurtenissen die hardware of software van een systeem kunnen beïnvloeden, zoals gebruikersacties, statuswijzigingen of gegevensupdates.
EDA maakt het mogelijk dat verschillende delen van een toepassing op een losgekoppelde manier met elkaar kunnen communiceren, waardoor ze kunnen communiceren via gebeurtenissen in plaats van directe oproepen. Deze opstelling stelt componenten in staat om onafhankelijk te werken, te reageren op gebeurtenissen asynchroon en zich aan te passen aan veranderende bedrijfsbehoeften zonder grote systeemherconfiguratie, wat de wendbaarheid bevordert.
Nieuwe en moderne toepassingen vertrouwen nu zwaar op realtime gegevensverwerking en responsiviteit. De belangrijkheid van EDA kan niet worden overschat omdat het het kader biedt dat die vereisten ondersteunt. Door gebruik te maken van asynchrone communicatie en op gebeurtenissen gebaseerde interacties, kunnen systemen efficiënt omgaan met grote hoeveelheden transacties en prestaties behouden onder instabiele belastingen. Deze functies worden vooral gewaardeerd in omgevingen waar veranderingen zeer spontaan zijn, zoals e-commerceplatforms of IoT-toepassingen.
Enkele belangrijke componenten van EDA zijn:
-
Gebeurtenisbronnen: Dit zijn de producenten die gebeurtenissen genereren wanneer belangrijke acties binnen het systeem plaatsvinden. Voorbeelden zijn gebruikersinteracties of gegevenswijzigingen.
-
Luisteraars: Dit zijn entiteiten die zich abonneren op specifieke gebeurtenissen en reageren wanneer die gebeurtenissen zich voordoen. Luisteraars stellen het systeem in staat om dynamisch te reageren op veranderingen.
-
Handlers: Deze zijn verantwoordelijk voor het verwerken van de gebeurtenissen zodra ze worden gedetecteerd door luisteraars, het uitvoeren van de noodzakelijke bedrijfslogica of workflows die worden geactiveerd door de gebeurtenis.
In dit artikel leer je hoe je op gebeurtenissen gebaseerde gegevensverwerking implementeert met Traefik, Kafka en Docker.
Hier is een eenvoudige toepassing gehost op GitHub die je snel kunt uitvoeren om een overzicht te krijgen van wat je vandaag zult bouwen.
Inhoudsopgave
Dit is wat we zullen behandelen:
Laten we beginnen!
Vereisten
Voordat je begint:
-
Implementeer een Ubuntu 24.04 instantie met minimaal 4 GB RAM en een minimum van 20 GB vrije schijfruimte om Docker-images, containers en Kafka-gegevens te accommoderen.
-
Open de instantie met een niet-rootgebruiker met sudo-rechten.
-
Werk de pakketindex bij.
sudo apt update
Begrip van de Technologieën
Apache Kafka
Apache Kafka is een gedistribueerd gebeurtenissenstroomplatform gebouwd voor data pipelines met een hoog doorvoervermogen en real-time streamingtoepassingen. Het fungeert als ruggengraat voor het implementeren van EDA door efficiënt grote hoeveelheden gebeurtenissen te beheren. Kafka maakt gebruik van een publiceer-abonneemodel waarbij producenten gebeurtenissen naar onderwerpen sturen en consumenten zich abonneren op deze onderwerpen om de gebeurtenissen te ontvangen.
Enkele van de belangrijkste kenmerken van Kafka zijn:
-
Hoge doorvoer: Kafka is in staat om miljoenen gebeurtenissen per seconde te verwerken met lage latentie, waardoor het geschikt is voor toepassingen met een hoog volume.
-
Fouttolerantie: Kafka’s gedistribueerde architectuur zorgt voor gegevensduurzaamheid en beschikbaarheid, zelfs bij serverstoringen. Het repliceert gegevens over meerdere brokers binnen een cluster.
-
Schaalbaarheid: Kafka kan eenvoudig horizontaal worden geschaald door meer brokers aan het cluster toe te voegen of partities aan topics, waardoor groeiende gegevensbehoeften worden ondersteund zonder significante herconfiguratie.
Traefik
Traefik is een moderne HTTP-reverse-proxy en load balancer die speciaal is ontworpen voor microservices-architecturen. Het ontdekt automatisch services die in uw infrastructuur draaien en routeert het verkeer dienovereenkomstig. Traefik vereenvoudigt het beheer van microservices door dynamische routeringsmogelijkheden te bieden op basis van servicemetadata.
Enkele van de belangrijkste functies van Traefik zijn:
-
Dynamische configuratie: Traefik werkt automatisch zijn routeringsconfiguratie bij wanneer services worden toegevoegd of verwijderd, waardoor handmatige interventie wordt geëlimineerd.
-
Load Balancer: Het verdeelt efficiënt binnenkomende verzoeken over meerdere service-instanties, waardoor de prestaties en betrouwbaarheid verbeteren.
-
Geïntegreerd Dashboard: Traefik biedt een gebruiksvriendelijk dashboard voor het monitoren van verkeer en de gezondheid van services in realtime.
Door Kafka en Traefik te gebruiken in een op gebeurtenissen gebaseerde architectuur, kunt u responsieve systemen bouwen die efficiënt omgaan met real-time gegevensverwerking, terwijl hoge beschikbaarheid en schaalbaarheid worden gehandhaafd.
Hoe u de omgeving instelt
Hoe u Docker installeert op Ubuntu 24.04
- Installeer de vereiste pakketten.
sudo apt install ca-certificates curl gnupg lsb-release
- Voeg de officiële GPG-sleutel van Docker toe.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
- Voeg het Docker-repository toe aan uw APT-bronnen.
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- Werk de pakketindex opnieuw bij en installeer Docker Engine met de Docker Compose-plugin.
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
- Controleer om de installatie te verifiëren.
sudo docker run hello-world
Verwachte uitvoer:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:305243c734571da2d100c8c8b3c3167a098cab6049c9a5b066b6021a60fcb966
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
Hoe u Docker Compose configureert
Docker Compose vereenvoudigt het beheer van multi-container toepassingen, waardoor u services kunt definiëren en uitvoeren in een enkel bestand.
- Maak een projectdirectory
mkdir ~/kafka-traefik-setup && cd ~/kafka-traefik-setup
- Maak een
docker-compose.yml
-bestand.
nano docker-compose.yml
- Voeg de volgende configuratie toe aan het bestand om uw services te definiëren.
version: '3.8'
services:
kafka:
image: wurstmeister/kafka:latest
ports:
- "9092:9092"
environment:
KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9092,OUTSIDE://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
KAFKA_LISTENERS: INSIDE://0.0.0.0:9092,OUTSIDE://0.0.0.0:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
zookeeper:
image: wurstmeister/zookeeper:latest
ports:
- "2181:2181"
traefik:
image: traefik:v2.9
ports:
- "80:80" # HTTP verkeer
- "8080:8080" # Traefik dashboard (onveilig)
command:
- "--api.insecure=true"
- "--providers.docker=true"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
Sla je wijzigingen op met ctrl + o
, en verlaat met ctrl + x
.
- Start je diensten.
docker compose up -d
Verwachte uitvoer:
[+] Running 4/4
✔ Network kafka-traefik-setup_default Created 0.2s
✔ Container kafka-traefik-setup-zookeeper-1 Started 1.9s
✔ Container kafka-traefik-setup-traefik-1 Started 1.9s
✔ Container kafka-traefik-setup-kafka-1 Started 1.9s
Hoe een op gebeurtenissen aangedreven systeem te bouwen
Hoe gebeurtenisproducenten te creëren
Om gebeurtenissen in Kafka te produceren, moet je een Kafka-producent implementeren. Hieronder staat een voorbeeld met Java.
- Maak een bestand
kafka-producer.java
.
nano kafka-producer.java
- Voeg de volgende configuratie toe voor een Kafka-producent.
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;
import java.util.Properties;
public class SimpleProducer {
public static void main(String[] args) {
// Stel de producenteigenschappen in
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
// Maak de producent aan
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
try {
// Stuur een bericht naar het onderwerp "my-topic"
ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key1", "Hello, Kafka!");
RecordMetadata metadata = producer.send(record).get(); // Synchroniseren verzenden
System.out.printf("Sent message with key %s to partition %d with offset %d%n",
record.key(), metadata.partition(), metadata.offset());
} catch (Exception e) {
e.printStackTrace();
} finally {
// Sluit de producent
producer.close();
}
}
}
Sla je wijzigingen op met ctrl + o
, en verlaat met ctrl + x
.
In de bovenstaande configuratie verstuurt de producent een bericht met de sleutel “key1” en de waarde “Hallo, Kafka!” naar het onderwerp “my-topic”.
Hoe Kafka-onderwerpen in te stellen
Voordat je berichten kunt produceren of consumeren, moet je onderwerpen in Kafka aanmaken.
- Gebruik het
kafka-topics.sh
script dat is inbegrepen bij je Kafka-installatie om een topic aan te maken.
kafka-topics.sh --bootstrap-server localhost:9092 --create --topic <TopicName> --partitions <NumberOfPartitions> --replication-factor <ReplicationFactor>
Bijvoorbeeld, als je een topic met de naam my-topic
met 3 partities en een replicafactor van 1 wilt aanmaken, voer dan het volgende uit:
docker exec <Kafka Container ID> /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic my-topic --partitions 3 --replication-factor 1
Verwachte uitvoer:
Created topic my-topic.
- Controleer om te bevestigen of het topic succesvol is aangemaakt.
docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list
Verwachte uitvoer:
my-topic
Hoe Event Consumers Aan te maken
Nadat je je producers en topics hebt aangemaakt, kun je consumenten creëren om berichten van die topics te lezen.
- Maak een bestand
kafka-consumer.java
aan.
nano kafka-consumer.java
- Voeg de volgende configuratie toe voor een Kafka consument.
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import java.time.Duration;
import java.util.Collections;
import java.util.Properties;
public class SimpleConsumer {
public static void main(String[] args) {
// Stel de consumenteigenschappen in
Properties props = new Properties();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-group");
props.put(ConsumerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
props.put(ConsumerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
// Maak de consument aan
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
// Abonneer op het topic
consumer.subscribe(Collections.singletonList("my-topic"));
try {
while (true) {
// Poll voor nieuwe records
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
System.out.printf("Consumed message with key %s and value %s from partition %d at offset %d%n",
record.key(), record.value(), record.partition(), record.offset());
}
}
} finally {
// Sluit de consument af
consumer.close();
}
}
}
Sla je wijzigingen op met ctrl + o
, en verlaat met ctrl + x
.
In de bovenstaande configuratie abonneert de consument zich op my-topic
en pollt continu voor nieuwe berichten. Wanneer berichten worden ontvangen, worden hun sleutels en waarden samen met partitie- en offsetinformatie afgedrukt.
Hoe Traefik te integreren met Kafka
Configureer Traefik als een Reverse Proxy.
Integratie van Traefik als een reverse proxy voor Kafka stelt je in staat om binnenkomend verkeer efficiënt te beheren, terwijl het functies biedt zoals dynamische routering en SSL-terminatie.
- Werk het
docker-compose.yml
bestand bij.
version: '3.8'
services:
kafka:
image: wurstmeister/kafka:latest
ports:
- "9092:9092"
environment:
KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9092,OUTSIDE://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
KAFKA_LISTENERS: INSIDE://0.0.0.0:9092,OUTSIDE://0.0.0.0:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
labels:
- "traefik.enable=true"
- "traefik.http.routers.kafka.rule=Host(`kafka.example.com`)"
- "traefik.http.services.kafka.loadbalancer.server.port=9092"
zookeeper:
image: wurstmeister/zookeeper:latest
ports:
- "2181:2181"
traefik:
image: traefik:v2.9
ports:
- "80:80" # HTTP verkeer
- "8080:8080" # Traefik dashboard (onveilig)
command:
- "--api.insecure=true"
- "--providers.docker=true"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
Vervang in deze configuratie kafka.example.com
door je werkelijke domeinnaam. De labels definiëren de routeringsregels die Traefik zal gebruiken om verkeer naar de Kafka-service te leiden.
- Herstart je services.
docker compose up -d
-
Toegang tot je Traefik dashboard door
http://localhost:8080
in je webbrowser te openen.Load Balancing met Traefik
Traefik biedt ingebouwde load balancing mogelijkheden die kunnen helpen om verzoeken over meerdere instanties van je Kafka-producers en -consumenten te verspreiden.
Strategieën voor Load Balancing in Event-Driven Microservices
- Round Robin:
Standaard gebruikt Traefik een round-robin-strategie om inkomende verzoeken gelijkmatig over alle beschikbare instanties van een service te verdelen. Dit is effectief voor het balanceren van de belasting wanneer er meerdere instanties van Kafka-producenten of -consumenten actief zijn.
- Sticky Sessions:
Als u wilt dat verzoeken van een specifieke client altijd naar dezelfde instantie gaan (bijvoorbeeld om sessiestatus te behouden), kunt u plakkerige sessies configureren in Traefik met behulp van cookies of headers.
- Health Checks:
Configureer gezondheidscontroles in Traefik om ervoor te zorgen dat verkeer alleen wordt doorgestuurd naar gezonde instanties van uw Kafka-services. U kunt dit doen door gezondheidscontroleparameters toe te voegen in de service-definities in uw docker-compose.yml
-bestand:
labels:
- "traefik.http.services.kafka.loadbalancer.healthcheck.path=/health"
- "traefik.http.services.kafka.loadbalancer.healthcheck.interval=10s"
- "traefik.http.services.kafka.loadbalancer.healthcheck.timeout=3s"
Testen van de Setup
Verifiëren van Event Productie en Consumptie
- Kafka biedt ingebouwde opdrachtregeltools voor testen. Start een Console-producent.
docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-topic
Nadat u deze opdracht heeft uitgevoerd, kunt u berichten typen in de terminal die worden verzonden naar het opgegeven Kafka-onderwerp.
- Start een andere terminalsessie en start een console-consument.
docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-topic --from-beginning
Dit commando toont alle berichten in my-topic
, inclusief die geproduceerd voordat de consument begon.
- Om te zien hoe goed uw consumenten bijblijven met producenten, kunt u het volgende commando uitvoeren om de vertraging voor een specifieke consumentengroep te controleren.
docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group <your-consumer-group>
Monitoring en Logging
- Kafka Statistieken:
Kafka biedt talloze statistieken die kunnen worden gemonitord met JMX (Java Management Extensions). U kunt JMX configureren om deze statistieken te exporteren naar monitorsystemen zoals Prometheus of Grafana. Belangrijke statistieken om te monitoren zijn:
-
Berichten Doorvoer: De snelheid van geproduceerde en geconsumeerde berichten.
-
Consumenten Vertraging: Het verschil tussen de offset van het laatst geproduceerde bericht en de offset van het laatst geconsumeerde bericht.
-
Broker Gezondheid: Statistieken gerelateerd aan de prestaties van de broker, zoals aanvraagpercentages en foutpercentages.
- Integratie van Prometheus en Grafana:
Om Kafka-statistieken te visualiseren, kunt u Prometheus instellen om statistieken van uw Kafka-brokers te verzamelen. Volg deze stappen:
-
Schakel JMX Exporter in op uw Kafka-brokers door het toe te voegen als een Java-agent in uw brokerconfiguratie.
-
Configureer Prometheus door een scrape taak toe te voegen in het configuratiebestand (
prometheus.yml
) dat wijst naar uw JMX Exporter-eindpunt. -
Gebruik Grafana om dashboards te maken die deze metingen in realtime visualiseren.
Hoe Monitoring implementeren voor Traefik
- Traefik Metrics-eindpunt.
Traefik biedt ingebouwde ondersteuning voor het exporteren van metingen via Prometheus. Voeg om deze functie in te schakelen de volgende configuratie toe in de definitie van uw Traefik-service binnen docker-compose.yml
:
command:
- "--metrics.prometheus=true"
- "--metrics.prometheus.addservice=true"
- Visualiseer Traefik-metingen met Grafana.
Zodra Prometheus Traefik-metingen schraapt, kunt u ze visualiseren met Grafana:
-
Maak een nieuw dashboard in Grafana en voeg panelen toe die belangrijke Traefik-metingen weergeven, zoals:
-
traefik_entrypoint_requests_total: Totaal aantal ontvangen verzoeken.
-
traefik_backend_request_duration_seconds: Responstijden van backend-services.
-
traefik_service_requests_total: Totaal aantal verzoeken doorgestuurd naar backend-services.
- Instellen van waarschuwingen.
Configureer waarschuwingen in Prometheus of Grafana op basis van specifieke drempels (bijv. hoge consumentenvertraging of verhoogde foutpercentages).
Conclusie
In deze handleiding heeft u met succes Event Driven Architecture (EDA) geïmplementeerd met behulp van Kafka en Traefik binnen de Ubuntu 24.04-omgeving.
Extra bronnen
Voor meer informatie kunt u terecht op:
Source:
https://www.freecodecamp.org/news/how-to-implement-event-driven-data-processing/