Temporal은 상태를 절대 잃지 않는 무료 내구성 Workflow Engine을 가지고 있다
Source: Dev.to
위 링크에 있는 전체 텍스트를 제공해 주시면, 해당 내용을 한국어로 번역해 드리겠습니다. (코드 블록, URL, 마크다운 형식 등은 그대로 유지됩니다.)
소개
결제 처리가 거래 중에 중단되면 어떻게 될까요?
일반 코드에서는 — 데이터 손실.
Temporal을 사용하면 — 중단된 지점부터 정확히 재개됩니다. Temporal은 워크플로우를 기본적으로 내구성 있고, 신뢰할 수 있으며, 재개 가능하도록 만듭니다.
Core Benefits
- Durable execution – 워크플로우는 충돌, 재시작 및 배포 후에도 지속됩니다.
- Automatic retries – 활동당 구성 가능한 재시도 정책.
- Long‑running workflows – 일, 주, 혹은 월 단위로 실행됩니다.
- Timers – 리소스를 차지하지 않고 시간(시간/일) 동안 대기합니다.
- Versioning – 실행 중인 인스턴스를 깨뜨리지 않고 워크플로우 코드를 업데이트합니다.
- Visibility – 모든 워크플로우 상태를 보여주는 웹 UI.
- TypeScript SDK – 완전 타입 지원, 뛰어난 개발자 경험.
- Self‑hosted – Docker Compose 또는 Kubernetes.
시작하기
Temporal 서버 실행
docker compose up -d
프로젝트 생성
npx @temporalio/create@latest my-app
cd my-app
npm run start
워크플로우 예시 (workflows.ts)
import { proxyActivities, sleep } from '@temporalio/workflow';
import type * as activities from './activities';
const { sendEmail, chargePayment, provisionAccount } = proxyActivities({
startToCloseTimeout: '30 seconds',
retry: { maximumAttempts: 3 }
});
export async function onboardUser(email: string, plan: string): Promise {
// Step 1: Send welcome email
await sendEmail(email, 'Welcome!');
// Step 2: Charge payment
const paymentId = await chargePayment(email, plan);
// Step 3: Provision account
await provisionAccount(email, plan);
// Step 4: Wait 3 days, then send tips
await sleep('3 days'); // Durable! Survives server restarts.
await sendEmail(email, 'Here are some tips...');
// Step 5: Wait 7 days, check engagement
await sleep('7 days');
await sendEmail(email, "How's it going?");
}
서버가 Step 2 이후에 충돌하면, Temporal은 Step 3부터 재개합니다 — 처음부터 시작하지 않습니다.
활동 (activities.ts)
export async function sendEmail(to: string, subject: string): Promise {
await resend.emails.send({ to, subject, from: 'app@company.com' });
}
export async function chargePayment(email: string, plan: string): Promise {
const session = await stripe.checkout.sessions.create({
customer_email: email,
line_items: [{ price: plans[plan], quantity: 1 }]
});
return session.id;
}
export async function provisionAccount(email: string, plan: string): Promise {
await db.accounts.create({ data: { email, plan, status: 'active' } });
}
워크플로 시작하기 (client.ts)
import { Client } from '@temporalio/client';
const client = new Client();
const handle = await client.workflow.start('onboardUser', {
taskQueue: 'main',
workflowId: `onboard-${userId}`,
args: ['user@example.com', 'pro']
});
// Check status
const result = await handle.result();
일반적인 사용 사례
- 결제 처리 – 보증된 완료와 함께 청구, 이행, 환불.
- 사용자 온보딩 – 상태를 잃지 않는 다일 멀티 시퀀스.
- 데이터 파이프라인 – 실패 지점부터 재개되는 ETL 작업.
- 주문 이행 – 결제 → 재고 → 배송 → 알림.
- 구독 관리 – 청구 주기, 업그레이드, 취소.
기능 비교
| 기능 | Temporal | BullMQ | Inngest | Trigger.dev |
|---|---|---|---|---|
| 지속 가능한 실행 | ✅ 핵심 기능 | ❌ | ✅ | ✅ |
| 장기 실행 | 일/개월 | 시간 | 제한됨 | 시간 |
| 워크플로 상태 | 자동 | 수동 | 자동 | 수동 |
| 버전 관리 | 내장 | 없음 | 없음 | 없음 |
| 가시성 UI | 전체 | Bull Board | 대시보드 | 대시보드 |
| 자체 호스팅 | ✅ | ✅ (Redis) | ❌ | ❌ |
| 복잡도 | 중간 | 낮음 | 낮음 | 낮음 |
결론
Temporal은 반드시 완료되어야 하는 워크플로에 이상적입니다—결제 처리, 주문 이행, 데이터 파이프라인 등. 충돌이나 재시작으로 상태가 손실될 수 있는 경우, Temporal은 내구성과 신뢰성을 보장하여 모든 애플리케이션에 엔터프라이즈 수준의 복원력을 제공합니다.