用途
Restate 是一个持久化执行(durable execution)框架,旨在让应用对故障具有弹性。该技能适用于构建以下类型的系统:
- 带自动重试的持久化工作流
- 带持久化状态的服务(虚拟对象)
- 具有事务保证的微服务编排
- 具有恰好一次(exactly-once)语义的事件处理
- 能在崩溃后继续运行的长时任务
何时使用
在以下情况使用 Restate:
- 构建即使发生故障也必须完成的工作流
- 需要自动重试和恢复,而无需手动编写重试逻辑
- 构建有状态服务(购物车、用户会话、支付处理)
- 使用 saga/补偿模式编排多个服务
- 处理具有恰好一次投递保证的事件
- 调度持久化定时器和 cron 任务
核心概念
服务类型
Restate 支持三种服务类型:
- Services:无状态处理器,具备持久化执行。适用于微服务编排、saga、幂等请求。
- Virtual Objects:有状态处理器,K/V 状态按 key 隔离。适用于实体(购物车)、状态机、actor、有状态事件处理。每个对象 key 同一时间只有一个处理器运行(一致性保证)。
- Workflows:特殊的虚拟对象,其中 run 处理器恰好执行一次。适用于订单处理、人工介入、长时预配。
持久化构建块
Restate 通过 SDK 上下文提供以下构建块:
- 日志化动作(ctx.run()):持久化副作用的结果
- 状态(ctx.get/set/clear):虚拟对象的 K/V 状态
- 定时器(ctx.sleep()):可在重启后存活的持久化睡眠
- 服务调用(ctx.serviceClient()):带自动重试的 RPC
- Awakeables:等待外部事件/信号
TypeScript SDK 快速参考
安装
npm install @restatedev/restate-sdk
基本服务
import * as restate from "@restatedev/restate-sdk";
const myService = restate.service({
name: "MyService",
handlers: {
greet: async (ctx: restate.Context, name: string) => {
return "Hello, " + name + "!";
},
},
});
restate.endpoint().bind(myService).listen(9080);
虚拟对象(有状态)
const counter = restate.object({
name: "Counter",
handlers: {
add: async (ctx: restate.ObjectContext, value: number) => {
const current = (await ctx.get<number>("count")) ?? 0;
ctx.set("count", current + value);
return current + value;
},
get: restate.handlers.object.shared(
async (ctx: restate.ObjectSharedContext) => {
return (await ctx.get<number>("count")) ?? 0;
}
),
},
});
工作流
const paymentWorkflow = restate.workflow({
name: "PaymentWorkflow",
handlers: {
run: async (ctx: restate.WorkflowContext, payment: Payment) => {
// Step 1: Reserve funds
const reservation = await ctx.run("reserve", () =>
reserveFunds(payment)
);
// Step 2: Wait for approval (awakeable)
const approved = await ctx.promise<boolean>("approval");
if (!approved) {
await ctx.run("cancel", () => cancelReservation(reservation));
return { status: "cancelled" };
}
// Step 3: Complete payment
await ctx.run("complete", () => completePayment(reservation));
return { status: "completed" };
},
approve: async (ctx: restate.WorkflowSharedContext) => {
ctx.promise<boolean>("approval").resolve(true);
},
reject: async (ctx: restate.WorkflowSharedContext) => {
ctx.promise<boolean>("approval").resolve(false);
},
},
});
关键 SDK 模式
// Journaled action - result persisted, replayed on retry
const result = await ctx.run("action-name", async () => {
return await callExternalApi();
});
// Durable timer - survives restarts
await ctx.sleep(60_000); // 60 seconds
// Call another service
const client = ctx.serviceClient(OtherService);
const response = await client.handler(input);
// Async call (fire and forget)
ctx.serviceSendClient(OtherService).handler(input);
// Delayed call
ctx.serviceSendClient(OtherService, { delay: 60_000 }).handler(input);
// Awakeable - wait for external signal
const { id, promise } = ctx.awakeable<string>();
// Give `id` to external system, then:
const result = await promise;
// Random (deterministic)
const value = ctx.rand.random();
const uuid = ctx.rand.uuidv4();
本地运行
启动 Restate 服务器:
npx @restatedev/restate-server
运行你的服务:
npx ts-node src/app.ts
向 Restate 注册服务:
npx @restatedev/restate deployments register http://localhost:9080
通过 HTTP 调用处理器:
# Service handler
curl localhost:8080/MyService/greet -H 'content-type: application/json' -d '"World"'
# Virtual Object handler (with key)
curl localhost:8080/Counter/user123/add -H 'content-type: application/json' -d '5'
# Start workflow
curl localhost:8080/PaymentWorkflow/order-456/run -H 'content-type: application/json' -d '{"amount": 100}'
重要准则
- 副作用必须包裹在 ctx.run() 中——外部调用、随机值、时间戳都必须经过上下文,以便正确日志化和重放。
- 状态访问仅限虚拟对象/工作流——普通服务没有状态访问能力。
- 处理器必须是确定性的——相同输入应产生相同输出。使用 ctx.rand 获取随机性。
- 每个虚拟对象 key 同一时间只有一个处理器运行——Restate 通过将同一 key 的并发请求排队来保证一致性。
- 工作流的 run 处理器恰好执行一次——使用其他处理器查询/向工作流发送信号。
- 代码变更后需重新注册服务——运行 restate deployments register 以更新处理器定义。
适用场景
- 工作流
- 异步任务
- 事件处理
- 微服务编排
限制
- 状态访问仅限虚拟对象和工作流,普通服务不支持。
- 处理器必须保持确定性,随机性需通过 ctx.rand 获取。
- 每个虚拟对象 key 同一时间仅允许一个处理器运行。
- 代码变更后必须重新注册服务以更新处理器定义。
- 关于收费、价格、平台支持范围等具体信息,资料中暂未提供。