قوائم الانتظار والمهام الخلفية في Rust: كتابة عامل غير متزامن في ساعة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

قوائم الانتظار والمهام الخلفية في Rust: كتابة عامل غير متزامن في ساعة

\n\n

هل تساءلت يومًا لماذا تتباطأ خدمة الويب الخاصة بك أحيانًا عندما ينقر المستخدم على زر "إرسال"؟ في أغلب الأحيان، يكون السبب هو العمليات الثقيلة التي يتم تنفيذها أثناء معالجة الطلب. إرسال البريد الإلكتروني، إنشاء PDF، معالجة الصور، التكامل مع واجهات برمجة التطبيقات الخارجية - كل هذه يجب أن تعيش حياتها الخاصة، بدلاً من حظر الرد على المستخدم. الحل هو قوائم الانتظار والمهام الخلفية.

\n\n

وإذا كنت معتادًا على حل هذه المشكلة في Python باستخدام Celery أو RQ، فستفاجأ في Rust. Rust ليس سريعًا فحسب - بل يوفر تحكمًا فريدًا في الذاكرة والعمليات، مما يسمح بكتابة عمال فائقين الكفاءة يستهلكون الحد الأدنى من الموارد. في هذه المقالة، سنشرح كيفية تنفيذ قوائم الانتظار والمهام الخلفية في Rust باستخدام المكتبات والأساليب الحديثة. ستتعلم كيفية بناء نظام موثوق لمعالجة المهام لن ينهار تحت الضغط.

\n\n

لماذا Rust للمهام الخلفية؟ ثلاث مزايا غير واضحة

\n\n

قبل الغوص في الكود، دعنا نفهم لماذا نستخدم Rust لقوائم الانتظار عندما تكون هناك حلول Python مجربة.

\n\n
    \n
  • أداء بدون جامع القمامة (GC). يمكن للعمال في Python أن "يتجمدوا" أثناء توقف جامع القمامة. Rust خالٍ من هذه المشكلة - أنت تتحكم في كل بايت من الذاكرة. هذا أمر بالغ الأهمية للأنظمة عالية التحميل حيث كل ملي ثانية مهمة.
  • \n
  • غير متزامن "خارج الصندوق". Rust مع tokio أو async-std يسمح بمعالجة آلاف الاتصالات المتزامنة على خيط واحد. يمكنك تشغيل مئات العمال دون الخوف من تجاوز الذاكرة.
  • \n
  • الموثوقية. نظام الملكية (ownership) في Rust يضمن عدم حدوث حالة سباق (data race) في العامل الخلفي. يتم معالجة الأخطاء بشكل صريح - لا توجد استثناءات مخفية.
  • \n
\n\n

الآن بعد أن فهمنا "لماذا"، ننتقل إلى "كيف".

\n\n

اختيار وسيط الرسائل: RabbitMQ مقابل Redis مقابل NATS

\n\n

قائمة انتظار المهام ليست مجرد قائمة. إنها وسيط رسائل يخزن المهام ويوزعها بين العمال. في نظام Rust البيئي، توجد كريتات (crates) لجميع الوسطاء المشهورين.

\n\n

RabbitMQ + lapin: الكلاسيكية في عالم قوائم الانتظار

\n\n

RabbitMQ هو وحش موثوق لمهام المؤسسات. توفر كريتة lapin واجهة برمجة تطبيقات غير متزامنة نظيفة. إنها مثالية إذا كنت بحاجة إلى توجيه الرسائل وضمانات التسليم والطوبولوجيات المعقدة.

\n\n

Redis + fred: البساطة والسرعة

\n\n

Redis هو سكين سويسري. باستخدام fred (عميل Redis غير متزامن)، يمكنك إنشاء قائمة انتظار من خلال القوائم (BLPOP) أو Pub/Sub. Redis مناسب تمامًا للسيناريوهات البسيطة: "أرسل مهمة - احصل على نتيجة".

\n\n

NATS + async-nats: وسيط خفيف الوزن

\n\n

NATS هو وسيط سحابي بأقل تأخير. إذا كنت بحاجة إلى معالجة ملايين الرسائل في الثانية على مثيلات صغيرة، فإن NATS هو خيارك.

\n\n

في هذه المقالة، سنركز على RabbitMQ لأنه يوفر التحكم الأكثر شمولاً. لكن المبادئ ستكون نفسها لأي وسيط.

\n\n

كتابة قائمة انتظار في Rust: مثال خطوة بخطوة

\n\n

لنقم بإنشاء نظام بسيط: مولد المهام (producer) وعامل (consumer). سنقوم بمعالجة مهام إرسال البريد الإلكتروني.

\n\n

الخطوة 1: إعداد المشروع والتبعيات

\n\n

أنشئ مشروعًا جديدًا:

\n\n
cargo new rust_queue_demo\ncd rust_queue_demo
\n\n

أضف التبعيات إلى Cargo.toml:

\n\n
[dependencies]\ntokio = { version = "1", features = ["full"] }\nlapin = "2.4"\nserde = { version = "1", features = ["derive"] }\nserde_json = "1"\ntracing = "0.1"\ntracing-subscriber = "0.3"\nanyhow = "1"
\n\n

نستخدم tokio كبيئة تشغيل غير متزامنة، و lapin لـ RabbitMQ، و serde لتسلسل المهام، و tracing للتسجيل.

\n\n

الخطوة 2: تعريف بنية المها

المدونات

توصيات الكتب