موازنة مبسطة لأحمال NGINX مع Loadcat
نشرت: 2022-03-11غالبًا ما تتطلب تطبيقات الويب المصممة لتكون قابلة للتوسع أفقيًا عقدًا واحدًا أو أكثر من عقد موازنة الأحمال. الغرض الأساسي منها هو توزيع حركة المرور الواردة عبر خوادم الويب المتاحة بطريقة عادلة. يمكن أن تكون القدرة على زيادة السعة الإجمالية لتطبيق الويب ببساطة عن طريق زيادة عدد العقد وجعل موازنات التحميل تتكيف مع هذا التغيير مفيدة للغاية في الإنتاج.
NGINX هو خادم ويب يوفر ميزات موازنة تحميل عالية الأداء ، من بين العديد من إمكانياته الأخرى. تتوفر بعض هذه الميزات فقط كجزء من نموذج الاشتراك الخاص بهم ، ولكن الإصدار المجاني والمفتوح المصدر لا يزال غنيًا جدًا بالميزات ويأتي مع أهم ميزات موازنة التحميل خارج الصندوق.
في هذا البرنامج التعليمي ، سوف نستكشف الآليات الداخلية لأداة تجريبية تسمح لك بتكوين مثيل NGINX الخاص بك أثناء الطيران للعمل كموازن تحميل ، واستخراج جميع التفاصيل الدقيقة لملفات تكوين NGINX من خلال توفير شبكة ويب أنيقة- واجهة المستخدم القائمة. الغرض من هذه المقالة هو إظهار مدى سهولة البدء في إنشاء مثل هذه الأداة. ومن الجدير بالذكر أن مشروع Loadcat مستوحى بشكل كبير من NodeBalancers من Linode.
NGINX والخوادم والمنبع
أحد أكثر استخدامات NGINX شيوعًا هو إجراء وكلاء عكسي للطلبات من العملاء إلى تطبيقات خادم الويب. على الرغم من أن تطبيقات الويب المطورة بلغات البرمجة مثل Node.js و Go يمكن أن تكون خوادم ويب مكتفية ذاتيًا ، فإن وجود وكيل عكسي أمام تطبيق الخادم الفعلي يوفر العديد من الفوائد. يمكن أن تبدو كتلة "الخادم" لحالة استخدام بسيطة مثل هذه في ملف تكوين NGINX كما يلي:
server { listen 80; server_name example.com; location / { proxy_pass http://192.168.0.51:5000; } }
سيؤدي ذلك إلى جعل NGINX يستمع على المنفذ 80 لجميع الطلبات التي تشير إلى example.com ويمرر كل منها إلى بعض تطبيقات خادم الويب التي تعمل على 192.168.0.51:5000. يمكننا أيضًا استخدام عنوان IP للاسترجاع 127.0.0.1 هنا إذا كان خادم تطبيق الويب يعمل محليًا. يرجى ملاحظة أن المقتطف أعلاه يفتقر إلى بعض التعديلات الواضحة التي تُستخدم غالبًا في تكوين الوكيل العكسي ، ولكن يتم الاحتفاظ بها بهذه الطريقة للإيجاز.
ولكن ماذا لو أردنا موازنة جميع الطلبات الواردة بين مثيلين من نفس خادم تطبيق الويب؟ هذا هو المكان الذي يصبح فيه التوجيه "upstream" مفيدًا. في NGINX ، مع التوجيه "المنبع" ، من الممكن تحديد عدة عقد خلفية والتي من بينها سوف تقوم NGINX بموازنة جميع الطلبات الواردة. علي سبيل المثال:
upstream nodes { server 192.168.0.51:5000; server 192.168.0.52:5000; } server { listen 80; server_name example.com; location / { proxy_pass http://nodes; } }
لاحظ كيف قمنا بتعريف كتلة "upstream" ، تسمى "nodes" ، تتكون من خادمين. يتم تحديد كل خادم بواسطة عنوان IP ورقم المنفذ الذي يستمعون عليه. مع هذا ، يصبح NGINX موازن تحميل في أبسط أشكاله. بشكل افتراضي ، ستقوم NGINX بتوزيع الطلبات الواردة بطريقة round-robin ، حيث سيتم وكيل أول واحد إلى الخادم الأول ، والثاني إلى الخادم الثاني ، والثالث إلى الخادم الأول وما إلى ذلك.
ومع ذلك ، لدى NGINX الكثير لتقدمه عندما يتعلق الأمر بموازنة التحميل. يسمح لك بتعريف الأوزان لكل خادم ، ووضع علامة عليها على أنها غير متاحة مؤقتًا ، واختيار خوارزمية موازنة مختلفة (على سبيل المثال ، هناك خوارزمية تعمل بناءً على تجزئة IP للعميل) ، وما إلى ذلك. تم توثيق جميع هذه الميزات وتوجيهات التكوين بشكل جيد في nginx.org . علاوة على ذلك ، يسمح NGINX بتغيير ملفات التكوين وإعادة تحميلها أثناء التنقل دون أي انقطاع تقريبًا.
إن قابلية تكوين NGINX وملفات التكوين البسيطة تجعل من السهل حقًا تكييفها مع العديد من الاحتياجات. وهناك عدد كبير من البرامج التعليمية الموجودة بالفعل على الإنترنت والتي تعلمك بالضبط كيفية تكوين NGINX كموازن تحميل.
Loadcat: أداة تكوين NGINX
هناك شيء رائع حول البرامج التي بدلاً من القيام بشيء ما بمفردها ، قم بتهيئة أدوات أخرى للقيام بذلك نيابة عنها. إنهم لا يفعلون الكثير بخلاف ربما أخذ مدخلات المستخدم وإنشاء بعض الملفات. معظم الفوائد التي تجنيها من هذه الأدوات هي في الواقع ميزات أدوات أخرى. لكنهم بالتأكيد يجعلون الحياة سهلة. أثناء محاولتي إعداد موازن تحميل لأحد مشاريعي الخاصة ، تساءلت: لماذا لا تفعل شيئًا مشابهًا لـ NGINX وقدرات موازنة الحمل الخاصة به؟
ولدت لودكات!
لا تزال Loadcat ، التي تم إنشاؤها باستخدام Go ، في مهدها. في هذه اللحظة ، تتيح لك الأداة تكوين NGINX لموازنة التحميل وإنهاء SSL فقط. يوفر للمستخدم واجهة مستخدم رسومية بسيطة على شبكة الإنترنت. بدلاً من استعراض الميزات الفردية للأداة ، دعنا نلقي نظرة خاطفة على ما هو تحتها. كن على علم ، إذا كان شخص ما يستمتع بالعمل مع ملفات تكوين NGINX يدويًا ، فقد يجد قيمة قليلة في هذه الأداة.
هناك عدة أسباب وراء اختيار Go كلغة برمجة لذلك. أحدها هو أن Go ينتج ثنائيات مجمعة. يتيح لنا ذلك إنشاء Loadcat وتوزيعه أو نشره كثنائي مترجم إلى الخوادم البعيدة دون القلق بشأن حل التبعيات. شيء يبسط عملية الإعداد بشكل كبير. بالطبع ، يفترض النظام الثنائي أن NGINX مثبت بالفعل وأن ملف وحدة systemd موجود له.
إذا لم تكن مهندس Go ، فلا داعي للقلق على الإطلاق. Go سهل وممتع للغاية لتبدأ به. علاوة على ذلك ، فإن التنفيذ نفسه بسيط للغاية ويجب أن تكون قادرًا على المتابعة بسهولة.
هيكل
اذهب إلى أدوات البناء ، وفرض بعض القيود على كيفية هيكلة تطبيقك وترك الباقي للمطور. في حالتنا ، قمنا بتقسيم الأشياء إلى عدد قليل من حزم Go بناءً على أغراضها:
- cfg: يقوم بالتحميل والتحليل وتوفير قيم التكوين
- cmd / loadcat: الحزمة الرئيسية ، تحتوي على نقطة الدخول ، وتجميعها في ثنائي
- البيانات: تحتوي على "نماذج" ، وتستخدم مفتاحًا مضمنًا / مخزنًا للقيمة من أجل الثبات
- القطط: يحتوي على وظائف أساسية ، مثل إنشاء ملفات التكوين ، وآلية إعادة التحميل ، وما إلى ذلك.
- ui: يحتوي على القوالب ومعالجات URL وما إلى ذلك.
إذا ألقينا نظرة فاحصة على بنية الحزمة ، خاصةً داخل حزمة القطط ، فسوف نلاحظ أن جميع التعليمات البرمجية الخاصة بـ NGINX قد تم الاحتفاظ بها داخل حزمة فرعية feline / nginx. يتم ذلك حتى نتمكن من الاحتفاظ ببقية منطق التطبيق العام وتوسيع نطاق الدعم لموازن التحميل الأخرى (مثل HAProxy) في المستقبل.
نقطة الدخول
دعونا نبدأ من الحزمة الرئيسية لـ Loadcat ، الموجودة داخل "cmd / loadcatd". الوظيفة الرئيسية ، نقطة دخول التطبيق ، تقوم بثلاثة أشياء.
func main() { fconfig := flag.String("config", "loadcat.conf", "") flag.Parse() cfg.LoadFile(*fconfig) feline.SetBase(filepath.Join(cfg.Current.Core.Dir, "out")) data.OpenDB(filepath.Join(cfg.Current.Core.Dir, "loadcat.db")) defer data.DB.Close() data.InitDB() http.Handle("/api", api.Router) http.Handle("/", ui.Router) go http.ListenAndServe(cfg.Current.Core.Address, nil) // Wait for an “interrupt“ signal (Ctrl+C in most terminals) }
لتبسيط الأمور وتسهيل قراءة الشفرة ، تمت إزالة جميع رموز معالجة الأخطاء من المقتطف أعلاه (وأيضًا من المقتطفات لاحقًا في هذه المقالة).
كما يمكنك أن تقول من الكود ، فإننا نقوم بتحميل ملف التكوين بناءً على علامة سطر الأوامر "-config" (والتي يتم تعيينها افتراضيًا على "loadcat.conf" في الدليل الحالي). بعد ذلك ، نقوم بتهيئة مكونين ، وهما الحزمة الأساسية وقاعدة البيانات. أخيرًا ، بدأنا تشغيل خادم ويب لواجهة المستخدم الرسومية المستندة إلى الويب.
إعدادات
من المحتمل أن يكون تحميل ملف التكوين وتحليله أسهل جزء هنا. نحن نستخدم TOML لتشفير معلومات التكوين. هناك حزمة تحليل TOML أنيقة متاحة لـ Go. نحتاج إلى القليل جدًا من معلومات التكوين من المستخدم ، وفي معظم الحالات يمكننا تحديد الإعدادات الافتراضية المعقولة لهذه القيم. يمثل الهيكل التالي هيكل ملف التكوين:
struct { Core struct { Address string Dir string Driver string } Nginx struct { Mode string Systemd struct { Service string } } }
وإليك ما قد يبدو عليه ملف "loadcat.conf" النموذجي:
[core] address=":26590" dir="/var/lib/loadcat" driver="nginx" [nginx] mode="systemd" [nginx.systemd] service="nginx.service"
كما نرى ، هناك تشابه بين بنية ملف التكوين المشفر TOML والبنية الموضحة أعلاه. تبدأ حزمة الضبط بتعيين بعض الإعدادات الافتراضية المعقولة لحقول معينة من البنية ثم تحلل ملف التكوين فوقها. في حالة فشلها في العثور على ملف التكوين في المسار المحدد ، فإنه يقوم بإنشاء واحد ، وتفريغ القيم الافتراضية فيه أولاً.
func LoadFile(name string) error { f, _ := os.Open(name) if os.IsNotExist(err) { f, _ = os.Create(name) toml.NewEncoder(f).Encode(Current) f.Close() return nil } toml.NewDecoder(f).Decode(&Current) return nil }
البيانات والثبات
قابل بولت. مخزن مفتاح / قيمة مضمن مكتوب في Pure Go. تأتي كحزمة بواجهة برمجة تطبيقات بسيطة للغاية ، وتدعم المعاملات خارج الصندوق ، وهي سريعة بشكل مزعج .
ضمن بيانات الحزمة ، لدينا هياكل تمثل كل نوع من الكيانات. على سبيل المثال ، لدينا:
type Balancer struct { Id bson.ObjectId Label string Settings BalancerSettings } type Server struct { Id bson.ObjectId BalancerId bson.ObjectId Label string Settings ServerSettings }
... حيث يمثل مثيل Balancer موازن حمل واحد. يسمح لك Loadcat بشكل فعال بموازنة الطلبات لتطبيقات الويب المتعددة من خلال مثيل واحد من NGINX. يمكن أن يكون لكل موازن خادم واحد أو أكثر خلفه ، حيث يمكن أن يكون كل خادم عقدة خلفية منفصلة.
نظرًا لأن Bolt عبارة عن متجر ذي قيمة رئيسية ، ولا يدعم استعلامات قاعدة البيانات المتقدمة ، فلدينا منطق من جانب التطبيق يقوم بذلك من أجلنا. لا يُقصد من Loadcat تكوين آلاف الموازين مع آلاف الخوادم في كل منها ، لذلك من الطبيعي أن يعمل هذا النهج الساذج بشكل جيد. أيضًا ، يعمل Bolt مع المفاتيح والقيم التي هي شرائح بايت ، ولهذا السبب نقوم بترميز BSON للهياكل قبل تخزينها في Bolt. يتم عرض تنفيذ وظيفة تسترد قائمة بنيات Balancer من قاعدة البيانات أدناه:
func ListBalancers() ([]Balancer, error) { bals := []Balancer{} DB.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("balancers")) c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { bal := Balancer{} bson.Unmarshal(v, &bal) bals = append(bals, bal) } return nil }) return bals, nil }
تبدأ وظيفة ListBalancers معاملة للقراءة فقط ، وتتكرر عبر جميع المفاتيح والقيم داخل حاوية "الموازن" ، وتقوم بفك تشفير كل قيمة إلى مثيل من بنية Balancer وإرجاعها في مصفوفة.

يكاد يكون تخزين الموازن في الدلو بسيطًا بنفس القدر:
func (l *Balancer) Put() error { if !l.Id.Valid() { l.Id = bson.NewObjectId() } if l.Label == "" { l.Label = "Unlabelled" } if l.Settings.Protocol == "https" { // Parse certificate details } else { // Clear fields relevant to HTTPS only, such as SSL options and certificate details } return DB.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("balancers")) p, err := bson.Marshal(l) if err != nil { return err } return b.Put([]byte(l.Id.Hex()), p) }) }
تقوم وظيفة Put بتعيين بعض القيم الافتراضية لحقول معينة ، وتحلل شهادة SSL المرفقة في إعداد HTTPS ، وتبدأ معاملة ، وترميز مثيل البنية وتخزينها في المستودع مقابل معرّف الموازن.
أثناء تحليل شهادة SSL ، يتم استخراج قطعتين من المعلومات باستخدام تشفير الحزمة القياسي / pem وتخزينها في SSLOptions ضمن حقل الإعدادات : أسماء DNS وبصمة الإصبع.
لدينا أيضًا وظيفة تبحث عن الخوادم عن طريق الموازن:
func ListServersByBalancer(bal *Balancer) ([]Server, error) { srvs := []Server{} DB.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("servers")) c := b.Cursor() for k, v := c.First(); k != nil; k, v = c.Next() { srv := Server{} bson.Unmarshal(v, &srv) if srv.BalancerId.Hex() != bal.Id.Hex() { continue } srvs = append(srvs, srv) } return nil }) return srvs, nil }
توضح هذه الوظيفة مدى سذاجة نهجنا حقًا. هنا ، نقرأ بشكل فعال حاوية "الخوادم" بالكامل ونقوم بتصفية الكيانات غير ذات الصلة قبل إعادة المصفوفة. لكن مرة أخرى ، هذا يعمل بشكل جيد ، ولا يوجد سبب حقيقي لتغييره.
تعد وظيفة Put للخوادم أبسط بكثير من وظيفة Balancer Struct لأنها لا تتطلب العديد من الأسطر الافتراضية لإعدادات الكود والحقول المحسوبة.
السيطرة على NGINX
قبل استخدام Loadcat ، يجب علينا تكوين NGINX لتحميل ملفات التكوين التي تم إنشاؤها. يقوم Loadcat بإنشاء ملف "nginx.conf" لكل موازن ضمن دليل بواسطة معرف الموازن (سلسلة سداسية عشرية قصيرة). يتم إنشاء هذه الأدلة ضمن دليل "خارجي" في cwd
. لذلك ، من المهم أن تقوم بتكوين NGINX لتحميل ملفات التكوين التي تم إنشاؤها. يمكن القيام بذلك باستخدام أمر "include" داخل كتلة "http":
قم بتحرير /etc/nginx/nginx.conf وأضف السطر التالي في نهاية كتلة "http":
http { include /path/to/out/*/nginx.conf; }
سيؤدي ذلك إلى قيام NGINX بفحص جميع الأدلة الموجودة ضمن "/ path / to / out /" ، والبحث عن الملفات المسماة "nginx.conf" داخل كل دليل ، وتحميل كل مجلد يعثر عليه.
في الحزمة الأساسية لدينا ، القطط ، نحدد واجهة سائق . أي هيكل يوفر وظيفتين ، إنشاء وإعادة تحميل ، مع التوقيع الصحيح يؤهل ليكون سائقًا.
type Driver interface { Generate(string, *data.Balancer) error Reload() error }
على سبيل المثال ، بنية Nginx تحت حزم feline / nginx:
type Nginx struct { sync.Mutex Systemd *dbus.Conn } func (n Nginx) Generate(dir string, bal *data.Balancer) error { // Acquire a lock on n.Mutex, and release before return f, _ := os.Create(filepath.Join(dir, "nginx.conf")) TplNginxConf.Execute(f, /* template parameters */) f.Close() if bal.Settings.Protocol == "https" { // Dump private key and certificate to the output directory (so that Nginx can find them) } return nil } func (n Nginx) Reload() error { // Acquire a lock on n.Mutex, and release before return switch cfg.Current.Nginx.Mode { case "systemd": if n.Systemd == nil { c, err := dbus.NewSystemdConnection() n.Systemd = c } ch := make(chan string) n.Systemd.ReloadUnit(cfg.Current.Nginx.Systemd.Service, "replace", ch) <-ch return nil default: return errors.New("unknown Nginx mode") } }
يمكن استدعاء Generate بسلسلة تحتوي على المسار إلى دليل الإخراج ومؤشر إلى مثيل بنية Balancer . يوفر Go حزمة قياسية لقوالب النص ، والتي يستخدمها برنامج تشغيل NGINX لإنشاء ملف تكوين NGINX النهائي. يتكون القالب من كتلة "upstream" متبوعة بكتلة "server" ، تم إنشاؤها بناءً على كيفية تكوين الموازن:
var TplNginxConf = template.Must(template.New("").Parse(` upstream {{.Balancer.Id.Hex}} { {{if eq .Balancer.Settings.Algorithm "least-connections"}} least_conn; {{else if eq .Balancer.Settings.Algorithm "source-ip"}} ip_hash; {{end}} {{range $srv := .Balancer.Servers}} server {{$srv.Settings.Address}} weight={{$srv.Settings.Weight}} {{if eq $srv.Settings.Availability "available"}}{{else if eq $srv.Settings.Availability "backup"}}backup{{else if eq $srv.Settings.Availability "unavailable"}}down{{end}}; {{end}} } server { {{if eq .Balancer.Settings.Protocol "http"}} listen {{.Balancer.Settings.Port}}; {{else if eq .Balancer.Settings.Protocol "https"}} listen {{.Balancer.Settings.Port}} ssl; {{end}} server_name {{.Balancer.Settings.Hostname}}; {{if eq .Balancer.Settings.Protocol "https"}} ssl on; ssl_certificate {{.Dir}}/server.crt; ssl_certificate_key {{.Dir}}/server.key; {{end}} location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://{{.Balancer.Id.Hex}}; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; } } `))
إعادة التحميل هي الوظيفة الأخرى في Nginx Struct التي تجعل NGINX تعيد تحميل ملفات التكوين. تعتمد الآلية المستخدمة على كيفية تكوين Loadcat. بشكل افتراضي ، يفترض أن NGINX هي خدمة systemd تعمل كخدمة nginx. مثل أن [sudo] systemd reload nginx.service
ستعمل. ومع ذلك ، بدلاً من تنفيذ أمر shell ، فإنه ينشئ اتصالاً بـ systemd من خلال D-Bus باستخدام الحزمة github.com/coreos/go-systemd/dbus.
واجهة المستخدم الرسومية المستندة إلى الويب
مع وجود كل هذه المكونات في مكانها الصحيح ، سنختتم كل ذلك بواجهة مستخدم Bootstrap بسيطة.
بالنسبة لهذه الوظائف الأساسية ، يكفي عدد قليل من معالجات مسارات GET و POST البسيطة:
GET /balancers GET /balancers/new POST /balancers/new GET /balancers/{id} GET /balancers/{id}/edit POST /balancers/{id}/edit GET /balancers/{id}/servers/new POST /balancers/{id}/servers/new GET /servers/{id} GET /servers/{id}/edit POST /servers/{id}/edit
قد لا يكون تجاوز كل مسار على حدة هو الشيء الأكثر إثارة للاهتمام الذي يجب القيام به هنا ، نظرًا لأن هذه هي إلى حد كبير صفحات CRUD. لا تتردد في إلقاء نظرة خاطفة على كود واجهة المستخدم للحزمة لمعرفة كيف تم تنفيذ معالجات كل من هذه المسارات.
كل دالة معالج هي إجراء إما:
- يجلب البيانات من مخزن البيانات ويستجيب بالقوالب المعروضة (باستخدام البيانات التي تم جلبها)
- يوزع بيانات النموذج الواردة ، ويُجري التغييرات الضرورية في مخزن البيانات ويستخدم حزمة القطط لإعادة إنشاء ملفات تكوين NGINX
علي سبيل المثال:
func ServeServerNewForm(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bal, _ := data.GetBalancer(bson.ObjectIdHex(vars["id"])) TplServerNewForm.Execute(w, struct { Balancer *data.Balancer }{ Balancer: bal, }) } func HandleServerCreate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bal, _ := data.GetBalancer(bson.ObjectIdHex(vars["id"])) r.ParseForm() body := struct { Label string `schema:"label"` Settings struct { Address string `schema:"address"` } `schema:"settings"` }{} schema.NewDecoder().Decode(&body, r.PostForm) srv := data.Server{} srv.BalancerId = bal.Id srv.Label = body.Label srv.Settings.Address = body.Settings.Address srv.Put() feline.Commit(bal) http.Redirect(w, r, "/servers/"+srv.Id.Hex()+"/edit", http.StatusSeeOther) }
كل وظيفة ServeServerNewForm تقوم بجلب موازن من مخزن البيانات وتعرض قالبًا ، TplServerList في هذه الحالة ، والذي يسترد قائمة الخوادم ذات الصلة باستخدام وظيفة الخوادم في الموازن.
تقوم وظيفة HandleServerCreate ، على الجانب الآخر ، بتوزيع حمولة POST الواردة من الجسم إلى بنية وتستخدم هذه البيانات لإنشاء مثيل لهيكل خادم جديد واستمراره في مخزن البيانات قبل استخدام قطط الحزمة لإعادة إنشاء ملف تكوين NGINX الخاص بالموازن.
يتم تخزين جميع قوالب الصفحات في ملف "ui / template.go" ويمكن العثور على ملفات HTML الخاصة بالقالب المطابق ضمن دليل "ui / Templates".
تجربته
يعد نشر Loadcat على خادم بعيد أو حتى في بيئتك المحلية أمرًا سهلاً للغاية. إذا كنت تقوم بتشغيل Linux (64 بت) ، فيمكنك الحصول على أرشيف باستخدام برنامج Loadcat ثنائي تم إنشاؤه مسبقًا من قسم إصدارات المستودع. إذا كنت تشعر ببعض المغامرة ، يمكنك استنساخ المستودع وتجميع الكود بنفسك. على الرغم من أن التجربة في هذه الحالة قد تكون مخيبة للآمال بعض الشيء لأن تجميع برامج Go لا يمثل تحديًا حقًا. وفي حال كنت تقوم بتشغيل Arch Linux ، فأنت محظوظ! تم تصميم حزمة للتوزيع من أجل الراحة. ما عليك سوى تنزيله وتثبيته باستخدام مدير الحزم الخاص بك. تم توضيح الخطوات المتضمنة في مزيد من التفاصيل في ملف المشروع README.md.
بمجرد تكوين Loadcat وتشغيله ، قم بتوجيه مستعرض الويب الخاص بك إلى "http: // localhost: 26590" (بافتراض أنه يعمل محليًا ويستمع على المنفذ 26590). بعد ذلك ، أنشئ موازنًا ، وأنشئ خادمين ، وتأكد من أن شيئًا ما يستمع إلى تلك المنافذ المحددة ، وفويلا ، يجب أن يكون لديك NGINX لطلبات توازن التحميل الواردة بين تلك الخوادم قيد التشغيل.
ماذا بعد؟
هذه الأداة بعيدة كل البعد عن الكمال ، وهي في الواقع مشروع تجريبي. لا تغطي الأداة جميع الوظائف الأساسية لـ NGINX. على سبيل المثال ، إذا كنت تريد تخزين الأصول التي تخدمها العقد الخلفية في طبقة NGINX مؤقتًا ، فلا يزال يتعين عليك تعديل ملفات تكوين NGINX يدويًا. وهذا ما يجعل الأشياء مثيرة. هناك الكثير الذي يمكن القيام به هنا وهذا هو بالضبط ما هو التالي: تغطية المزيد من ميزات موازنة الحمل في NGINX - الميزات الأساسية وربما حتى الميزات التي يقدمها NGINX Plus.
جرب Loadcat. تحقق من الكود ، قم بتقسيمه ، قم بتغييره ، والعب به. أيضًا ، أخبرنا إذا كنت قد أنشأت أداة تقوم بتكوين برامج أخرى أو استخدمت برنامجًا يعجبك حقًا في قسم التعليقات أدناه.