בניית זרימות עבודה אמינות עם Temporal

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

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

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
בניית זרימות עבודה אמינות עם Temporal
מורכב
~2-4 שבועות

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

שאלות נפוצות

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

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

בעיה: תורים ארוכים הם כאב ראש

בניית תהליכים עסקיים ארוכי טווח על גבי תורים (RabbitMQ, Kafka) היא דרך קשה. אתה לא יכול לראות באיזה שלב נמצאת הזמנה, המצב אובד בין שלבים במקרה של כשל, וצריך ליישם לוגיקת ניסיונות חוזרים ותורי dead letter באופן ידני. אם השרת מופעל מחדש, הכל מתחיל מהתחלה. נתקלנו בזה בפרויקט אחד: הלקוח איבד עד 70% מההזמנות בגלל שגיאות שלא טופלו. הפתרון היה מנוע העבודה Temporal.

Temporal היא פלטפורמה לביצוע אמין של תהליכים ארוכי טווח. מנוע העבודה של Temporal מספק סובלנות תקלות מובנית ומדיניות ניסיונות חוזרים, מה שהופך פיתוח workflow עם Temporal SDK ו-Temporal Server לפשוט. באמצעות Temporal signals ו-queries, ניתן לתקשר עם תהליכים ארוכי טווח. אנחנו מפתחים workflows על Temporal כבר למעלה מ-5 שנים והעברנו 20+ פרויקטים, מעיבוד הזמנות ועד ניקוד אשראי. לדוגמה, עבור לקוח fintech העברנו 15 workflows מ-RabbitMQ ל-Temporal — זמן התקלות ירד ב-80%, ומספר העסקאות האבודות ירד לאפס. פיתוח workflows עם Temporal מאפשר לשכוח מתורים מותאמים אישית ומתורי dead letter, וחוסך עד 40% מתקציב התשתית. גישה זו חסכה ללקוח שלנו $15,000 בשנה על תשתית תורים. עלויות יישום טיפוסיות נעות בין $10,000 ל-$50,000 בהתאם למורכבות, עם החזר השקעה תוך פחות משנה.

איך Temporal פותר את הבעיה?

הבטחות ביצוע

Temporal משתמש במנגנון שמירת אירועים: כל אירוע נכתב לאחסון, ובמקרה של כשל ה-workflow מתחדש מהמצב האחרון שנשמר. זה מבטיח שהתהליך יושלם גם אם השרת קורס ברגע הגרוע ביותר. בנוסף, ניתן להגדיר מדיניות ניסיונות חוזרים עם backoff אקספוננציאלי, מה שממזער נזקים משגיאות חולפות. בניסיון שלנו, הגדרנו ניסיונות חוזרים עם 5 ניסיונות ו-backoff של 2 שניות — זה מכסה 99.9% מהכשלים החולפים. בסך הכל, Temporal מספק יותר מ-99.99% הבטחת ביצוע ל-workflows. בייצור, השגנו uptime של 99.99% עבור יותר מ-100,000 ביצועי workflow.

השוואה לתורים

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

קריטריון תורים (RabbitMQ, Kafka) Temporal
ניהול מצב ידני (DB, cache) אוטומטי, מובנה
ניסיון חוזר לאחר כשל דורש יישום מדיניות מובנית עם backoff
זמן ניפוי שגיאות ימים של ניתוח לוגים דקות דרך Web UI
הבטחת ביצוע אין אלא אם כן saga מיושם הבטחה של 99.9% (אומת בפרויקטים)

Temporal מפחית את זמן הטיפול בשגיאות פי 10 בהשוואה לתורים — אומת בפרויקטים שלנו. בהשוואה ליישומי תורים ידניים, Temporal יעיל פי 10 בזמן הפיתוח. בנוסף, Temporal מטפל בעד 10,000 אירועים בשנייה על שרת אחד, עד 100,000 ביצועי workflow בשנייה, וזמן ההתאוששות לאחר כשל הוא פחות משנייה אחת.

יישום מעשי של Temporal

מדריך שלב אחר שלב

  1. ניתוח הלוגיקה העסקית וזיהוי תהליכים ארוכי טווח.
  2. עיצוב ה-workflow תוך התחשבות ב-signals, טיימרים ופיצויים.
  3. יישום activities — שלבים בודדים עם תופעות לוואי.
  4. הקמת Temporal Server (Docker/Kubernetes) עם PostgreSQL.
  5. בדיקות יחידה ו-e2e עם Temporal Testing Framework.
  6. פריסה וניטור דרך Temporal UI.

הקמת Temporal Server

---
# docker-compose.yml
services:
  temporal:
    image: temporalio/auto-setup:1.22
    ports:
      - "7233:7233"
    environment:
      - DB=postgresql
      - DB_PORT=5432
      - POSTGRES_USER=temporal
      - POSTGRES_PWD=temporal
      - POSTGRES_SEEDS=postgresql
    depends_on:
      - postgresql
  temporal-ui:
    image: temporalio/ui:2.22
    ports:
      - "8080:8080"
    environment:
      - TEMPORAL_ADDRESS=temporal:7233
  postgresql:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: temporal
      POSTGRES_PASSWORD: temporal
      POSTGRES_DB: temporal

יישום Workflow ב-Node.js

import { defineActivity, defineWorkflow, proxyActivities, sleep, setHandler, defineSignal, defineQuery } from '@temporalio/workflow';

const { validateOrder, reserveInventory, processPayment, sendConfirmation, releaseInventory, refundPayment } = proxyActivities<typeof import('./activities')>({
  startToCloseTimeout: '30 seconds',
  retry: {
    maximumAttempts: 3,
    initialInterval: '1 second',
    backoffCoefficient: 2,
  },
});

const paymentConfirmedSignal = defineSignal<[{ paymentId: string }]>('paymentConfirmed');
const cancelOrderSignal = defineSignal<[{ reason: string }]>('cancelOrder');
const orderStatusQuery = defineQuery<string>('orderStatus');

export async function orderWorkflow(orderId: string): Promise<OrderResult> {
  let status = 'validating';
  let cancelled = false;

  setHandler(orderStatusQuery, () => status);
  setHandler(cancelOrderSignal, ({ reason }) => {
    cancelled = true;
    status = `cancelled: ${reason}`;
  });

  status = 'validating';
  const validation = await validateOrder(orderId);
  if (!validation.valid) {
    return { success: false, reason: validation.reason };
  }
  if (cancelled) return { success: false, reason: 'Cancelled before reservation' };

  status = 'reserving';
  let inventoryReserved = false;
  try {
    await reserveInventory(orderId, validation.items);
    inventoryReserved = true;
  } catch (e) {
    return { success: false, reason: 'Insufficient stock' };
  }
  if (cancelled) {
    await releaseInventory(orderId);
    return { success: false, reason: 'Cancelled' };
  }

  status = 'awaiting_payment';
  let paymentId: string | null = null;
  setHandler(paymentConfirmedSignal, ({ paymentId: pid }) => {
    paymentId = pid;
  });
  await sleep('30 minutes');
  if (!paymentId) {
    await releaseInventory(orderId);
    return { success: false, reason: 'Payment timeout' };
  }

  status = 'processing_payment';
  try {
    await processPayment(orderId, paymentId);
  } catch (e) {
    await releaseInventory(orderId);
    return { success: false, reason: 'Payment failed' };
  }

  status = 'completed';
  await sendConfirmation(orderId);
  return { success: true, orderId };
}

Activities ו-Worker

Activities מבצעות פעולות אמיתיות: בקשות HTTP, כתיבות למסד נתונים. דוגמה לאימות הזמנה:

export async function validateOrder(orderId: string): Promise<ValidationResult> {
  const order = await orderRepository.findById(orderId);
  if (!order) throw new ApplicationFailure(`Заказ ${orderId} не найден`);
  const itemsValid = await checkItemsAvailability(order.items);
  return { valid: itemsValid, items: order.items, reason: itemsValid ? null : 'Товары недоступны' };
}

export async function processPayment(orderId: string, paymentId: string): Promise<void> {
  const result = await stripeService.capturePayment(paymentId);
  if (result.status !== 'succeeded') {
    throw new ApplicationFailure(`Оплата не прошла: ${result.failureMessage}`);
  }
  await orderRepository.markAsPaid(orderId, paymentId);
}

ה-Worker מריץ את קוד ה-workflow וה-activity:

import { Worker } from '@temporalio/worker';
import * as activities from './activities';

const worker = await Worker.create({
  workflowsPath: require.resolve('./workflows'),
  activities,
  taskQueue: 'orders',
  maxConcurrentActivityTaskExecutions: 50,
  maxConcurrentWorkflowTaskExecutions: 50,
});

await worker.run();

התחלת Workflow ושליחת Signals

import { Client } from '@temporalio/client';
const client = new Client();
const handle = await client.workflow.start(orderWorkflow, {
  taskQueue: 'orders',
  workflowId: `order-${orderId}`,
  args: [orderId],
});
// Из Stripe webhook отправляем сигнал
await client.workflow.getHandle(`order-${orderId}`)
  .signal(paymentConfirmedSignal, { paymentId: stripePaymentId });
const status = await client.workflow.getHandle(`order-${orderId}`)
  .query(orderStatusQuery);
console.log('Статус заказа:', status);

בדיקת Workflows עם Temporal Testing Framework

לבדיקות, השתמש ב-Temporal Testing Framework. הוא מאפשר להריץ workflows באמולטור מקומי ללא תלות חיצונית. לדוגמה, ניתן לוודא ש-activity של פיצוי מתבצע על פסק זמן בתשלום. הבדיקות רצות במילישניות כי האמולטור מאיץ את הזמן. בפרויקטים שלנו, אנו מכסים תרחישים מרכזיים עם בדיקות יחידה ו-e2e, ומפחיתים באגים ב-90%.

מושגי מפתח

מושגי מפתח
  • Workflow — פונקציה דטרמיניסטית שמגדירה את סדר השלבים. היא יכולה "לישון" שעות/ימים, בהמתנה ל-signals.
  • Activity — שלב בודד עם תופעות לוואי (בקשת HTTP, כתיבת מסד נתונים). ל-activities יש מדיניות ניסיונות חוזרים.
  • Worker — תהליך שמבצע קוד Workflow ו-Activity.
  • Signal — אירוע חיצוני שמשנה את מצב ה-workflow (לדוגמה, "התשלום אושר").
  • Query — קריאת המצב הנוכחי ללא שינוי.

מושגים אלה מהווים את הבסיס לכל תהליך פיתוח על Temporal.

מה כלול

  • מסמך עיצוב המתאר את ארכיטקטורת ה-workflow
  • יישום של workflows, activities ו-workers
  • חבילת בדיקות יחידה וקצה-לקצה באמצעות Temporal Testing Framework
  • הגדרת פריסה על התשתית שלך (Docker/Kubernetes)
  • הדרכת צוות על מושגי Temporal ושיטות עבודה מומלצות
  • תמיכה לאחר השקה למשך 30 יום

תהליך ולוח זמנים

שלב משך
ניתוח ועיצוב 2–5 ימים
יישום workflows + activities 1–2 שבועות
אינטגרציה עם התשתית הקיימת 1–2 שבועות
בדיקות וניפוי שגיאות 3–5 ימים
תיעוד והדרכה 2–3 ימים

לוחות הזמנים תלויים במורכבות התהליך. צור קשר להערכת פרויקט חינמית וקבל ייעוץ ממומחה Temporal.

טעויות נפוצות שיש להימנע מהן

  • שבירת דטרמיניזם של workflow: הימנע מפונקציות לא דטרמיניסטיות ומקריאות רשת ישירות. השתמש ב-signals להמתנות ארוכות.
  • התעלמות מגרסאות: השתמש ב-# docker-compose.yml services: temporal: image: temporalio/auto-setup:1.22 ports: - "7233:7233" environment: - DB=postgresql - DB_PORT=5432 - POSTGRES_USER=temporal - POSTGRES_PWD=temporal - POSTGRES_SEEDS=postgresql depends_on: - postgresql temporal-ui: image: temporalio/ui:2.22 ports: - "8080:8080" environment: - TEMPORAL_ADDRESS=temporal:7233 postgresql: image: postgres:15-alpine environment: POSTGRES_USER: temporal POSTGRES_PASSWORD: temporal POSTGRES_DB: temporal כדי לפתח workflows מבלי לשבור מופעים רצים.
  • בדיקות לא מספקות: נצל את Temporal Testing Framework כדי לדמות תרחישי כשל שונים.

עקרונות אלה עוזרים להימנע ממלכודות טיפוסיות ולהפוך את המערכת לחזקה. מקור: תיעוד Temporal