رفتن به متن راهنما
همه‌ی راهنماها

محدودیت‌های Reqtide

کتابخانه امروز چه کاری می‌کند و چه کاری نمی‌کند: حالت، مهلت‌ها، تلاش مجدد، حالت مشترک، پلتفرم‌های آزموده‌شده، تعهدها و نسخه‌بندی.

برنامه Reqtide PHP 0.1.0آخرین بررسی زمان خواندن 8 دقیقه

در این صفحه

نخستین نسخه 0.1.0 (بتا) است. API بین نسخه‌های minor ممکن است تغییر کند و هر تغییر در changelog ثبت می‌شود. نصب را ببینید.

پیش از نخستین انتشار، هر نام یا رفتار عمومی ممکن است عوض شود. بستهٔ اصلی enaxon/reqtide حالت خود را در یک پردازه نگه می‌دارد. بسته‌های Redis و Guzzle دو بستهٔ جدا در همین مخزن‌اند و در حالت مشترک با Redis و درخواست‌های Guzzle با Reqtide توضیح داده شده‌اند.

پلتفرم‌های آزموده‌شده

آزمون‌ها و مثال‌ها در Docker و روی خط فرمان با PHP 8.3 و 8.4 و 8.5 اجرا شده‌اند. PHP-FPM را سه lane در CI پوشش می‌دهد، برای هر یک از PHP 8.3 و 8.4 و 8.5، با nginx، شش worker و Redis 8.2.10. این laneها این موارد را بررسی می‌کنند: حالت درون‌پردازه در هر درخواست از نو شروع می‌شود، حالت Redis بین درخواست‌ها مشترک است و زیر درخواست‌های هم‌زمان درست کار می‌کند، و یک سقف اجرای هم‌زمان (Bulkhead)، یک مهلت و یک تلاش مجدد هم آزموده می‌شود. اجرای client Guzzle زیر FPM، Apache و تنظیم‌های دیگر وب‌سرور انجام نشده است. بستهٔ Guzzle را با nginx 1.28 در نقش reverse proxy جلوی یک سرور آزمایشی هم اجرا کرده‌ایم: با بدنهٔ درخواست بافرشده و بافرنشده، با پاسخ chunked کند و با پاسخی که هیچ‌وقت تمام نمی‌شود (مهلت هر تلاش آن را قطع می‌کند). بدنهٔ streaming و proxyهای دیگر اجرا نشده‌اند. یک اجرای موفق محلی ادعای پشتیبانی یا آمادگی برای محیط تولید نیست.

دربارهٔ سرعت، ظرفیت یا تأخیر، Reqtide هیچ ادعایی ندارد. تنها اعداد موجود، هزینه‌های تقریبی در درخواست‌های Guzzle با Reqtide هستند. این اعداد یک بار روی یک لپ‌تاپ اندازه‌گیری شده‌اند و نوسان زیادی دارند.

کتابخانه چه کارهایی را نمی‌کند

موضوعبرای شما یعنی چه
حالت در یک پردازهٔ PHP می‌ماندزیر PHP-FPM، پایپ‌لاینی که داخل یک درخواست ساخته شود، هر درخواست را با سهمیهٔ کامل و مدار بسته شروع می‌کند. محدودیت‌ها بین درخواست‌ها، workerها و سرورها جمع نمی‌شوند. بستهٔ اصلی را جایی به کار ببرید که یک پردازه آن‌قدر عمر می‌کند که اهمیت داشته باشد، مثلاً worker، کار خط فرمان یا daemon. در غیر این صورت از بستهٔ Redis استفاده کنید.
بستهٔ اصلی سهمیهٔ مشترک نداردمحدودیت نرخ در بستهٔ اصلی فقط از یک پردازه محافظت می‌کند. اگر ده worker داشته باشید، هر کدام کل محدودیت را می‌گیرد. سهمیهٔ مشترک بستهٔ Redis را لازم دارد.
قطع نشدن callback در حال اجرامهلت کل بین مرحله‌ها بررسی می‌شود. اگر callable شما از مهلت کل بگذرد، تا آخر اجرا می‌شود و Reqtide نتیجهٔ دیرهنگام را با DeadlineExceeded گزارش می‌کند. runtime همگام نمی‌تواند مهلت هر تلاش را اعمال کند. شما آن را Cooperative اعلام می‌کنید و کد خودتان باید خودش متوقف شود.
اجاره (lease) در سقف هم‌زمانی توقف فیزیکی نیستوقتی اجاره تمام شود، callback ممکن است هنوز در حال اجرا باشد. مجوز دوباره آزاد می‌شود، اما کار متوقف نشده است. در این حالت فراخوانی دیگری می‌تواند فراتر از سقف bulkhead پذیرفته شود، و فراخوانی کندی که دیر شکست بخورد در مدارشکن شمرده نمی‌شود. به callable خودتان یک مهلت سخت جدا بدهید که از مهلت هر تلاش کوتاه‌تر باشد (مثلاً مهلت client HTTP یا پایگاه داده). بستهٔ Guzzle این کار را خودش انجام می‌دهد. اگر اجاره تمام شده باشد، در نتیجه diagnostic با نام concurrency_release_stale ثبت می‌شود. Reqtide پیش از هر ارسال، با ساعت یکنواخت (monotonic) خودش بررسی می‌کند که مجوز هم‌زمانی و probe نیمه‌باز هنوز بیشتر از تلاش دوام دارند. اگر نه، تلاش فرستاده نمی‌شود و با ownership_lease_insufficient تمام می‌شود. این بررسی محلی و محافظه‌کارانه است. توکن حصار (fence) نیست و مکثی که بعد از بررسی پیش بیاید دیده نمی‌شود. سامانه‌ای که باید از نگه‌دارندهٔ متوقف یا کند در امان بماند، حصار خودش را لازم دارد، مثلاً نسخه یا توکنی که خودش بررسی کند. Reqtide توکن حصار نمی‌دهد.
هزینهٔ نرخ پس داده نمی‌شودفراخوانی که بعد از پذیرش و پیش از ارسال لغو شود، باز هم یک واحد مصرف کرده است. سهمیهٔ مصرف‌شده با تعداد درخواست‌های ارسال‌شده یکی نیست.
اجرای دقیقاً یک‌بار تضمین نمی‌شودممکن است فراخوانی بیش از یک بار اجرا شود، یا یک بار و با نتیجهٔ نامعلوم. Reqtide آنچه را می‌داند گزارش می‌کند، اما نمی‌تواند عملیات شما را idempotent کند.
تلاش مجدد اجازهٔ شما را می‌خواهدتلاش مجدد به این‌ها نیاز دارد: اعلام شما که تکرار فراخوانی ایمن است، سهمیهٔ تلاش مجدد و کلاس استثنای قابل تلاش مجدد. Reqtide ایمنی را هرگز حدس نمی‌زند و از HTTP چیزی نمی‌داند.
پیش‌فرض وجود نداردهر مهلت، محدودیت، پنجره و تأخیری را خودتان انتخاب می‌کنید. عددهای مثال‌ها فقط رفتار را قابل‌مشاهده می‌کنند و توصیه نیستند.
تضمین failover وجود نداردبستهٔ Redis حالت خود را در حافظهٔ Redis نگه می‌دارد. راه‌اندازی دوباره بدون ماندگاری، flush یا failover آن را از بین می‌برد. تضمین‌های سخت‌گیرانهٔ failover خارج از دامنه‌اند. Sentinel، Cluster و Valkey پشتیبانی نمی‌شوند.
دامنهٔ کتابخانهکار Reqtide پیچیدن یک callable است. درخواست نمی‌فرستد، کار را برای بعد ذخیره نمی‌کند و از endpoint عمومی دفاع نمی‌کند.
در نسخهٔ اول نیستدرخواست‌های hedged، اعتبارسنجی دوبارهٔ کش، صف کارهای ناموفق و صف‌های انتظار.
کارهایی که Reqtide انجام نمی‌دهد و معنی آن‌ها برای کد شما.

تعهدهای Reqtide

این تعهدها برای بخش محلی کتابخانه برقرارند.

  • یک عملیات، یک مهلت کل. تلاش مجددی که تأخیرش در زمان باقی‌مانده جا نشود، شروع نمی‌شود.
  • استثناهای شما دست‌نخورده بیرون می‌آیند. رد کردن‌های Reqtide استثناهایی با نوع مشخص‌اند و دلیل را به شکل قابل‌خواندن برای ماشین همراه دارند. مدیریت خطا را ببینید.
  • بدون اجازهٔ شما هیچ چیز تلاش مجدد نمی‌شود. تلاش مجدد به اعلام ایمنی از طرف شما، سهمیهٔ تلاش مجدد و کلاس استثنای قابل تلاش مجدد نیاز دارد.
  • مجوز حداکثر یک بار آزاد می‌شود، یا با پایان اجاره تمام می‌شود. مجوز مدار و مجوز هم‌زمانی در حالت موفقیت، استثنا و لغو آزاد می‌شود. اگر آزادسازی شکست بخورد، Reqtide شکست را ثبت می‌کند و مجوز با پایان اجاره تمام می‌شود.
  • شکست حالت پنهان نمی‌شود. اگر backend حالت از کار بیفتد، فراخوانی محافظت‌شده اجرا نمی‌شود و Reqtide رفتار جایگزینی از خودش نمی‌سازد. اگر observer یا مرحلهٔ ثبت داخلی بعد از فراخوانی شکست بخورد، هرگز جای نتیجهٔ شما را نمی‌گیرد.
  • زمان یکنواخت است و با عدد صحیح محاسبه می‌شود. ساعتی که به عقب برود، هرگز سهمیه را دوباره پر نمی‌کند.
  • حالت محدود است. backend حافظه وقتی به سقف خود برسد، اول رکوردهای منقضی را آزاد می‌کند. بعد قدیمی‌ترین رکوردهای ثبت داخلی را که از چیزی محافظت نمی‌کنند بیرون می‌اندازد. بعد پارتیشن‌های تازه را رد می‌کند. مجوز فعال، موجودی سهمیه یا مدار باز را هرگز بیرون نمی‌اندازد.

بسته‌های جدا و برنامه‌های بعدی

موردوضعیت
حالت مشترک در Redis برای محدودیت نرخ، مدار، سقف هم‌زمانی، سهمیهٔ تلاش مجدد و دورهٔ انتظار (enaxon/reqtide-redis)بتا، روی Packagist. راهنما: حالت مشترک با Redis. در Docker و در CI با PHP 8.3 تا 8.5 روی خط فرمان و با Redis 7.4.11 و 8.2.10 اجرا شده است. Sentinel، Cluster و Valkey پشتیبانی نمی‌شوند. برای PHP-FPM همان lane در CI هست که پیش‌تر آمد.
یکپارچگی با Guzzle (enaxon/reqtide-guzzle)بتا، روی Packagist. راهنما: درخواست‌های Guzzle با Reqtide. در Docker و در CI با PHP 8.3 تا 8.5 روی خط فرمان و با Guzzle 7.15.5 اجرا شده است. PSR-18 پشتیبانی نمی‌شود و client زیر PHP-FPM اجرا نشده است.
پشتیبانی از PSR-18، PSR-15، Symfony HTTP و ثبت در فریم‌ورک‌هاممکن است بعداً بیاید
بسته‌های جدا و برنامه‌های مربوط به آن‌ها.

هر مورد برنامه‌ریزی‌شده ابتدا طراحی و آزمون جداگانهٔ خودش را لازم دارد.

نسخه‌بندی و سازگاری

  • نسخه‌بندی معنایی. پیش از 1.0، نسخهٔ minor هم می‌تواند API را تغییر دهد. هر ناسازگاری در CHANGELOG.md (opens in a new tab) فهرست می‌شود. از 1.0 به بعد فقط نسخهٔ major ناسازگاری ایجاد می‌کند.
  • یک نسخه برای هر سه بسته. enaxon/reqtide، enaxon/reqtide-redis و enaxon/reqtide-guzzle با هم منتشر می‌شوند. هر آداپتور دقیقاً همان نسخهٔ بستهٔ اصلی را می‌خواهد.
  • قول شامل چه چیزهایی می‌شود. کلاس‌ها، interfaceها، enumها، ثابت‌ها و متدهای عمومی که با @internal علامت نخورده‌اند. مقدارهای رشته‌ای ReasonCode و اعضای Problem JSON، از جمله شناسهٔ type آن، هم در این قول هستند. کد دلیل تازه ناسازگاری حساب نمی‌شود، پس کدهای ناشناخته را هم مدیریت کنید.
  • چه چیزهایی را در بر نمی‌گیرد. هر چیزی که با @internal علامت خورده، بخش‌های درونی ابزارهای کمکی آزمون، چیدمان کلیدهای Redis، اسکریپت‌های Lua و متن پیام‌ها. Reqtide نسخهٔ طرح registry را بررسی می‌کند و اگر هماهنگ نباشد آن را رد می‌کند.
  • ارث‌بری نکنید. کلاس‌ها final هستند. دو کلاس پایهٔ abstract استثنا برای catch کردن‌اند، نه برای ارث‌بری.