Durable Objects
มันคืออะไร
ลองนึกภาพพนักงานต้อนรับคนเดียวที่รับมือกับคนทีละคน และจดจำทุกคนที่เคยมาก่อนหน้านี้ได้ — ไม่มีพนักงานคนที่สองมาให้คำตอบที่ขัดแย้งกันได้ Durable Object ก็คือพนักงานคนนั้นในรูปแบบซอฟต์แวร์ นั่นคือ เซิร์ฟเวอร์ขนาดจิ๋วที่เก็บความจำของตัวเองไว้ (เรียกว่า "stateful" หรือมีสถานะ) และ Cloudflare รับประกันว่ามันมีอยู่เพียงที่เดียวในเวลาใดเวลาหนึ่งเท่านั้น แต่ละอ็อบเจ็กต์มี ID เฉพาะตัว มีพื้นที่จัดเก็บข้อมูลถาวรของตัวเอง และประมวลผลคำขอทีละรายการ จึงเหมาะเป็นบ้านตามธรรมชาติสำหรับงานประสานงาน เช่น ตัวนับ (counter), การล็อก (lock), ห้องเกม, เซสชันแชท ในขณะที่ Worker ลืมทุกอย่างระหว่างคำขอแต่ละครั้ง (เรียกว่า "stateless" หรือไม่มีสถานะ) และทำงานได้พร้อมกันในหลายที่ Durable Object กลับจดจำและมีอยู่เพียงหนึ่งเดียว
จุดแข็ง
- รับประกันอินสแตนซ์เดียว — ไม่มีปัญหา race condition (การแย่งชิงจังหวะ) ข้ามชุดสำเนา
- มีพื้นที่จัดเก็บข้อมูลถาวรในตัว (ปัจจุบันใช้ SQLite เป็นฐาน) ที่อยู่ติดกับตัวอ็อบเจ็กต์
- เหมาะกับแอปแบบเรียลไทม์: WebSockets (การเชื่อมต่อสองทางแบบสดที่เปิดค้างไว้ ทำให้เซิร์ฟเวอร์ส่งอัปเดตได้ทันที), การแสดงสถานะออนไลน์ (presence), การทำงานร่วมกันแบบสด
- ความสอดคล้องของข้อมูลสูง (strong consistency): การอ่านหลังเขียน (read-after-write) ภายในอ็อบเจ็กต์เดียวกันเกิดขึ้นทันที
- Alarms ช่วยให้อ็อบเจ็กต์กำหนดเวลางานในอนาคตของตัวเองได้
ข้อแลกเปลี่ยน
- ประมวลผลแบบเธรดเดียวต่ออ็อบเจ็กต์ — อ็อบเจ็กต์ที่มีทราฟฟิกสูงอาจกลายเป็นคอขวด ควรแบ่งชาร์ด (shard) ตามคีย์
- ต้องคิดวิเคราะห์มากกว่า Worker ธรรมดา คุณต้องออกแบบขอบเขตของอ็อบเจ็กต์เอง
- พื้นที่จัดเก็บข้อมูลต่ออ็อบเจ็กต์มีขีดจำกัด ไม่ใช่ตัวแทนของ D1 (ฐานข้อมูล ) หรือ R2 (พื้นที่เก็บไฟล์) เมื่อต้องขยายสเกล
- มากเกินความจำเป็นสำหรับการจัดการคำขอแบบ stateless
เมื่อไรควรใช้
หยิบ Durable Objects มาใช้เมื่อคุณต้องการการประสานงานหรือสถานะต่อหน่วยข้อมูล เช่น ห้องแชท สถานะเกมแบบผู้เล่นหลายคน ตัวจำกัดอัตราคำขอ (rate limiter) การเลือกผู้นำ (leader election) หรือเอกสารสดที่ผู้ใช้หลายคนแก้ไขพร้อมกัน
เหมาะกับ vibe coding แค่ไหน
Durable Objects โดดเด่นสำหรับฟีเจอร์แบบเรียลไทม์ที่ปกติแล้วสร้างได้ยุ่งยาก และเอเจนต์สามารถร่างโครงคลาส การเชื่อมโยง (binding) และการจัดการ WebSocket ให้ได้ บอกให้มันรู้วิธีแบ่งชาร์ด — โดยทั่วไปคือหนึ่งอ็อบเจ็กต์ต่อหนึ่งห้อง ผู้ใช้ หรือเอกสาร — เพื่อไม่ให้อ็อบเจ็กต์เดียวต้องเรียงลำดับประมวลผลทราฟฟิกทั้งหมดของคุณ การตั้งค่าด้านล่างประกาศคลาส Durable Object พร้อมการโยกย้าย (migration)
# wrangler.toml
[[durable_objects.bindings]]
name = "ROOM"
class_name = "ChatRoom"
[[migrations]]
tag = "v1"
new_sqlite_classes = ["ChatRoom"]
npx wrangler deploy