"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > بناء موازن تحميل بسيط في Go

بناء موازن تحميل بسيط في Go

تم النشر بتاريخ 2024-11-05
تصفح:193

تعتبر موازنات التحميل ضرورية في تطوير البرامج الحديثة. إذا سبق لك أن تساءلت عن كيفية توزيع الطلبات عبر خوادم متعددة، أو لماذا تبدو بعض مواقع الويب أسرع حتى أثناء حركة المرور الكثيفة، فغالبًا ما تكمن الإجابة في موازنة التحميل الفعالة.

Building a simple load balancer in Go

في هذا المنشور، سنقوم بإنشاء موازن تحميل تطبيق بسيط باستخدام خوارزمية Round Robin في Go. الهدف من هذا المنشور هو فهم كيفية عمل موازن الأحمال تحت الغطاء، خطوة بخطوة.

ما هو موازن التحميل؟

موازن التحميل هو نظام يقوم بتوزيع حركة مرور الشبكة الواردة عبر خوادم متعددة. فهو يضمن عدم تحمل أي خادم واحد الكثير من التحميل، مما يمنع الاختناقات ويحسن تجربة المستخدم بشكل عام. يضمن أسلوب موازنة التحميل أيضًا أنه في حالة فشل أحد الخوادم، يمكن إعادة توجيه حركة المرور تلقائيًا إلى خادم آخر متاح، وبالتالي تقليل تأثير الفشل وزيادة التوفر.

لماذا نستخدم موازن التحميل؟

  • توفر عالي: من خلال توزيع حركة المرور، تضمن موازنات التحميل أنه حتى في حالة فشل خادم واحد، يمكن توجيه حركة المرور إلى خوادم سليمة أخرى، مما يجعل التطبيق أكثر مرونة.
  • قابلية التوسع: تسمح لك موازنات التحميل بتوسيع نطاق نظامك أفقيًا عن طريق إضافة المزيد من الخوادم مع زيادة حركة المرور.
  • الكفاءة: تعمل على زيادة استخدام الموارد إلى الحد الأقصى من خلال ضمان مشاركة جميع الخوادم في عبء العمل بالتساوي.

خوارزميات موازنة التحميل

هناك خوارزميات واستراتيجيات مختلفة لتوزيع حركة المرور:

  • Round Robin: إحدى أبسط الطرق المتاحة. يقوم بتوزيع الطلبات بشكل تسلسلي بين الخوادم المتاحة. بمجرد وصوله إلى الخادم الأخير، يبدأ مرة أخرى من البداية.
  • المرجحة المستديرة روبن: تشبه خوارزمية روبن المستديرة باستثناء أنه يتم تعيين بعض الترجيح الرقمي الثابت لكل خادم. يتم استخدام هذا الوزن المحدد لتحديد الخادم لتوجيه حركة المرور.
  • الاتصالات الأقل: لتوجيه حركة المرور إلى الخادم مع الاتصالات الأقل نشاطًا.
  • تجزئة IP: حدد الخادم بناءً على عنوان IP الخاص بالعميل.

في هذا المنشور، سنركز على تنفيذ موازن التحميل Round Robin.

ما هي خوارزمية Round Robin؟

تقوم خوارزمية round robin بإرسال كل طلب وارد إلى الخادم التالي المتاح بطريقة دائرية. إذا تعامل الخادم A مع الطلب الأول، فسيتعامل الخادم B مع الطلب الثاني، وسيتعامل الخادم C مع الطلب الثالث. بمجرد أن تتلقى جميع الخوادم طلبًا، يبدأ مرة أخرى من الخادم أ.

الآن، دعنا ننتقل إلى التعليمات البرمجية ونبني موازن التحميل الخاص بنا!

الخطوة 1: تحديد موازن التحميل والخادم

type LoadBalancer struct {
    Current int
    Mutex   sync.Mutex
}

سنقوم أولاً بتحديد بنية LoadBalancer بسيطة مع الحقل الحالي لتتبع الخادم الذي يجب أن يتعامل مع الطلب التالي. يضمن Mutex أن الكود الخاص بنا آمن للاستخدام بشكل متزامن.

يتم تحديد رصيد كل خادم نقوم بتحميله من خلال بنية الخادم:

type Server struct {
    URL       *url.URL
    IsHealthy bool
    Mutex     sync.Mutex
}

هنا، كل خادم لديه عنوان URL وعلامة IsHealthy، التي تشير إلى ما إذا كان الخادم متاحًا للتعامل مع الطلبات.

الخطوة 2: جولة خوارزمية روبن

قلب موازن التحميل لدينا هو خوارزمية روبن الدائرية. وإليك كيفية العمل:

func (lb *LoadBalancer) getNextServer(servers []*Server) *Server {
    lb.Mutex.Lock()
    defer lb.Mutex.Unlock()

    for i := 0; i 


  • تتكرر هذه الطريقة عبر قائمة الخوادم بطريقة دائرية. إذا كان الخادم المحدد سليمًا، فإنه يقوم بإرجاع هذا الخادم للتعامل مع الطلب الوارد.
  • نحن نستخدم Mutex للتأكد من أن goroutine واحد فقط يمكنه الوصول إلى الحقل الحالي لموازن التحميل وتعديله في المرة الواحدة. وهذا يضمن أن خوارزمية round robin تعمل بشكل صحيح عند معالجة طلبات متعددة بشكل متزامن.
  • يحتوي كل خادم أيضًا على كائن Mutex خاص به. عندما نتحقق من حقل IsHealthy، نقوم بقفل Mutex الخاص بالخادم لمنع الوصول المتزامن من goroutines المتعددة.
  • بدون قفل Mutex، من الممكن أن يقوم goroutine آخر بتغيير القيمة مما قد يؤدي إلى قراءة بيانات غير صحيحة أو غير متسقة.
  • نقوم بإلغاء تأمين Mutex بمجرد قيامنا بتحديث الحقل الحالي أو قراءة قيمة حقل IsHealthy لإبقاء القسم الحرج صغيرًا قدر الإمكان. بهذه الطريقة، نستخدم Mutex لتجنب أي حالة سباق.

الخطوة 3: تكوين موازن التحميل

يتم تخزين التكوين الخاص بنا في ملف config.json، الذي يحتوي على عناوين URL للخادم وفترات التحقق من السلامة (المزيد حول ذلك في القسم أدناه).

type Config struct {
    Port                string   `json:"port"`
    HealthCheckInterval string   `json:"healthCheckInterval"`
    Servers             []string `json:"servers"`
}

قد يبدو ملف التكوين بالشكل التالي:

{
  "port": ":8080",
  "healthCheckInterval": "2s",
  "servers": [
    "http://localhost:5001",
    "http://localhost:5002",
    "http://localhost:5003",
    "http://localhost:5004",
    "http://localhost:5005"
  ]
}

الخطوة 4: الفحوصات الصحية

نريد التأكد من سلامة الخوادم قبل توجيه أي حركة مرور واردة إليها. ويتم ذلك عن طريق إرسال فحوصات صحية دورية إلى كل خادم:

func healthCheck(s *Server, healthCheckInterval time.Duration) {
    for range time.Tick(healthCheckInterval) {
        res, err := http.Head(s.URL.String())
        s.Mutex.Lock()
        if err != nil || res.StatusCode != http.StatusOK {
            fmt.Printf("%s is down\n", s.URL)
            s.IsHealthy = false
        } else {
            s.IsHealthy = true
        }
        s.Mutex.Unlock()
    }
}

كل بضع ثوانٍ (كما هو محدد في التكوين)، يرسل موازن التحميل طلب HEAD إلى كل خادم للتحقق مما إذا كان سليمًا. إذا كان الخادم معطلاً، يتم تعيين علامة IsHealthy على خطأ، مما يمنع توجيه حركة المرور المستقبلية إليه.

الخطوة 5: عكس الوكيل

عندما يتلقى موازن التحميل طلبًا، فإنه يعيد توجيه الطلب إلى الخادم التالي المتاح باستخدام الوكيل العكسي. في Golang، توفر حزمة httputil طريقة مدمجة للتعامل مع البروكسي العكسي، وسوف نستخدمها في الكود الخاص بنا من خلال وظيفة ReverseProxy:

func (s *Server) ReverseProxy() *httputil.ReverseProxy {
    return httputil.NewSingleHostReverseProxy(s.URL)
}
ما هو الوكيل العكسي؟

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

في حالتنا، يعمل موازن التحميل كوكيل عكسي، حيث يجلس أمام خوادم متعددة ويوزع طلبات HTTP الواردة عبرها.

الخطوة 6: التعامل مع الطلبات

عندما يقوم العميل بتقديم طلب إلى موازن التحميل، فإنه يحدد الخادم الصحي التالي المتاح باستخدام تطبيق خوارزمية round robin في وظيفة getNextServer ويقوم بإرسال طلب العميل إلى ذلك الخادم. في حالة عدم توفر خادم سليم، فإننا نرسل خطأ عدم توفر الخدمة إلى العميل.

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        server := lb.getNextServer(servers)
        if server == nil {
            http.Error(w, "No healthy server available", http.StatusServiceUnavailable)
            return
        }
        w.Header().Add("X-Forwarded-Server", server.URL.String())
        server.ReverseProxy().ServeHTTP(w, r)
    })

تقوم طريقة ReverseProxy بإرسال الطلب إلى الخادم الفعلي، ونقوم أيضًا بإضافة رأس مخصص X-Forwarded-Server لأغراض تصحيح الأخطاء (رغم أنه في الإنتاج، يجب علينا تجنب الكشف عن تفاصيل الخادم الداخلية مثل هذا).

الخطوة 7: بدء موازن التحميل

أخيرًا، نبدأ موازن التحميل على المنفذ المحدد:

log.Println("Starting load balancer on port", config.Port)
err = http.ListenAndServe(config.Port, nil)
if err != nil {
        log.Fatalf("Error starting load balancer: %s\n", err.Error())
}

العمل التجريبي

ليرة تركية؛ د

في هذا المنشور، قمنا ببناء موازن تحميل أساسي من الصفر في Golang باستخدام خوارزمية round robin. هذه طريقة بسيطة لكنها فعالة لتوزيع حركة المرور عبر خوادم متعددة والتأكد من قدرة نظامك على التعامل مع الأحمال الأعلى بكفاءة.

هناك الكثير مما يجب استكشافه، مثل إضافة فحوصات صحية متطورة، أو تنفيذ خوارزميات مختلفة لموازنة التحميل، أو تحسين تحمل الأخطاء. ولكن هذا المثال الأساسي يمكن أن يكون أساسًا متينًا يمكن البناء عليه.

يمكنك العثور على الكود المصدري في مستودع GitHub هذا.

بيان الافراج تم نشر هذه المقالة على: https://dev.to/vivekalhat/building-a-simple-load-balancer-in-go-70d?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3