أداء تطبيقات شبكة Linux. مقدمة

يتم الآن استخدام تطبيقات الويب في كل مكان، ومن بين جميع بروتوكولات النقل، يحتل HTTP نصيب الأسد. عند دراسة الفروق الدقيقة في تطوير تطبيقات الويب، لا يولي معظم الأشخاص سوى القليل من الاهتمام لنظام التشغيل الذي تعمل فيه هذه التطبيقات فعليًا. الفصل بين التطوير (Dev) والعمليات (Ops) أدى إلى تفاقم الوضع. ولكن مع ظهور ثقافة DevOps، أصبح المطورون مسؤولين عن تشغيل تطبيقاتهم في السحابة، لذلك من المفيد جدًا لهم أن يصبحوا على دراية كاملة بالواجهة الخلفية لنظام التشغيل. يعد هذا مفيدًا بشكل خاص إذا كنت تحاول نشر نظام لآلاف أو عشرات الآلاف من الاتصالات المتزامنة.

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

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

لينكس هو غرفة الخادم نظام التشغيل، وغالبًا ما تعمل تطبيقاتك على نظام التشغيل هذا. على الرغم من أنني أقول "Linux"، إلا أنه يمكنك في معظم الأوقات أن تفترض بأمان أنني أقصد جميع أنظمة التشغيل المشابهة لـ Unix بشكل عام. ومع ذلك، لم أختبر الكود المصاحب على الأنظمة الأخرى. لذا، إذا كنت مهتمًا بـ FreeBSD أو OpenBSD، فقد تختلف نتائجك. عندما أحاول شيئًا خاصًا بنظام التشغيل Linux، فإنني أشير إليه.

على الرغم من أنه يمكنك استخدام هذه المعرفة لإنشاء تطبيق من الصفر وسيتم تحسينه بشكل مثالي، فمن الأفضل عدم القيام بذلك. إذا قمت بكتابة خادم ويب جديد بلغة C أو C++ لتطبيق الأعمال الخاص بمؤسستك، فقد يكون هذا هو آخر يوم لك في الوظيفة. ومع ذلك، فإن معرفة بنية هذه التطبيقات ستساعد في اختيار البرامج الموجودة. ستكون قادرًا على مقارنة الأنظمة القائمة على العمليات مع الأنظمة القائمة على الخيوط بالإضافة إلى الأنظمة القائمة على الأحداث. سوف تفهم وتقدر سبب أداء Nginx بشكل أفضل من Apache httpd، ولماذا يمكن لتطبيق Python المستند إلى Tornado أن يخدم المزيد من المستخدمين مقارنة بتطبيق Python المستند إلى Django.

ZeroHTTPd: أداة تعليمية

ZeroHTTPd هو خادم ويب كتبته من الصفر بلغة C كأداة تعليمية. ليس لديه أي تبعيات خارجية، بما في ذلك الوصول إلى Redis. نحن ندير إجراءات Redis الخاصة بنا. انظر أدناه لمزيد من التفاصيل.

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

هناك الكثير من التعليقات في الكود لمساعدتك على الفهم. نظرًا لكونه خادم ويب بسيطًا يتكون من بضعة أسطر من التعليمات البرمجية، فإن ZeroHTTPd يعد أيضًا إطارًا مصغرًا لتطوير الويب. وظائفه محدودة، لكنه قادر على تقديم ملفات ثابتة وصفحات "ديناميكية" بسيطة للغاية. يجب أن أقول أن ZeroHTTPd مفيد لتعلم كيفية إنشاء تطبيقات Linux عالية الأداء. بشكل عام، تنتظر معظم خدمات الويب الطلبات وتفحصها وتعالجها. وهذا هو بالضبط ما سيفعله ZeroHTTPd. هذه أداة للتعلم، وليس الإنتاج. إنها ليست رائعة في معالجة الأخطاء ومن غير المرجح أن تتباهى بأفضل الممارسات الأمنية (أوه نعم، لقد استخدمت strcpy) أو الحيل الذكية للغة C. لكني آمل أن تقوم بعملها بشكل جيد.

أداء تطبيقات شبكة Linux. مقدمة
الصفحة الرئيسية لـ ZeroHTTPd. يمكنه إخراج أنواع مختلفة من الملفات بما في ذلك الصور

تطبيق كتاب الزوار

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

أداء تطبيقات شبكة Linux. مقدمة
تطبيق الويب "سجل الزوار" ZeroHTTPd

يتم تخزين إدخالات عداد الزوار ودفتر الزوار في Redis. بالنسبة للاتصالات مع Redis، يتم تنفيذ الإجراءات الخاصة بها، ولا تعتمد على المكتبة الخارجية. أنا لست من أشد المعجبين بطرح كود البيرة المنزلية عندما تكون هناك حلول متاحة للجمهور ومختبرة جيدًا. لكن الغرض من ZeroHTTPd هو دراسة أداء Linux والوصول إلى الخدمات الخارجية، في حين أن خدمة طلبات HTTP لها تأثير خطير على الأداء. يجب علينا التحكم بشكل كامل في الاتصالات مع Redis في كل من بنيات الخادم لدينا. في بعض البنيات نستخدم حظر المكالمات، وفي أخرى نستخدم الإجراءات المستندة إلى الأحداث. إن استخدام مكتبة عميل Redis خارجية لن يوفر هذا التحكم. بالإضافة إلى ذلك، لا يؤدي عميل Redis الصغير سوى بعض الوظائف (الحصول على مفتاح وإعداده وزيادته؛ والحصول على مصفوفة وإلحاقها). بالإضافة إلى ذلك، فإن بروتوكول Redis أنيق وبسيط للغاية. لا تحتاج حتى إلى تعليمه بشكل خاص. إن حقيقة أن البروتوكول يقوم بكل العمل في حوالي مائة سطر من التعليمات البرمجية توضح مدى تفكيره جيدًا.

ويوضح الشكل التالي ما يفعله التطبيق عندما يطلبه العميل (المتصفح). /guestbookURL.

أداء تطبيقات شبكة Linux. مقدمة
كيف يعمل تطبيق سجل الزوار

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

بنيات الخادم ZeroHTTPd

نحن نبني سبعة إصدارات من ZeroHTTPd بنفس الوظيفة ولكن ببنيات مختلفة:

  • ترابطي
  • خادم Fork (عملية فرعية واحدة لكل طلب)
  • خادم ما قبل الشوكة (الشوكة المسبقة للعمليات)
  • خادم مزود بخيوط التنفيذ (خيط واحد لكل طلب)
  • الخادم مع إنشاء ما قبل الموضوع
  • على أساس الهندسة المعمارية poll()
  • على أساس الهندسة المعمارية epoll

نقوم بقياس أداء كل بنية عن طريق تحميل الخادم بطلبات HTTP. ولكن عند مقارنة بنيات متوازية للغاية، يزداد عدد الاستعلامات. نختبر ثلاث مرات ونحسب المتوسط.

منهجية الاختبار

أداء تطبيقات شبكة Linux. مقدمة
إعداد اختبار التحميل ZeroHTTPd

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

ماذا يفعل كل من هذه الخوادم؟

  • Load.unixism.net: هذا هو المكان الذي نركض فيه ab، فائدة أباتشي المعيار. فهو يولد الحمل اللازم لاختبار بنيات الخادم لدينا.
  • nginx.unixism.net: في بعض الأحيان نرغب في تشغيل أكثر من مثيل لبرنامج خادم. للقيام بذلك، يعمل خادم Nginx المزود بالإعدادات المناسبة كموازن تحميل قادم من ab لعمليات الخادم لدينا.
  • Zerohttpd.unixism.net: هنا نقوم بتشغيل برامج الخادم لدينا على سبعة بنيات مختلفة، واحدة تلو الأخرى.
  • redis.unixism.net: يقوم هذا الخادم بتشغيل برنامج Redis، حيث يتم تخزين إدخالات سجل الزوار وعدادات الزوار.

تعمل جميع الخوادم على نفس قلب المعالج. والفكرة هي تقييم الأداء الأقصى لكل بنية. وبما أن كافة برامج الخادم يتم اختبارها على نفس الجهاز، فهذا هو الأساس للمقارنة. يتكون إعداد الاختبار الخاص بي من خوادم افتراضية مستأجرة من Digital Ocean.

ماذا نقيس؟

يمكنك قياس مؤشرات مختلفة. نقوم بتقييم أداء كل بنية في تكوين معين عن طريق تحميل الخوادم بطلبات بمستويات مختلفة من التوازي: ينمو الحمل من 20 إلى 15 مستخدم متزامن.

نتائج الاختبار

يوضح الرسم البياني التالي أداء الخوادم على بنيات مختلفة عند مستويات مختلفة من التوازي. المحور الصادي هو عدد الطلبات في الثانية، والمحور السيني هو الاتصالات المتوازية.

أداء تطبيقات شبكة Linux. مقدمة

أداء تطبيقات شبكة Linux. مقدمة

أداء تطبيقات شبكة Linux. مقدمة

وفيما يلي جدول بالنتائج.

الطلبات في الثانية

تواز
ترابطي
شوكة
شوكة مسبقة
تدفق
البث المسبق
في.
إبول

20
7
112
2100
1800
2250
1900
2050

50
7
190
2200
1700
2200
2000
2000

100
7
245
2200
1700
2200
2150
2100

200
7
330
2300
1750
2300
2200
2100

300
-
380
2200
1800
2400
2250
2150

400
-
410
2200
1750
2600
2000
2000

500
-
440
2300
1850
2700
1900
2212

600
-
460
2400
1800
2500
1700
2519

700
-
460
2400
1600
2490
1550
2607

800
-
460
2400
1600
2540
1400
2553

900
-
460
2300
1600
2472
1200
2567

1000
-
475
2300
1700
2485
1150
2439

1500
-
490
2400
1550
2620
900
2479

2000
-
350
2400
1400
2396
550
2200

2500
-
280
2100
1300
2453
490
2262

3000
-
280
1900
1250
2502
انتشار كبير
2138

5000
-
انتشار كبير
1600
1100
2519
-
2235

8000
-
-
1200
انتشار كبير
2451
-
2100

10
-
-
انتشار كبير
-
2200
-
2200

11
-
-
-
-
2200
-
2122

12
-
-
-
-
970
-
1958

13
-
-
-
-
730
-
1897

14
-
-
-
-
590
-
1466

15
-
-
-
-
532
-
1281

من الرسم البياني والجدول، يمكن ملاحظة أنه فوق 8000 طلب متزامن، لم يبق لدينا سوى لاعبين اثنين: pre-fork وepoll. ومع زيادة التحميل، يكون أداء الخادم القائم على الاستقصاء أسوأ من خادم البث المباشر. تعد بنية الإنشاء المسبق لسلسلة الرسائل منافسًا جديرًا لـ epoll، وهي شهادة على مدى نجاح نواة Linux في جدولة أعداد كبيرة من سلاسل الرسائل.

كود مصدر ZeroHTTPd

كود مصدر ZeroHTTPd هنا. يوجد دليل منفصل لكل بنية.

ZeroHTTPd │ ├── 01_iteative │ ├── main.c ├── 02_forking │ ├── main.c ├── 03_preforking │ ├── main.c ├── 04_ خيوط │ ├── main.c ├── 05_prethreading │ ├── main.c ├── 06_poll │ ├── main.c ├── 07_epoll │ └── main.c ├── Makefile ├── عام │ ├── فهرس .html │ └── توكس .png └── قوالب └── سجل الزوار └── Index.html

بالإضافة إلى سبعة أدلة لجميع البنيات، هناك دليلان آخران في دليل المستوى الأعلى: عام وقوالب. يحتوي الأول على ملف Index.html والصورة من لقطة الشاشة الأولى. يمكنك وضع ملفات ومجلدات أخرى هناك، ومن المفترض أن يقوم ZeroHTTPd بخدمة تلك الملفات الثابتة دون أي مشاكل. إذا كان المسار الموجود في المتصفح يطابق المسار الموجود في المجلد العام، فسيبحث ZeroHTTPd عن ملف Index.html في هذا الدليل. يتم إنشاء محتوى دفتر الزوار ديناميكيًا. إنه يحتوي فقط على صفحة رئيسية، ويعتمد محتواه على الملف "templates/guestbook/index.html". يضيف ZeroHTTPd بسهولة صفحات ديناميكية للامتداد. الفكرة هي أنه يمكن للمستخدمين إضافة قوالب إلى هذا الدليل وتوسيع ZeroHTTPd حسب الحاجة.

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

واجهة برمجة تطبيقات لينكس

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

الأداء وقابلية التوسع

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

مهام وحدة المعالجة المركزية والإدخال/الإخراج

أخيرًا، يوجد دائمًا نوعان محتملان من المهام في الحوسبة: الإدخال/الإخراج ووحدة المعالجة المركزية. إن تلقي الطلبات عبر الإنترنت (الإدخال/الإخراج للشبكة)، وخدمة الملفات (الإدخال/الإخراج للشبكة والقرص)، والتواصل مع قاعدة البيانات (الإدخال/الإخراج للشبكة والقرص) كلها أنشطة إدخال/إخراج. قد تتطلب بعض استعلامات قاعدة البيانات استهلاكًا كبيرًا لوحدة المعالجة المركزية (الفرز، وحساب متوسط ​​مليون نتيجة، وما إلى ذلك). معظم تطبيقات الويب مقيدة بأقصى قدر ممكن من عمليات الإدخال/الإخراج، ونادرًا ما يتم استخدام المعالج بكامل طاقته. عندما ترى أن بعض مهام الإدخال/الإخراج تستخدم قدرًا كبيرًا من وحدة المعالجة المركزية، فمن المرجح أن يكون ذلك علامة على ضعف بنية التطبيق. قد يعني هذا إهدار موارد وحدة المعالجة المركزية في إدارة العمليات وتبديل السياق - وهذا ليس مفيدًا تمامًا. إذا كنت تفعل شيئًا مثل معالجة الصور، أو تحويل الملفات الصوتية، أو التعلم الآلي، فإن التطبيق يتطلب موارد وحدة المعالجة المركزية القوية. ولكن بالنسبة لمعظم التطبيقات هذا ليس هو الحال.

تعرف على المزيد حول بنيات الخادم

  1. الجزء الأول: العمارة التكرارية
  2. الجزء الثاني. خوادم شوكة
  3. الجزء الثالث. خوادم ما قبل الانقسام
  4. الجزء الرابع. خوادم مع خيوط التنفيذ
  5. الجزء الخامس. الخوادم المترابطة مسبقًا
  6. الجزء السادس. العمارة القائمة على بول
  7. الجزء السابع. الهندسة المعمارية القائمة على epoll

المصدر: www.habr.com

إضافة تعليق