قوائم المهام في Go: نظرة عامة على مكتبات async و gocelery و machinery

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

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

ابدأ الدورة

قوائم المهام لـ Go (Golang): نظرة عامة وتطبيق عملي



في تطبيقات الويب الحديثة والخدمات المصغرة، غالبًا ما تنشأ الحاجة لتنفيذ عمليات كثيفة الاستخدام للموارد أو طويلة الأمد بشكل غير متزامن: إرسال البريد الإلكتروني، إنشاء التقارير، معالجة الصور، التفاعل مع واجهات برمجة التطبيقات الخارجية. لهذه الأغراض، تُستخدم قوائم المهام (task queues). في نظام Go (Golang) البيئي، توجد العديد من المكتبات الناضجة التي تسمح بتنفيذ هذه البنية. في هذه المقالة، سنستعرض ثلاث أدوات شائعة: machinery و gocelery و asynq، وسنحلل ميزاتها ونقدم أمثلة على الكود.



لماذا نحتاج إلى قائمة مهام في Go؟

تحل قائمة المهام العديد من المشكلات الرئيسية:

  • فصل المسؤوليات: لا ينتظر معالج HTTP اكتمال المهمة الخلفية.
  • قابلية التوسع: يمكنك تشغيل عدة عمال (worker) على خوادم مختلفة.
  • الموثوقية: عند فشل العامل، لا تُفقد المهمة ويمكن إعادة معالجتها.
  • الجدولة: إمكانية تأجيل تنفيذ المهمة لوقت محدد.


1. Machinery — مكتبة قوية ومرنة

Machinery هي قائمة مهام غير متزامنة لـ Go، مكتوبة من الصفر. تدعم عدة وسطاء (Redis، RabbitMQ، AWS SQS) ومخازن نتائج (Redis، MongoDB، Memcache). توفر Machinery واجهة برمجة تطبيقات غنية لإنشاء المهام والسلاسل (chains) والمجموعات (groups) والمهام المتكررة.



التثبيت ومثال

go get github.com/RichardKnox/machinery/v2


مثال على عامل وعميل بسيطين:

package main

import ( "github.com/RichardKnox/machinery/v2" "github.com/RichardKnox/machinery/v2/config" "github.com/RichardKnox/machinery/v2/tasks")

func main() { // التكوين باستخدام وسيط Redis cnf := &config.Config{ Broker: "redis://localhost:6379", DefaultQueue: "machinery_tasks", ResultBackend: "redis://localhost:6379", }

server, err := machinery.NewServer(cnf) if err != nil { panic(err) }

// تسجيل المهمة err = server.RegisterTasks(map[string]interface{}{ "add": func(a, b int) (int, error) { return a + b, nil }, }) if err != nil { panic(err) }

// تشغيل العامل worker := server.NewWorker("worker1", 2) // مهمتان متزامنتان go worker.Launch()

// إرسال المهمة task := tasks.Signature{ Name: "add", Args: []tasks.Arg{ {Type: "int", Value: 5}, {Type: "int", Value: 7}, }, } result, _ := server.SendTask(&task) // انتظار النتيجة if res, err := result.Get(10); err == nil { println("Result:", res.(int)) // Output: 12 }}


الإيجابيات: دعم الرسوم البيانية المعقدة للمهام، إمكانية إعادة المحاولة، المراقبة عبر واجهة ويب.

السلبيات: إعداد معقد نسبيًا، التوثيق أحيانًا يتأخر عن الكود.



2. Asynq — قائمة مهام حديثة مع واجهة مستخدم غنية

Asynq هي مكتبة من مطوري Google، تعتمد على Redis. توفر واجهة برمجة تطبيقات مريحة، جدولة مدمجة، أولويات للمهام، وواجهة ويب مدمجة للمراقبة. Asynq قيد التطوير النشط ولديها توثيق ممتاز.



التثبيت ومثال

go get github.com/hibiken/asynq


مثال على عميل وعامل بسيطين:

package main

import ( "context" "log" "github.com/hibiken/asynq")

// مهمة محددة النوعconst TypeEmailDelivery = "email:deliver"

func main() { // عميل لإرسال المهام client := asynq.NewClient(asynq.RedisClientOpt{Addr: "localhost:6379"}) defer client.Clos

توصيات