בעיצוב מערכות עכשווי, ארכיטקטורת מופעים (Event-Driven Architecture או EDA) מתמקדת ביצירה, זיהוי, שימוש ותגובה לאירועים בתוך מערכת. אירועים הם אירועים חשובים שיכולים להשפיע על חומרה או תוכנה במערכת, כגון פעולות משתמש, שינויי מצב או עדכוני נתונים.

EDA מאפשרת לרכיבים שונים באפליקציה להתקשר בדרך שאינה תלויתית, מאפשרת להם לתקשר דרך אירועים במקום בקריאות ישירות. ההגדרה הזו מאפשרת לרכיבים לעבוד באופן עצמאי, להגיב לאירועים באופן אסינכרוני ולהתאים את עצמם לצרכי עסקיים שמשתנים בלי צורך בשינויים רבים במערכת, תוך קידום גמישות.

אפליקציות חדשות ומודרניות נסמכות עכשיו בעיבוד נתונים בזמן אמת וביכולת להגיב מיד. חשיבותה של EDA אינה יכולה להיות מופצה מידי, מאחר שהיא מספקת את המסגרת התומכת בדרישות אלה. על ידי שימוש בתקשורת אסינכרונית ובהתגברות על פעולות שמבוצעות לפי אירועים, מערכות יכולות להתמודד ביעילות עם כמויות גבוהות של עסקאות ולשמור על ביצועים בתנאי העומס המשתנים. התכונות הללו נמצאות במיוחד מוערכות בסביבות שבהן השינויים מתרחשים באופן מאוד ספונטני, כגון פלטפורמות סחר אלקטרוני או אפליקציות IoT.

כמה מרכיבי EDA המרכזיים כוללים:

  • מקורות אירועים: אלה הם היוצרים שיוצרים אירועים כאשר פעולות חשובות מתרחשות במערכת. דוגמאות כוללות אינטראקציות משתמש או שינויים בנתונים.

  • מאזינים: אלה הם ישויות שמנויים לאירועים ספציפיים ומגיבים כאשר אירועים אלה מתרחשים. מאזינים מאפשרים למערכת להגיב בצורה דינמית לשינויים.

  • מטפלים: אלה אחראים על עיבוד האירועים לאחר שהם מזוהים על ידי מאזינים, ומבצעים את הלוגיקה העסקית או הזרימות הנדרשות שמעוררות על ידי האירוע.

במאמר זה, תלמד כיצד ליישם עיבוד נתונים מונחה אירועים באמצעות Traefik, Kafka ודוקר.

הנה יישום פשוט המופעל על GitHub שאתה יכול להריץ במהירות כדי לקבל סקירה על מה שאתה הולך לבנות היום.

תוכן העניינים

הנה מה שנכסה:

בואו נתחיל!

דרישות מקדימות

לפני שאתה מתחיל:

  • פרוס מופע של Ubuntu 24.04 עם לפחות 4 GB של RAM ומינימום של 20 GB של שטח דיסק פנוי כדי להכיל תמונות Docker, קונטיינרים ונתוני Kafka.

  • גש למופע עם משתמש שאינו root עם הרשאות sudo.

  • עדכן את אינדקס החבילות.

sudo apt update

הבנת הטכנולוגיות

אפאצ'י קאפה

אפאצ'י קאפה היא פלטפורמת זרימת אירועים מבוזרת שנבנתה עבור צינורות נתונים בעלי קיבולת גבוהה ואפליקציות זרימה בזמן אמת. היא משמשת כעורף ליישום EDA על ידי ניהול יעיל של כמויות גדולות של אירועים. קאפה משתמשת במודל פרסום-מנוי שבו מפיקים שולחים אירועים לנושאים, וצורכים נרשמים לנושאים אלה כדי לקבל את האירועים.

כמה מהתכונות המרכזיות של קאפה כוללות:

  • קיבולת גבוהה: קאפה מסוגלת לטפל במיליוני אירועים בשנייה עם השהיה נמוכה, מה שהופך אותה מתאימה לאפליקציות בנפח גבוה.

  • עמידות בפני תקלות: הארכיטקטורה המפולגת של קפקא מבטיחה עמידות וזמינות של נתונים גם כאשר מתרחשות תקלות בשרתים. היא משכפלת נתונים בין מספר מתווכים בתוך אשכול.

  • סקלאביליות: קפקא יכולה להתרחב בקלות אופקית על ידי הוספת מתווכים נוספים לאשכול או חלוקות לנושאים, מה שמאפשר לעמוד בדרישות הנתונים הגדלות ללא צורך בהגדרות מחדש משמעותיות.

Traefik

Traefik הוא פרוקסי הפוך מודרני ל-HTTP ומאזן עומסים, שנועד במיוחד לארכיטקטורות של מיקרו-שירותים. הוא מגלה אוטומטית שירותים הפועלים בתשתית שלך ומנתב את התנועה בהתאם. Traefik מפשט את ניהול המיקרו-שירותים על ידי מתן יכולות ניתוב דינמי בהתבסס על מטא-נתוני השירות.

כמה מהתכונות המרכזיות של Traefik כוללות:

  • הגדרה דינמית: Traefik מעדכן אוטומטית את הגדרות הניתוב שלו כאשר שירותים מתווספים או מוסרים, מה שמ eliminates את הצורך בהתערבות ידנית.

  • איזון עומסים: הוא מפיץ ביעילות בקשות נכנסות על פני מספר מופעי שירות, ומשפר ביצועים ואמינות.

  • לוח בקרה משולב: טראפיק מספק לוח בקרה ידידותי למשתמש למעקב אחר תנועת נתונים ובריאות השירות בזמן אמת.

באמצעות קפקא וטראפיק בארכיטקטורה מונחית אירועים, ניתן לבנות מערכות תגובתיות שמטפלות ביעילות בעיבוד נתונים בזמן אמת תוך שמירה על זמינות גבוהה וסקלאביליות.

איך להקים את הסביבה

איך להתקין דוקר על אובונטו 24.04

  1. התקן את החבילות הנדרשות.
sudo apt install ca-certificates curl gnupg lsb-release
  1. הוסף את מפתח ה-GPG הרשמי של דוקר.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
  1. הוסף את מאגר דוקר למקורות ה-APT שלך.
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
  1. עדכן את אינדקס החבילות שוב והתקן את מנוע דוקר עם תוסף דוקר קומפוז.
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
  1. בדוק כדי לאשר את ההתקנה.
sudo docker run hello-world

פלט צפוי:

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.

איך להגדיר את דוקר קומפוז

דוקר קומפוז מפשט את ניהול יישומי ריבוי קונטיינרים, ומאפשר לך להגדיר ולהפעיל שירותים בקובץ אחד.

  1. צור תיקיית פרויקט
mkdir ~/kafka-traefik-setup && cd ~/kafka-traefik-setup
  1. צור קובץ docker-compose.yml.
nano docker-compose.yml
  1. הוסף את התצורה הבאה לקובץ כדי להגדיר את השירותים שלך.
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
      - "8080:8080"   # לוח המחוונים של Traefik (לא בטוח)
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

שמור את השינויים שלך בעזרת ctrl + o, ולאחר מכן צא בעזרת ctrl + x.

  1. התחל את השירותים שלך.
docker compose up -d

פלט צפוי:

[+] 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

כיצד לבנות את המערכת המופעלת בארועים

כיצד ליצור מפיקי ארועים

כדי ליצור ארועים ב-Kafka, תצטרך לממש מפיק Kafka. להלן דוגמה בשימוש ב-Java.

  1. צור קובץ kafka-producer.java.
nano kafka-producer.java
  1. הוסף את התצורה הבאה עבור מפיק Kafka.
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) {
        // הגדר את תכונות המפיק
        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");

        // צור את המפיק
        KafkaProducer<String, String> producer = new KafkaProducer<>(props);

        try {
            // שלח הודעה לנושא "my-topic"
            ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key1", "Hello, Kafka!");
            RecordMetadata metadata = producer.send(record).get(); // שליחה סינכרונית
            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 {
            // סגור את המפיק
            producer.close();
        }
    }
}

שמור את השינויים שלך בעזרת ctrl + o, ולאחר מכן צא בעזרת ctrl + x.

בהגדרה שלמעלה, המפיק שולח הודעה עם המפתח "key1" והערך "שלום, Kafka!" לנושא "my-topic".

כיצד להגדיר נושאי Kafka

לפני שתייצר או תצרוף הודעות, עליך ליצור נושאים ב-Kafka.

  1. השתמש בסקריפט kafka-topics.sh הכלול בהתקנת Kafka שלך כדי ליצור נושא.
kafka-topics.sh --bootstrap-server localhost:9092 --create --topic <TopicName> --partitions <NumberOfPartitions> --replication-factor <ReplicationFactor>

לדוגמה, אם אתה רוצה ליצור נושא בשם my-topic עם 3 מחיצות וגורם שכפול של 1, הרץ:

docker exec <Kafka Container ID> /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic my-topic --partitions 3 --replication-factor 1

פלט צפוי:

Created topic my-topic.
  1. בדוק כדי לאשר אם הנושא נוצר בהצלחה.
docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list

פלט צפוי:

my-topic

איך ליצור צרכני אירועים

לאחר שיצרת את המפיקים והנושאים שלך, תוכל ליצור צרכנים כדי לקרוא הודעות מהנושאים הללו.

  1. צור קובץ kafka-consumer.java.
nano kafka-consumer.java
  1. הוסף את ההגדרה הבאה לצרכן Kafka.
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) {
        // הגדר את המאפיינים של הצרכן
        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");

        // צור את הצרכן
        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);

        // הירשם לנושא
        consumer.subscribe(Collections.singletonList("my-topic"));

        try {
            while (true) {
                // חפש רשומות חדשות
                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 {
            // סגור את הצרכן
            consumer.close();
        }
    }
}

שמור את השינויים שלך עם ctrl + o, ואז צא עם ctrl + x.

בהגדרה שלמעלה, הצרכן נרשם לmy-topic ומבצע חיפוש מתמשך להודעות חדשות. כאשר מתקבלות הודעות, הוא מדפיס את המפתחות והערכים שלהן יחד עם מידע על מחיצה ומיקום.

איך לשלב טראפיק עם קאפקה

הגדר את Traefik כפרוקסי הפוך.

שילוב Traefik כפרוקסי הפוך עבור Kafka מאפשר לך לנהל תעבורת נכנסת ביעילות תוך הפצת תכונות כגון הפניית נתיבים דינמיים וסיום SSL.

  1. עדכן את קובץ docker-compose.yml.
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
      - "8080:8080"    # לוח המחוונים של Traefik (לא מאובטח)
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

בהגדרה זו, החלף את kafka.example.com בשם הדומיין האמיתי שלך. התוויות מגדירות את כללי הניתוב שבהם ישתמש Traefik כדי להפנות תעבורה לשירות ה-Kafka.

  1. אתחל מחדש את השירותים שלך.
docker compose up -d
  1. גש ללוח המחוונים של Traefik על ידי גישה אל http://localhost:8080 בדפדפן האינטרנט שלך.

    איזון עומס עם Traefik

    Traefik מספק יכולות איזון עומס מובנות שיכולות לסייע בהפצת בקשות על מספר מופעים של מפיקי וצרכני Kafka שלך.

    אסטרטגיות לאיזון עומס של שירותי מיקרוסרווס בעקבות אירועים

    1. Round Robin:

לפי ברירת מחדל, Traefik משתמשת באסטרטגיית round-robin כדי להפיץ בקשות נכנסות באופן שווה בין כל המופעים הזמינים של שירות. זה יעיל לצורך איזון עומס כאשר רץ מספר מופעים של פועלים או צרכני Kafka.

  1. Sticky Sessions:

אם נדרש שבקשות מלקוח ספציפי תמיד יעברו לאותו מופע (לדוגמה, לשמירת מצב הסשן), אפשר להגדיר סשנות יצוקות ב־Traefik באמצעות עוגיות או כותרות.

  1. בדיקות בריאות:

הגדר בדיקות בריאות ב־Traefik כדי לוודא שתעבור תעבורת רק למופעים בריאים של שירותי ה־Kafka שלך. אפשר לעשות זאת על ידי הוספת פרמטרים של בדיקת בריאות בהגדרות השירות בקובץ ה־docker-compose.yml שלך:

    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"

בדיקת ההגדרה

אימות ייצור אירועים וצריכה

  1. Kafka מספק כלים מובנים בשורת הפקודה לבדיקות. הפעלת יצרן קונסולה.
    docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-topic

לאחר הפעלת פקודה זו, אפשר להקיש הודעות בטרמינל, שישלחו לנושא ה־Kafka המצוין.

  1. התחל עוד ישיבת טרמינל והפעל צרכן קונסולה.
    docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-topic --from-beginning

פקודה זו תציג את כל ההודעות ב־my-topic, כולל אלה שנוצרו לפני שהצרכן התחיל.

  1. כדי לראות כמה טוב הצרכנים שלך מתמודדים עם היוצרים, תוכל להפעיל את הפקודה הבאה כדי לבדוק את הלאג עבור קבוצת צרכנים מסוימת.
    docker exec -it kafka-traefik-setup-kafka-1 /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group <your-consumer-group>

ניטור ולוגינג

  1. מדדי Kafka:

Kafka חושף מדדים רבים שניתן לנטר באמצעות JMX (Java Management Extensions). תוכל להגדיר את JMX כך שיצאיר את המדדים אלה למערכות ניטור כמו Prometheus או Grafana. מדדים מרכזיים לניטור כוללים:

  • כמות ההודעות: קצב ההודעות שנוצרות ונצרכות.

  • לאג של הצרכן: ההבדל בין אופסט ההודעה האחרונה שנוצרה ואופסט ההודעה האחרונה שנצרכה.

  • בריאות הברוקר: מדדים הקשורים לביצועי הברוקר, כמו קצבי בקשות וקצבי שגיאות.

  1. אינטגרציה עם Prometheus וGrafana:

כדי להמחיש את מדדי Kafka, תוכל להגדיר את Prometheus לגבות מדדים מהברוקרים שלך ב־Kafka. עקוב אחרי השלבים הללו:

  • אפשר JMX Exporter על הברוקרים של Kafka שלך על ידי הוספתו כסוכן Java בהגדרות הברוקר שלך.

  • הגדר את Prometheus על ידי הוספת עבודה לגריפת נתונים בקובץ ההגדרות שלו (prometheus.yml) המצביע על נקודת הקצה של JMX Exporter שלך.

  • השתמש ב-Grafana כדי ליצור לוחות מחוונים שמציגים את המדדים הללו בזמן אמת.

איך ליישם ניטור עבור Traefik

  1. נקודת קצה למדדי Traefik.

Traefik מספקת תמיכה מובנית לייצוא מדדים באמצעות Prometheus. כדי לאפשר תכונה זו, הוסף את ההגדרה הבאה בהגדרת השירות של Traefik שלך ב-docker-compose.yml:

    command:
      - "--metrics.prometheus=true"
      - "--metrics.prometheus.addservice=true"
  1. ויזואליזציה של מדדי Traefik עם Grafana.

ברגע ש-Prometheus גרף את מדדי Traefik, תוכל להציג אותם באמצעות Grafana:

  • צור לוח מחוונים חדש ב-Grafana והוסף פאנלים המראים מדדים מרכזיים של Traefik כגון:

  • traefik_entrypoint_requests_total: מספר כולל של בקשות שהתקבלו.

  • traefik_backend_request_duration_seconds: זמני תגובה של שירותי צד אחורי.

  • traefik_service_requests_total: סה"כ בקשות שהועברו לשירותי צד אחורי.

  1. הגדרת התראות.

הגדרת התראות ב-Prometheus או ב-Grafana בהתבסס על סף ספציפי (לדוגמה: לג איחוד גבוה או קצב שגיאות מתגבר).

מסקנה

במדריך זה, ביצעת בהצלחה ארכיטקטורת אירועים מבוססת אירועים (EDA) באמצעות Kafka ו-Traefik בתוך סביבת Ubuntu 24.04.

משאבים נוספים

כדי ללמוד עוד, ניתן לבקר: