סטנדרטיזציה של אירועי מיקרוסרוויסים: Avro, Schema Registry וחוזים

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

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
סטנדרטיזציה של אירועי מיקרוסרוויסים: Avro, Schema Registry וחוזים
מורכב
~3-5 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

סטנדרטיזציה של אירועי מיקרוסרוויס: Avro, Schema Registry וחוזים

ללא חוזה ברור, כל שינוי בפורמט האירוע שובר את הצרכנים. פעם אחת, שינוי שם שדה באירוע OrderShipped גרם לשלושה שירותים לקרוס בשעה 3:00 לפנות בוקר. ההתאוששות ארכה 4 שעות, וההפסד הממוצע מתקרית כזו הוא $15,000. סכמת אירועים היא חוזה שמבטיח שכל השינויים יהיו מפורשים ומבוקרים. היא מונעת 80% מבעיות התאימות לפני הפריסה. צור קשר — נעזור לך לעצב סכמות לארכיטקטורה שלך ולחסל קריסות בשעות הלילה.

Avro עם Schema Registry מהיר פי 3 בסריאליזציה מ-JSON ללא סכמה ומספק טיפוסיות קפדנית. אנו מבטיחים תאימות לאחור בכל שלבי האבולוציה — כך תימנע מתקריות לילה ותאיץ את הפיתוח.

למה Avro ולא JSON?

Avro הוא פורמט סריאליזציה בינארי שהוא קומפקטי פי 3-5 מ-JSON. הוא טיפוסי בקפדנות: שדה יכול להיות רק מהסוג המתואר בסכמה. Schema Registry בודק אוטומטית את תאימות הסכמות החדשות לישנות: אם תוסיף שדה חובה ללא ברירת מחדל, הרישום ידחה את ההרשמה. JSON אינו מספק ערבויות כאלה, ושגיאות תאימות מתגלות רק בזמן ריצה.

מאפיין Avro JSON (ללא סכמה)
טיפוסיות קפדנית דינמית
גודל הודעה קומפקטי (בינארי) מפורט (טקסט)
תאימות אוטומטית (Schema Registry) ידנית
מהירות סריאליזציה גבוהה (עד פי 3 מהר יותר) נמוכה
תמיכה באבולוציה מובנית (ברירת מחדל, alias) אין

אילו עקרונות עומדים בבסיס סכמת אירועים?

אירועים מתארים עובדות, לא פקודות. OrderShipped היא עובדה. ShipOrder היא פקודה. אירוע התרחש ואי אפשר לבטלו (רק לפצות עליו באירוע אחר).

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

תאימות לאחור כברירת מחדל. צרכנים ישנים חייבים לעבוד עם אירועים חדשים ללא שינויים.

מבנה אירוע

{ "eventId": "01HQ2XK4VB8M9QXYZ123456789",
  "eventType": "order.shipped",
  "eventVersion": "1.2",
  "occurredAt": "2025-03-28T14:22:00.000Z",
  "producedBy": "order-service",
  "correlationId": "req-abc-123",
  "causationId": "cmd-xyz-456",
  "aggregateType": "Order",
  "aggregateId": "12345",
  "aggregateVersion": 7,
  "payload": {
    "orderId": 12345,
    "userId": 67890,
    "carrier": "DHL",
    "trackingCode": "JD123456789DE",
    "estimatedDelivery": "2025-03-31",
    "items": [
      {
        "sku": "PROD-001",
        "quantity": 2,
        "warehouseId": "WH-MSK"
      }
    ]
  }
}
שדה מעטפת תיאור
eventId ULID או UUID עבור אידמפוטנטיות
eventType היררכי: domain.aggregate.action
eventVersion גרסת סמנטית של סכמת המטען
occurredAt UTC ISO 8601
correlationId למעקב אחר שרשראות בקשות
aggregateId + aggregateVersion לנעילה אופטימית

סכמת Avro עם אבולוציה

{ "type": "record", "name": "OrderShipped", "namespace": "com.example.orders.events", "doc": "Событие отгрузки заказа со склада", "fields": [
  {"name": "eventId", "type": "string"},
  {"name": "eventType", "type": "string", "default": "order.shipped"},
  {"name": "occurredAt", "type": {"type": "long", "logicalType": "timestamp-millis"}},
  {"name": "orderId", "type": "long"},
  {"name": "userId", "type": "long"},
  {"name": "carrier", "type": "string"},
  {"name": "trackingCode", "type": "string"},
  {
    "name": "estimatedDelivery",
    "type": ["null", "string"],
    "default": null,
    "doc": "ISO date, может отсутствовать для некоторых перевозчиков"
  },
  {
    "name": "warehouseId",
    "type": ["null", "string"],
    "default": null,
    "doc": "Добавлено в v1.1 — необязательное поле для backward compatibility"
  },
  {
    "name": "shippingCost",
    "type": ["null", {"type": "bytes", "logicalType": "decimal", "precision": 10, "scale": 2}],
    "default": null,
    "doc": "Добавлено в v1.2"
  }
] }

כללי אבולוציה לתאימות לאחור:

  • שדות חדשים — תמיד עם ברירת מחדל (null או ערך)
  • לא ניתן להסיר שדות חובה
  • לא ניתן לשנות את סוג השדה
  • לא ניתן לשנות שמות שדות (הוסף alias, ואז שנה שם דרך גרסה ראשית)

כדי להוסיף שדה { "eventId": "01HQ2XK4VB8M9QXYZ123456789", "eventType": "order.shipped", "eventVersion": "1.2", "occurredAt": "2025-03-28T14:22:00.000Z", "producedBy": "order-service", "correlationId": "req-abc-123", "causationId": "cmd-xyz-456", "aggregateType": "Order", "aggregateId": "12345", "aggregateVersion": 7, "payload": { "orderId": 12345, "userId": 67890, "carrier": "DHL", "trackingCode": "JD123456789DE", "estimatedDelivery": "2025-03-31", "items": [ {"sku": "PROD-001", "quantity": 2, "warehouseId": "WH-MSK"} ] } } מבלי לשבור תאימות, השתמש ב-{ "type": "record", "name": "OrderShipped", "namespace": "com.example.orders.events", "doc": "Событие отгрузки заказа со склада", "fields": [ {"name": "eventId", "type": "string"}, {"name": "eventType", "type": "string", "default": "order.shipped"}, {"name": "occurredAt", "type": {"type": "long", "logicalType": "timestamp-millis"}}, {"name": "orderId", "type": "long"}, {"name": "userId", "type": "long"}, {"name": "carrier", "type": "string"}, {"name": "trackingCode", "type": "string"}, { "name": "estimatedDelivery", "type": ["null", "string"], "default": null, "doc": "ISO date, может отсутствовать для некоторых перевозчиков" }, { "name": "warehouseId", "type": ["null", "string"], "default": null, "doc": "Добавлено в v1.1 — необязательное поле для backward compatibility" }, { "name": "shippingCost", "type": ["null", {"type": "bytes", "logicalType": "decimal", "precision": 10, "scale": 2}], "default": null, "doc": "Добавлено в v1.2" } ] } ובסוג warehouseId. צרכנים ישנים שלא יודעים על שדה זה פשוט יקבלו null.

איך לבדוק תאימות סכמה?

אנו בודקים אוטומטית תאימות לאחור ב-CI/CD: סריאליזציה של האירוע בצד המפיק, דה-סריאליזציה בצד הצרכן, ומוודאים שגרסאות ישנות לא קורסות. זה תופס שינויים שוברים לפני הפריסה. בדיקות חוזה מתקנות ציפיות משני הצדדים. רק תקרית אחת עקב אי-תאימות סכמה עולה בממוצע $15,000 במהלך פריסת לילה.

איך להבטיח תאימות לאחור?

# Настройка Schema Registry — BACKWARD совместимость для всех событий orders
curl -X PUT http://schema-registry:8081/config/order-events-value \
  -H "Content-Type: application/vnd.schemaregistry.v1+json" \
  -d '{"compatibility": "BACKWARD_TRANSITIVE"}'
# BACKWARD_TRANSITIVE — новая схема совместима со ВСЕМИ предыдущими версиями,
# не только с последней

שינוי ראשי (שינוי שובר) — נושא חדש:

  • "default": null → עבור צרכנים עם סכמה ישנה
  • ["null", "string"] → סכמה חדשה, צרכנים נודדים בהדרגה

תקופת מעבר: המפיק מפרסם לשני הנושאים. לאחר הגירה מלאה, # Настройка Schema Registry — BACKWARD совместимость для всех событий orders curl -X PUT http://schema-registry:8081/config/order-events-value \ -H "Content-Type: application/vnd.schemaregistry.v1+json" \ -d '{"compatibility": "BACKWARD_TRANSITIVE"}' # BACKWARD_TRANSITIVE — новая схема совместима со ВСЕМИ предыдущими версиями, # не только с последней מופסק.

קטלוג אירועים — תיעוד סכמות

עבור צוות עם מספר שירותים, רישום אירועים מרכזי הוא קריטי. אנו משתמשים ב-AsyncAPI כדי לתאר ערוצים והודעות.

asyncapi: 3.0.0
info:
  title: Order Service Events
  version: 1.0.0
  description: События, публикуемые Order Service
channels:
  order-events:
    address: order-events
    messages:
      OrderCreated:
        $ref: '#/components/messages/OrderCreated'
      OrderShipped:
        $ref: '#/components/messages/OrderShipped'
      OrderCancelled:
        $ref: '#/components/messages/OrderCancelled'
components:
  messages:
    OrderCreated:
      name: OrderCreated
      title: Заказ создан
      summary: Публикуется при успешном создании нового заказа
      contentType: application/avro
      headers:
        type: object
        properties:
          correlationId:
            type: string
            description: ID входящего HTTP-запроса
      payload:
        type: object
        required: [eventId, orderId, userId, items, totalAmount]
        properties:
          eventId:
            type: string
            format: ulid
          orderId:
            type: integer
            format: int64
          userId:
            type: integer
            format: int64
          items:
            type: array
            items:
              type: object
              properties:
                sku:
                  type: string
                quantity:
                  type: integer
                price:
                  type: number
          totalAmount:
            type: number
          createdAt:
            type: string
            format: date-time

מפרסם אירועים טיפוסי (TypeScript/Node.js)

import { SchemaRegistry } from '@kafkajs/confluent-schema-registry';
import { Kafka } from 'kafkajs';

interface EventEnvelope<T> {
  eventId: string;
  eventType: string;
  eventVersion: string;
  occurredAt: string;
  producedBy: string;
  correlationId?: string;
  aggregateType: string;
  aggregateId: string;
  aggregateVersion: number;
  payload: T;
}

interface OrderShippedPayload {
  orderId: number;
  userId: number;
  carrier: string;
  trackingCode: string;
  estimatedDelivery?: string;
}

class OrderEventPublisher {
  private registry: SchemaRegistry;
  private producer: ReturnType<Kafka['producer']>;

  async publishOrderShipped(data: OrderShippedPayload, correlationId?: string): Promise<void> {
    const envelope: EventEnvelope<OrderShippedPayload> = {
      eventId: ulid(),
      eventType: 'order.shipped',
      eventVersion: '1.2',
      occurredAt: new Date().toISOString(),
      producedBy: 'order-service',
      correlationId,
      aggregateType: 'Order',
      aggregateId: String(data.orderId),
      aggregateVersion: await this.getAggregateVersion(data.orderId),
      payload: data,
    };

    const schemaId = await this.registry.getLatestSchemaId('order-events-value');
    const encoded = await this.registry.encode(schemaId, envelope);

    await this.producer.send({
      topic: 'order-events',
      messages: [
        {
          key: String(data.orderId),
          value: encoded,
          headers: {
            'correlation-id': correlationId ?? '',
            'event-type': 'order.shipped',
          },
        },
      ],
    });
  }
}

איך עובד יישום סכמת אירועים?

יום 1: אנו מקיימים סדנה עם צוותי השירות: יצירת מפת Event Storming, זיהוי כל אירועי הדומיין והגבולות שלהם. יום 2: פיתוח סכמות Avro לכל סוג אירוע, הגדרת כללי שמות ומבנה מעטפת. רישום שלהם ב-Schema Registry. יום 3: יישום מפרסמי אירועים טיפוסיים בכל שירות מפיק ויצירת תיעוד AsyncAPI. יום 4: בדיקות חוזה, שילוב בדיקות תאימות ב-CI/CD, ומתן הנחיות לצוות על כללי אבולוציית סכמות.

מה כלול בפיתוח סכמת אירועים במפתחה מלאה

  • סדנת Event Storming ותיעוד כל האירועים
  • סכמות Avro עם תאימות לאחור וגרסאות
  • הגדרת Schema Registry (Kafka) עם כללי BACKWARD_TRANSITIVE
  • מפרסמי אירועים טיפוסיים ב-TypeScript/Node.js או Java/Scala
  • ספריית סריאליזציה/דה-סריאליזציה לאירועים
  • מפרט AsyncAPI לרישום האירועים המרכזי
  • בדיקות חוזה משולבות ב-CI/CD
  • תיעוד צוות והדרכת מפתחים
  • תמיכה במהלך הגירת צרכנים ישנים

אנו מבטיחים איכות תוצאות: הניסיון שלנו הוא 7 שנים בעיצוב מערכות ריאקטיביות וארכיטקטורת מיקרוקרנל, עם למעלה מ-30 פרויקטים של אינטגרציות מונעות אירועים. קבל ייעוץ על עיצוב סכמת אירועים — נבחן את הפרויקט שלך ונציע את הפתרון האופטימלי.