طوابير المهام والموازنة
1) لماذا قوائم انتظار المهام
قائمة انتظار العمل/قائمة انتظار العمل تفصل المصنعين وفناني الأداء حسب الوقت والسرعة:- قمم Smoothes: عازل بين النظم الفرعية الأمامية والثقيلة.
- تثبيت جيش تحرير السودان: الأولويات وعزل فئات الأحمال.
- يبسط تحمل الخطأ: إعادة التصوير، DLQ، إعادة التدريج.
- المقاييس أفقيًا: أضف العمال دون تغيير واجهة برمجة التطبيقات.
المجالات النموذجية: معالجة الدفع، والإخطارات، وتوليد التقارير/الوسائط، والمعالجة البريدية ETL/ML، والتكامل مع واجهات برمجة التطبيقات الخارجية.
2) المفاهيم النموذجية والأساسية
المنتج: ينشر المهمة (الحمولة + البيانات الوصفية: مفتاح الخصوصية، الأولوية، الموعد النهائي).
قائمة الانتظار/الموضوع: عازل/سجل المهام.
العامل: يأخذ مهمة أو يعالج أو يؤكد (ack) أو يعود بخطأ.
مهلة الرؤية/الإيجار: مهام «الإيجار» طوال مدة المعالجة، بعد - إعادة التسليم التلقائي.
DLQ (قائمة انتظار الحروف الميتة): مهام «الدفن» بعد حد المحاولات/الأخطاء الفادحة.
حد السعر/العملة المتزامنة: حدود الاستهلاك لكل عامل/لكل قائمة انتظار/لكل مستأجر.
- سحب: العامل نفسه يطلب المهمة (جرعة الحمل).
- الدفع: الوسيط يزعج ؛ بحاجة إلى الحماية من «ملء» العمال الضعفاء.
3) دلالات التسليم والتأكيد
على الأكثر مرة واحدة: لا توجد عمليات إعادة طباعة ؛ أسرع، ولكن خسارة محتملة.
مرة واحدة على الأقل (الافتراضي لمعظم قوائم الانتظار): التكرارات ممكنة → مطلوب المعالج الخصوصية.
بشكل فعال مرة واحدة بالضبط: تم تحقيقه على مستوى التطبيق (الخصوصية، التخلص، المعاملات/صندوق الخروج). يمكن للوسيط أن يساعد، ولكن ليس «رصاصة سحرية».
- Ack/Nack: نتيجة واضحة.
- Requeue/Retry: с backoff + jitter.
- رسالة سم - أرسل إلى DLQ.
4) الموازنة والتخطيط
4. 1 التسلسل والخوارزميات
الفيفو: بسيط ويمكن التنبؤ به.
قائمة الانتظار ذات الأولوية: الفئات ذات الأولوية (P0... ف-3).
WRR/WSR (الجولة المرجحة - Robin/Random): تشارك وحدة المعالجة المركزية/تنقل بين الفئات.
WFQ/DRR (مشابه لقوائم الانتظار «العادلة» في الشبكات): الأسهم لكل مستأجر/عميل.
الموعد النهائي/EDF: للمهام ذات المواعيد النهائية.
الحصة العادلة: الحد من «الجيران الصاخبين» (حصص المستأجر).
4. 2 تدفقات التجهيز
رحلة واحدة/التحام: دمج المهام الرئيسية المكررة.
الحدود القصوى للتزامن: قيود صارمة على التوازي حسب نوع المهمة/التكامل (واجهات برمجة التطبيقات الخارجية).
4. 3 الجغرافيا والتجزئة
القطع حسب المفتاح (المستأجر/الهوية) → موقع البيانات، ترتيب مستقر داخل الشظايا.
المخابئ/الموارد اللاصقة: توجيه التجزئة للعمال ذوي الحالة «الملحقة».
5) Retrai، backoff و DLQ
التراجع الأسي + النبض: «الأساس 2 ^ محاولة ± عشوائية».
الحد الأقصى للمحاولات والموعد النهائي الإجمالي (وقت الموت) لكل مهمة.
تصنيف الأخطاء: «قابل للتجربة» (الشبكة/الحد)، «غير قابل للتجربة» (التصديق/حظر الأعمال).
قائمة انتظار السيارات/التأخير: المهام المؤجلة (على سبيل المثال، كرر بعد 15 دقيقة).
سياسة DLQ: تأكد من تحديد أين وتحت أي ظروف تصل الرسالة «السامة» ؛ توفير معالج جديد.
6) الفراغ والتفريط
مفتاح الخصوصية في المهمة ؛ متجر (Redis/DB) مع TTL لآخر مفاتيح N:- شوهد → تخطي/دمج/مخبأ النتائج.
- المفاتيح الطبيعية: استخدم 'order _ id/ payment_id' بدلاً من UUIDs العشوائية.
- Outbox - سجل حقيقة المهمة وحالتها في معاملة قاعدة بيانات واحدة مع معاملة تجارية.
- مرة واحدة بالضبط باللون الأزرق: "UPSERt' بالمفتاح، إصدار،" مرة واحدة على الأقل "في قائمة الانتظار + الخصوصية في قاعدة البيانات.
7) فصول الإيجار المتعدد و SLA
قوائم الانتظار/التدفقات المنفصلة حسب الفصل: «حرجة»، «قياسية»، «كبيرة».
الحصص والأولويات لكل مستأجر (الذهب/الفضة/البرونز).
العزلة: تخصيص مجموعات من العمال تحت الرتبة ف-0 ؛ الخلفية - في مجموعة/عقد منفصلة.
التحكم في القبول: لا تقبل أكثر مما يمكنك معالجته في المواعيد النهائية.
8) عمال القياس الذاتي
مقاييس التحجيم: عمق قائمة الانتظار، ومعدل الوصول، ووقت المعالجة، والمواعيد النهائية لجيش تحرير السودان.
KEDA/Horizontal Pod Autoscaler: SQS/Rabbit/Kafka محفزات العمق المتأخر.
العوامل المقيدة: يحد السعر الخارجي من واجهات برمجة التطبيقات، وقاعدة البيانات (لا تدمر الطرف الخلفي).
9) خيارات وأنماط التكنولوجيا
9. 1 RabbitMQ/AMQP
التبادلات: مباشرة/موضوعية/معجبة ؛ قوائم الانتظار с ack/tl/DLQ (تبادل الحروف الميتة).
ينظم بريفتش (QoS) «عدد المهام على العامل».
ini x-dead-letter-exchange=dlx x-dead-letter-routing-key=jobs.failed x-message-ttl=60000
9. 2 SQS (ونظائرها)
Visibility Timeout، DelaySeconds، RedrivePolicy (DLQ).
الخصوصية - على التطبيق (طاولة التخلص).
الحدود: 1-10 وظائف ؛ التركيز على الكدمات الحمقاء.
9. 3 كافكا/ناتس جيت ستريم
بالنسبة لخطوط الأنابيب الواسعة النطاق: الإنتاجية العالية والاحتفاظ/إعادة التشغيل.
قائمة انتظار المهام فوق جذوع الأشجار: مهمة واحدة = رسالة واحدة ؛ عامل واحد لكل مفتاح مراقبة من خلال/تقسيم الموضوع.
Retrai: موضوعات فردية/لواحق الموضوع مع التراجع.
9. 4 قوائم انتظار Redis (Sidekiq/Resque/Bull/Celery-Redis)
الانخفاض الشديد في زمن الانتقال ؛ مراقبة الاستقرار (RDB/AOF)، وإعادة تجربة المفاتيح ومفاتيح القفل للرحلة الواحدة.
مناسب للمهام «الخفيفة»، وليس للتراجع طويل الأجل.
9. 5 أطر عمل
الكرفس (Python)، Sidekiq (Ruby)، RQ/BullMQ (Node)، Huey/Resque - إعادة تشغيل جاهزة، جداول، برامج وسيطة، مقاييس.
10) مخططات التوجيه والموازنة
Round-Robin: بالتساوي ولكن لا يأخذ في الاعتبار «شدة» المهام.
الموارد العادية المرجحة: التوزيع حسب طاقة العامل/المجموعة.
Fair/Backpressure-aware: يلتقط العامل مهمة جديدة فقط عندما يكون جاهزًا.
الممرات ذات الأولوية: طوابير منفصلة لكل فئة ؛ يقرأ العمال بالترتيب [P0→... →Pn] إذا كان متاحا.
Hash-routing: "hash (key)% shards' - للمعالجة الحكومية/المخبأة.
11) المهلات والمواعيد النهائية واتفاقات SLAs
مهلة لكل مهمة: «عقد إيجار» داخلي للعمل (في رمز العامل) ≤ وقت الرؤية للوسيط.
الموعد النهائي العالمي: المهمة غير منطقية بعد وقت T - NACK→DLQ.
إدراك الميزانية: تقليل العمل (الاستهلاك) عند اقتراب الموعد النهائي (نتائج جزئية).
12) إمكانية الرصد والإدارة
12. 1 مقاييس
«queue _ depth», «rescue _ rate», «service _ rate», «lag» (Kafka), «invisible _ messages» (SQS).
«success/failed/return _ total», «retry _ traits», «dlq _ in _ total», «processing _ time _ ms {p50, p95, p99}».
«ideputency _ hit _ rate», «dedup _ drops _ total», «poison _ total».
12. 2 جذوع الأشجار/التعقب
الارتباط: «job _ id»، «correlation _ id»، مفتاح التفريغ.
علامة 'retry/backoff/dlq' كأحداث ؛ الربط من الطلب الأولي الممتد.
12. 3 لوحات معلومات/تنبيهات
المشغلات: العمق> X، p99> SLO، نمو DLQ، المهام العالقة (الرؤية منتهية الصلاحية> N)، المفاتيح الساخنة.
13) السلامة والامتثال
عزل المستأجر: قوائم الانتظار الفردية/مساحات المفاتيح، ACLs، الحصص.
التشفير عند النقل و/أو «عند الراحة».
والتقليل إلى أدنى حد في الحمولة ؛ hash/ID بدلاً من PII الخام.
الأسرار: لا تضع الرموز في هيئة المهام، استخدم القبو/الحكام.
14) الأنماط المضادة
Retrai بدون الخدعة → عمليات/أموال مكررة «مرتين».
طابور عملاق واحد «لكل شيء» → لا عزلة، تأخيرات لا يمكن التنبؤ بها.
Retrai لا نهاية له بدون DLQ → مهام «سامة» أبدية.
وقت الرؤية <وقت المعالجة → النسخ المتتالية.
حمولة كبيرة في قائمة الانتظار → الشبكة/ضغط الذاكرة ؛ من الأفضل تخزين كائن في محجر ونقل رابط.
نموذج الدفع بدون ضغط خلفي → يختنق العمال.
مزج المهام الحرجة والجملة في مجموعة واحدة من العمال.
15) قائمة التنفيذ المرجعية
- تصنيف المهام حسب جيش تحرير السودان (P0/P1/P2) والحجم.
- اختر وسيطًا/إطارًا بالدلالات المرغوبة والاحتفاظ بها.
- مفاتيح التصميم والأولويات والتوجيه (التجزئة/الشظايا/الممرات ذات الأولوية).
- قم بتمكين التراجع + إعادة تشغيل jitter وسياسة DLQ.
- تطبيق الخصوصية (المفاتيح، المزعجة، المتجر مع TTL).
- حدد المهلة الزمنية لكل مهمة والوضوح والموعد النهائي العام.
- الحد من التزامن والسعر حسب عمليات الإدماج/المستأجرين.
- التدرج التلقائي للعمق/التأخر مع الصمامات.
- المقاييس/التعقب/التنبيهات ؛ كتيبات عن «العاصفة» وفيضان DLQ.
- اختبارات الفشل: سقوط العامل، الرسالة «السامة»، الحمل الزائد، المهام الطويلة.
16) تشكيلات العينة والرمز
16. 1 الكرفس (Redis/Rabbit) - التدفق الأساسي
python app = Celery("jobs", broker="amqp://...", backend="redis://...")
app.conf.task_acks_late = True # ack после выполнения app.conf.broker_transport_options = {"visibility_timeout": 3600}
app.conf.task_default_retry_delay = 5 app.conf.task_time_limit = 300 # hard timeout
@app.task(bind=True, autoretry_for=(Exception,), retry_backoff=True, retry_jitter=True, max_retries=6)
def process_order(self, order_id):
if seen(order_id): return "ok" # идемпотентность do_work(order_id)
mark_seen(order_id)
return "ok"
16. 2 RabbitMQ - DLQ/TTL
ini x-dead-letter-exchange=dlx x-dead-letter-routing-key=jobs.dlq x-message-ttl=600000 # 10 минут x-max-priority=10
16. 3 كافكا - إعادة التدوير حسب المستوى
orders -> orders.retry.5s -> orders.retry.1m -> orders.dlq
(التحويل مع تأخر التسليم عبر الجدولة/المستهلك.)
16. 4 NATS JetStream - تراجع с المستهلك
bash nats consumer add JOBS WORKERS --filter "jobs.email" \
--deliver pull --ack explicit --max-deliver 6 \
--backoff "1s,5s,30s,2m,5m"
17) الأسئلة الشائعة
س: متى تختار الدفع مقابل السحب ؟
ج: يعطي السحب ضغطًا خلفيًا طبيعيًا وتوازنًا «صادقًا» ؛ يكون الدفع أسهل بسرعات منخفضة وعندما تكون هناك حاجة إلى الحد الأدنى من TTFB، ولكنه يتطلب محددات.
س: كيف تتجنب المفتاح الساخن ؟
ج: Shard حسب المفتاح المركب ('order _ id% N')، puffer and bach-process، أدخل حدود لكل مفتاح.
س: هل من الممكن «مرة واحدة بالضبط» ؟
ج: عمليا - من خلال الحمق وصندوق المعاملات الخارجي. نادرًا ما يكون «رياضيًا» تمامًا مرة واحدة قابلاً للتحقيق ومكلفًا على طول الطريق.
س: أين تخزن ملحقات المهام الكبيرة ؟
أ: في تخزين الأجسام (S3/GCS)، وفي المهمة - الوصلة/الهوية ؛ يقلل الضغط على السمسار والشبكة.
س: كيف تختار TTL/الرؤية ؟
ج: الرؤية ≥ p99 وقت المعالجة × المخزون 2-3 ×. مهام TTL - مهلة عمل أقل.
18) المجاميع
نظام الانتظار القوي هو التوازن بين دلالات التسليم والأولويات والقيود. تصميم المفاتيح والتوجيه، وضمان الغباء، وإعادة الدرج مع التراجع و DLQ، وتخصيص الموارد لفئات SLA ومراقبة المقاييس. ثم ستكون عمليات خلفيتك متوقعة ومستقرة وقابلة للتطوير - لا توجد مفاجآت تحت القمم.