وصلکردن دیتابیس به Workerهای Cloudflare
خلاصهٔ کاملتر
این نوشته قسمت دومِ یه سری دربارهی استفاده از Cloudflare برای وباپه و اینبار سراغ راهاندازی دیتابیس میره. نویسنده از Postgres و ORMِ Drizzle استفاده میکنه، ولی تأکید میکنه که ماجرا ربطی به Drizzle نداره و هر جوری که کانکشن دیتابیست رو بسازی، همین مشکلها سرِ راهته. تمرکز مطلب رو خودِ Cloudflareست.
نویسنده اول روشِ «رایج ولی غلط برای Cloudflare» رو نشون میده: یه ماژول db.ts که یه Pool میسازه و export میکنه. مشکل اولش کارآییه؛ Workerها سریع و رویتقاضا بالا میان و اگه هر Worker یه کانکشن تازه به دیتابیس باز کنه، هم باز کردنش کنده و به cold-start اضافه میکنه، هم با زیاد شدن ترافیک تعداد کانکشنها به سقفِ دیتابیس میخوره. نویسنده میگه این مشکلِ هر پلتفرم مبتنی بر cloud function مثل AWS Lambda هم هست و راهحلش استخرِ کانکشنه، مثل PgBouncer که بهعنوان پروکسی جلوی دیتابیس میشینه.
مشکل دوم قانونِ خودِ Cloudflareست: منابع I/Oِ بلندعمر مثل connection poolِ Node بین درخواستها نباید زنده بمونن و مدلِ اجرایی Workers این اجازه رو نمیده، برای همین همین کد به خطای زمان اجرا میخوره.
راهحلِ کلودفلر برای بخش استخر، Hyperdriveه؛ یه استخرِ کانکشنِ ازپیشگرمشده. نویسنده میگه از داشبورد کلودفلر و بخش Storage and databases یه اتصال Hyperdrive میسازی (اینجا با PlanetScale)، بعد یه binding با آیدی مربوطه به فایل Wrangler اضافه میکنی و typingها رو با npx wrangler types بهروز میکنی. حالا بهجای اتصال مستقیم، از طریق آبجکت env به دیتابیس وصل میشی:
const pool = new Pool({
connectionString: env.HYPERDRIVE.connectionString,
});برای مشکل دومِ زندهموندن بین درخواستها، نویسنده از قابلیتِ global request middlewareِ خودِ TanStack Start استفاده میکنه. این میدلویر یه بار بهازای هر درخواست اجرا میشه، آبجکت دیتابیس رو همونجا میسازه و میذاره تو context، تا سرور-فانکشنها و روتهای API ازش استفاده کنن. نویسنده تأکید میکنه واژهی «کانکشن» رو شل به کار برده؛ عملاً Hyperdrive کانکشنهای واقعی TCP رو بین درخواستها استخر و بازاستفاده میکنه و هدف فقط اینه که منبعِ I/Oِ بلندعمری بین درخواستها نمونه.
آخرش هم یه نکتهی عملی میگه: اگه دیتابیست تو یه ناحیهی خاصه، بهتره وباپت رو هم به همون ناحیه پین کنی (با فیلد placement تو Wrangler). به گفتهی نویسنده نزدیک کردنِ Workerها به کاربر ولی دور کردنشون از دیتابیس، لِیتنسی کوئریها رو بالا میبره؛ خودش دیده یه کوئری ساده از حدود ۷ میلیثانیه (همناحیه با دیتابیس) به بیش از ۸۰ میلیثانیه (سواحل غربی آمریکا) پرید، یعنی حدود ۱۰ برابر.
نکات کلیدی:
- اتصال مستقیمِ Workers به دیتابیس دو مشکل داره: کندیِ باز کردن کانکشن و رسیدن به سقفِ تعداد کانکشنها
- Workers اجازه نمیده منابع I/Oِ بلندعمر مثل poolِ Node بین درخواستها زنده بمونن، وگرنه خطای زمان اجرا میگیری
- Hyperdrive یه استخرِ کانکشنِ ازپیشگرمشدهست که با یه binding تو Wrangler و از طریق env.HYPERDRIVE.connectionString وصل میشه
- با global request middlewareِ TanStack Start، آبجکت دیتابیس هر درخواست تازه ساخته و تو context گذاشته میشه
- وباپ رو همناحیه با دیتابیس نگه دار؛ فاصلهی ناحیهای میتونه لِیتنسی رو حدود ۱۰ برابر کنه




