תבנית סאגה: אורקסטרציה וכוריאוגרפיה לעסקאות מבוזרות

יישום תבנית סאגה לעסקאות מבוזרות

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

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
תבנית סאגה: אורקסטרציה וכוריאוגרפיה לעסקאות מבוזרות
מורכב
~2-4 שבועות

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

שאלות נפוצות

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

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1467
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1318
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1015
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1276
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1019
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1019

יישום תבנית סאגה לעסקאות מבוזרות

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

שני סוגי סאגה

כוריאוגרפיה — שירותים מגיבים לאירועים של זה ללא מתאם מרכזי. כל שירות מפרסם אירועים לברוקר (למשל, Kafka) ונרשם לאירועים רלוונטיים. אם התשלום נכשל, שירות המלאי מבטל את ההזמנה באמצעות אירוע הפוך.

תזמור — מתאם סאגה מרכזי (למשל, Temporal) מנהל במפורש את השלבים והפיצויים. הקוד ברור יותר, קל יותר לניפוי באגים, אך דורש שירות נפרד.

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

איך לבחור בין תזמור לכוריאוגרפיה?

אם יש לכם עד 5 שירותים ופשטות ניפוי הבאגים היא קריטית — בחרו בתזמור. עבור מערכות גדולות עם 10+ שירותים ועומס גבוה, כוריאוגרפיה דרך Kafka מספקת יכולת הרחבה טובה יותר. אנו מרבים לשלב בין השניים: תזמור לשרשראות קריטיות, כוריאוגרפיה לתהליכי רקע. המהנדסים שלנו יבחרו את הגישה הנכונה לפרויקט שלכם — צרו קשר לייעוץ.

מה זה Temporal ולמה אתם צריכים אותו?

Temporal הוא מנוע מוכן לייצור עבור זרימות עבודה ארוכות טווח. הוא מנסה אוטומטית פעולות חוזרות, מאחסן היסטוריית ביצוע, ומאפשר לבדוק סאגות דרך ממשק משתמש. הוא מבטיח ביצוע פיצויים גם אם שירות קורס. למעלה מ-95% מהסאגות עם Temporal מסתיימות ללא התערבות ידנית. לפי הנתונים שלנו, תזמור דרך Temporal אמין פי 2-3 יותר מכוריאוגרפיה ללא מתאם. דוגמת תזמור עם Temporal:

import { proxyActivities, sleep } from '@temporalio/workflow'; const { reserveStock, chargePayment, createShipment, releaseStock, refund } = proxyActivities({ startToCloseTimeout: '10 seconds' }); export async function createOrderWorkflow(input: CreateOrderInput): Promise<void> { let stockReserved = false; let paymentCharged = false; try { await reserveStock({ orderId: input.orderId, items: input.items }); stockReserved = true; await chargePayment({ orderId: input.orderId, amount: input.amount }); paymentCharged = true; await createShipment({ orderId: input.orderId, address: input.address }); } catch (error) { // Temporal гарантирует выполнение компенсаций if (paymentCharged) { await refund({ orderId: input.orderId }); } if (stockReserved) { await releaseStock({ orderId: input.orderId }); } throw error; } } 

סאגה מתמשכת עם מצב

סאגה חייבת לשרוד הפעלות מחדש של שירותים. המצב נשמר במסד נתונים (PostgreSQL, MySQL). אנו משתמשים בטבלה עם סטטוסים (import { proxyActivities, sleep } from '@temporalio/workflow'; const { reserveStock, chargePayment, createShipment, releaseStock, refund } = proxyActivities({ startToCloseTimeout: '10 seconds' }); export async function createOrderWorkflow(input: CreateOrderInput): Promise<void> { let stockReserved = false; let paymentCharged = false; try { await reserveStock({ orderId: input.orderId, items: input.items }); stockReserved = true; await chargePayment({ orderId: input.orderId, amount: input.amount }); paymentCharged = true; await createShipment({ orderId: input.orderId, address: input.address }); } catch (error) { // Temporal гарантирует выполнение компенсаций if (paymentCharged) { await refund({ orderId: input.orderId }); } if (stockReserved) { await releaseStock({ orderId: input.orderId }); } throw error; } } , running, completed, failed) והקשר. כאשר שירות קורס, הוא קורא מחדש סאגות לא שלמות וממשיך מהשלב האחרון.

interface SagaState { sagaId: string; sagaType: string; status: 'running' | 'completed' | 'failed' | 'compensating'; currentStep: number; context: Record<string, unknown>; completedSteps: string[]; failedStep?: string; createdAt: Date; updatedAt: Date; } class PersistentSagaOrchestrator { async startSaga(sagaType: string, context: unknown): Promise<string> { const sagaId = uuidv4(); await this.sagaRepo.save({ sagaId, sagaType, status: 'running', currentStep: 0, context, completedSteps: [] }); await this.executeSaga(sagaId); return sagaId; } } 

כוריאוגרפיה דרך Kafka

דוגמת טיפול באירועים בשירות המלאי:

// Order Service публикует событие await kafka.producer.send({ topic: 'order.events', messages: [{ key: orderId, value: JSON.stringify({ type: 'OrderCreated', orderId, items, customerId })}] }); // Inventory Service слушает и резервирует kafka.consumer.subscribe({ topic: 'order.events' }); kafka.consumer.run({ eachMessage: async ({ message }) => { const event = JSON.parse(message.value.toString()); if (event.type !== 'OrderCreated') return; try { await inventoryService.reserveStock(event.orderId, event.items); await kafka.producer.send({ topic: 'inventory.events', messages: [{ key: event.orderId, value: JSON.stringify({ type: 'StockReserved', orderId: event.orderId })}] }); } catch { await kafka.producer.send({ topic: 'inventory.events', messages: [{ key: event.orderId, value: JSON.stringify({ type: 'StockReservationFailed', orderId: event.orderId })}] }); } } }); 

בעיות נפוצות ופתרונות

בעיה פתרון
פעולות לא אידמפוטנטיות בדיקת מצב קיים לפני יצירה (דוגמה למעלה)
אובדן מצב סאגה בקריסה שמירת סטטוס והקשר במסד נתונים
ניסיונות חוזרים אינסופיים ועומס מערכת השהיה אקספוננציאלית ומגבלת ניסיונות (בדרך כלל 3-5)
חוסר ניטור כלים כמו Jaeger, Grafana להמחשת התקדמות הסאגה

מה כלול בעבודה

תהליך היישום כולל:

  • ניתוח: הגדרת עסקאות עסקיות, גבולות שירותים, נקודות כשל.
  • עיצוב: בחירה בין תזמור לכוריאוגרפיה, הכנת תוכנית פיצויים.
  • יישום: כתיבת קוד סאגה, אינטגרציה עם Temporal או Kafka, הבטחת אידמפוטנטיות.
  • בדיקות: בדיקות יחידה, בדיקות אינטגרציה, בדיקות תרחישי כשל (הנדסת כאוס).
  • פריסה: פריסה ב-Docker/Kubernetes, הגדרת ניטור (Jaeger, Grafana).

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

דוגמת סאגה מורכבת עם פיצויים מרובים

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

לוחות זמנים ואחריות

  • תזמור פשוט (2-3 שירותים, ללא Temporal) — 1 עד 2 שבועות.
  • תזמור עם Temporal + ניטור — 2 עד 3 שבועות.
  • כוריאוגרפיה דרך Kafka עם מטפלים אידמפוטנטיים — 2 עד 4 שבועות.

העלות נקבעת באופן אישי לאחר ניתוח. אנו מציעים אחריות לקוד למשך 6 חודשים. למעלה מ-100 פרויקטים שנמסרו במיקרוסרוויסים (5+ שנים בשוק). צרו קשר להערכת פרויקט חינמית ולפתרון אופטימלי.

קריאה נוספת: תבנית סאגה (ויקיפדיה).