P Pitchbar مستندات

عملیات

استقرار

Pitchbar با هدف اصلی استقرار روی Laravel Cloud ساخته شده است — پشته شامل FrankenPHP + Postgres + Redis است که Laravel Cloud به‌صورت بومی همه را ارائه می‌دهد. خودمیزبانی نیز پشتیبانی می‌شود اما اپراتور مسئولیت بیشتری دارد.

Laravel Cloud

فایل infra/cloud.yaml در مخزن، محیط‌ها و فرآیندها را شرح می‌دهد. ساختار کلی:

  • منطقه: به‌طور پیش‌فرض us-east. براساس نزدیکی به مشتریان خود انتخاب کنید.
  • فرآیند برنامه: FrankenPHP، حالت Octane. مقیاس‌پذیری خودکار.
  • فرآیند پردازشگر: Horizon، اختصاصی برای صف‌های crawl، index و default.
  • فرآیند Reverb: سرور WebSocket پایدار.
  • Postgres: نسخه ۱۶، با پشتیبان‌گیری روزانه.
  • Redis: نسخه ۷، پایدار.

محیط‌ها

محیطکاربرد
previewمحیط‌های موقت برای هر درخواست کشش. با باز شدن درخواست کشش به‌طور خودکار ایجاد و با ادغام/بسته شدن حذف می‌شود.
stagingطولانی‌مدت. پیکربندی را به تولید آینه می‌کند. برای تضمین کیفیت و تأیید پیش از انتشار استفاده می‌شود.
productionمحیط رو به مشتری. انتشار با شرط موفقیت CI + استقرار دستی انجام می‌شود.

اندازه‌گیری محاسبات برای نسخه v1

نقطه شروع. براساس ترافیک تنظیم کنید.

کامپوننتاندازهدلیل
برنامه (Octane)۲ نمونه × ۲ vCPU / ۲ گیگابایتمسیر اصلی بیشتر به خروجی جریانی هوش مصنوعی محدود است. دو نمونه برای در دسترس بودن بالا.
پردازشگر (Horizon)۲ نمونه × ۲ vCPU / ۲ گیگابایتتوان پردازش خودکار. براساس عمق صف مقیاس کنید.
Reverb۱ نمونه × ۱ vCPU / ۱ گیگابایتWebSocket، چسبنده.
Postgres۲ vCPU / ۴ گیگابایت / ۵۰ گیگابایت SSDتا حدود ۱۰ میلیون پیام راحت است.
Redis۱ گیگابایتنشست‌ها، صف، کش‌های سریع.

دامنه‌ها

معمولاً نیاز دارید:

  • دامنه اصلیapp.pitchbar.com برای برنامه مشتری / مدیریت.
  • دامنه ویجت — همان یا یک cdn.pitchbar.com جداگانه که /widget/widget.js را ارائه می‌دهد. بسته دارای یک پارامتر پرسش هش محتوا است، بنابراین کش‌گذاری تهاجمی ایمن است.
  • دامنه Reverbrealtime.pitchbar.com اگر فرآیند WebSocket را روی میزبان خود جدا کنید.

CI/CD

گردش‌های GitHub Actions در .github/workflows/:

  • tests.yml — راه‌اندازی PHP + Composer + مجموعه Pest (با داده‌های ساختگی، بدون شبکه).
  • lint.yml — Pint، ESLint، TypeScript tsc --noEmit.
  • widget.yml — ساخت بسته ویجت + بررسی بودجه حجم.

استقرارها با شرط موفقیت CI انجام می‌شوند؛ مرحله استقرار واقعی در Laravel Cloud (یا معادل هاستینگ شما) پیکربندی می‌شود، نه در فایل‌های فرآیند خودکار.

مهاجرت‌ها

Laravel Cloud php artisan migrate --force را در هر استقرار اجرا می‌کند. مهاجرت‌ها باید با نسخه‌های قبلی سازگار باشند — استقراری که یک ستون NOT NULL را به یک جدول پر شده اضافه می‌کند، نیاز به دو مرحله دارد:

  1. استقرار ۱: ستون را به‌صورت nullable اضافه کنید، داده‌های قبلی را پر کنید، کد برنامه شروع به نوشتن در آن می‌کند.
  2. استقرار ۲: ستون را به NOT NULL تغییر دهید.

همین قوانین برای تغییر نام و حذف نیز صدق می‌کند — هرگز در یک استقرار واحد، مخرب نباشید.

پشتیبان‌گیری

  • Postgres — تصاویر روزانه، به مدت ۳۰ روز نگهداری می‌شوند. بازیابی نقطه‌به‌زمان فعال است.
  • ذخیره‌ساز جستجوی هوشمند — Cloudflare Vectorize / Qdrant پشتیبان‌گیری داخلی ندارند؛ با ارسال مجدد IndexDocumentJob برای هر سند از جدول chunks بازسازی کنید. php artisan pitchbar:audit-vectors مغایرت بین جدول chunks و ذخیره‌ساز جستجوی هوشمند زنده را گزارش می‌دهد؛ اگر نیاز به تعمیر دارید، وظیفه را به ازای هر ردیف ارسال کنید.
  • R2 / ذخیره‌سازی اشیاء — نسخه‌گذاری فعال است.
  • اسرار برنامه — فروشگاه اسرار Laravel Cloud رمزگذاری شده است؛ از APP_KEY به‌طور جداگانه پشتیبان‌گیری کنید (کلید اصلی برای رمزگذاری app_settings است).

بازگشت به نسخه قبلی

Laravel Cloud نسخه قبلی را برای بازگشت فوری نگهداری می‌کند. برای بازگشت‌های ناسازگار با ساختار (نادر)، از آخرین تصویر بازیابی کنید.

خودمیزبانی

همان تنظیمات Docker که docker-compose.yml را اجرا می‌کند، با چند افزودنی برای تولید کار می‌کند:

  • پراکسی معکوس (Caddy یا Nginx) که TLS را در جلوی FrankenPHP خاتمه می‌دهد.
  • Postgres + Redis مدیریت‌شده (یا خودمدیریتی با کپی‌های با در دسترس بودن بالا).
  • Horizon به‌عنوان یک سرویس طولانی‌مدت که توسط systemd / یک مدیر فرآیند نظارت می‌شود.
  • Reverb به‌عنوان فرآیند خود.
  • کلکسیونر Sentry / OTEL که به‌صورت محلی اجرا می‌شود یا به یک سرویس ابری اشاره می‌کند.

میانبر composer run dev همه چیز را به‌صورت محلی (Octane، پردازشگر صف، Reverb، vite) برای توسعه راه‌اندازی می‌کند.

تیک پردازشگر صف از طریق cron پردازشگر Cloudflare

زمانی که زمان‌بندی درون‌خوشه‌ای در دسترس نباشد (هاست اشتراکی cPanel، VPS دستی بدون systemd، محیط‌های پیش‌نمایش Laravel Cloud)، یک پردازشگر خارجی Cloudflare می‌تواند هر ۶۰ ثانیه با ارسال درخواست POST به /api/v1/internal/queue-tick با کلید مخفی INTERNAL_QUEUE_TOKEN، صف را هدایت کند. این نقطه پایانی، php artisan queue:tick را فراخوانی می‌کند که یک بار queue:work --once --stop-when-empty را با تنظیمات پیش‌فرض زیر اجرا می‌کند:

  • --max-time=55 — حلقه قبل از مرز ۶۰ ثانیه‌ای تیک خارج می‌شود تا تیک‌های متوالی روی هم انباشته نشوند.
  • --job-timeout=120 — وظایف جداگانه (بیشتر CrawlPageJob / IndexDocumentJob) سقف ۲ دقیقه‌ای دارند.
  • صف‌های پردازش‌شده: crawl,index,default.

پردازشگر را از طریق php artisan pitchbar:deploy-cron-worker ساخته و استقرار دهید. بدنه پردازشگر از WorkerDeployer قالب‌بندی شده و با پارامترهای تیک درون‌ساخته ارسال می‌شود. پس از استقرار، INTERNAL_QUEUE_TOKEN را تغییر دهید.

قابلیت اطمینان خزنده

CrawlPageJob تا ۳ بار با فاصله‌های [30, 90, 180] ثانیه تلاش مجدد می‌کند. مسیر تلاش مجدد براساس کلاس خطا منشعب می‌شود:

  • محدودیت نرخ (429)release(60) بدون مصرف یک جایگاه تلاش مجدد. هر صفحه گسترش‌یافته معمولاً به همان موج 429 برخورد می‌کند؛ انتظار مشترک مفید است.
  • خطاهای دائمی — خطاهای DNS curl (6، 7)، رد اتصال، آدرس بدفرم، HTTP 400 / 401 / 403 / 404 / 410 / 451 — بلافاصله $this->fail() را فراخوانی کنید. بدون این، هر آدرس مرده بودجه کامل ۳ تلاش مجدد را می‌سوزاند و یک MaxAttemptsExceededException عمومی در لاگ‌ها تولید می‌کرد.
  • موقتی (5xx، نوسان شبکه) — تلاش مجدد معمولی با فاصله.

زمان‌بندی هر وظیفه ۹۰ ثانیه است؛ failOnTimeout=true به این معنی است که SIGTERM در زمان‌بندی همچنان failed() را اجرا کرده و ردیف منبع را با یک خطای قابل خواندن برای مشتری به failed تغییر می‌دهد.

زبان خود را انتخاب کنید