هل "epoll" هو السبب الأساسي في أن Tornadoweb (أو nginx) سريع جدًا؟
سؤال
Tornadoweb و nginx هي خوادم ويب شهيرة في الوقت الحالي وتظهر العديد من المعايير أن لديها أداء أفضل من Apache في ظل ظروف معينة. لذلك سؤالي هو:
هل "Epoll" هو السبب الأساسي الذي يجعلها سريعة جدًا؟ وماذا يمكنني أن أتعلم من ذلك إذا كنت أرغب في كتابة خادم مقبس جيد؟
المحلول
إذا كنت تبحث عن كتابة خادم مقبس ، فإن نقطة انطلاق جيدة هي مقالة C10K من Dan Kegel من بضع سنوات:
http://www.kegel.com/c10k.html
لقد وجدت أيضًا دليل Beej لبرمجة الشبكة ليكون مفيدًا جدًا:
أخيرًا ، إذا كنت بحاجة إلى مرجع رائع ، فهناك برمجة شبكة UNIX من قبل W. Richard Stevens et. آل:
http://www.amazon.com/unix-network-programming-sockets-networking/dp/0131411551/ref=dp_ob_title_bk
على أي حال ، للإجابة على سؤالك ، فإن الفرق الرئيسي بين Apache و Nginx هو أن Apache يستخدم مؤشر ترابط واحد لكل عميل مع حظر الإدخال/الإخراج ، في حين أن Nginx يتم تربيته مع I/O غير المحظور. يقلل تجمع العمال من Apache من العمليات المبدئية والمصير ، لكنه لا يزال يجعل مفتاح وحدة المعالجة المركزية بين عدة مؤشرات ترابط عند خدمة عملاء متعددين. NGINX ، من ناحية أخرى ، يتعامل مع جميع الطلبات في موضوع واحد. عندما يحتاج طلب واحد إلى تقديم طلب شبكة (على سبيل المثال ، إلى الواجهة الخلفية) ، يرفق Nginx رد اتصال على طلب الواجهة الخلفية ثم يعمل على طلب عميل نشط آخر. في الممارسة العملية ، هذا يعني أنه يعود إلى حلقة الحدث (epoll
, kqueue
, ، أو select
) ويسأل عن واصفات الملفات التي لديها شيء للإبلاغ عنه. لاحظ أن استدعاء النظام في حلقة الحدث الرئيسية هي في الواقع عملية حظر ، لأنه لا يوجد شيء يجب القيام به حتى يكون أحد واصفات الملف جاهزًا للقراءة أو الكتابة.
هذا هو السبب الرئيسي في أن Nginx و Tornado فعالان في خدمة العديد من العملاء المتزامنين: لا يوجد سوى عملية واحدة (وبالتالي توفير ذاكرة الوصول العشوائي) وخيط واحد فقط (وبالتالي توفير وحدة المعالجة المركزية من مفاتيح السياق). بالنسبة إلى Epoll ، إنها مجرد نسخة أكثر كفاءة من Select. إذا كانت هناك واصفات ملفات مفتوحة (مآخذ) ، فإنها تتيح لك اختيار تلك الجاهزة للقراءة في O (1) بدلاً من وقت O (n). في الواقع ، يمكن لـ NGINX استخدام SELECT بدلاً من EPOLL إذا قمت بتجميعه باستخدام --with-select_module
الخيار ، وأراهن أنه سيظل أكثر كفاءة من Apache. لست على دراية بـ Apache Internals ، لكن GREP السريع يظهر أنه يستخدم Select و Epoll - ربما عندما يستمع الخادم إلى منافذ/واجهات متعددة ، أو إذا كان ذلك يتطلب طلبات خلفية متزامنة لعميل واحد.
بالمناسبة ، بدأت في هذه الأشياء في محاولة لكتابة خادم مأخذ توصيل أساسي وأردت معرفة كيف كان Nginx فعالًا للغاية. بعد التغلب على رمز مصدر Nginx وقراءة تلك الأدلة/الكتب التي ربطتها أعلاه ، اكتشفت أنه سيكون من الأسهل كتابة وحدات Nginx بدلاً من الخادم الخاص بي. وهكذا ولد دليل Emiller السقوط السمي الآن لتطوير وحدة Nginx:
http://www.evanmiller.org/nginx-modules-guide.html
(تحذير: تمت كتابة الدليل ضد Nginx 0.5-0.6 وقد يكون واجهات برمجة التطبيقات قد تغيرت.) إذا كنت تفعل أي شيء مع HTTP ، فأنا أقول أن أعط Nginx لقطة لأنها توصلت إلى جميع التفاصيل المشعرة للتعامل مع العملاء أغبياء. على سبيل المثال ، عمل خادم المقبس الصغير الذي كتبته من أجل المتعة مع جميع العملاء - باستثناء Safari ، ولم أحسب أبدًا السبب. حتى بالنسبة للبروتوكولات الأخرى ، قد يكون Nginx هو الطريق الصحيح للذهاب ؛ تم تجريد الحدث بشكل جيد من البروتوكولات ، وهذا هو السبب في أنه يمكن أن يكون وكيل HTTP وكذلك IMAP. قاعدة كود Nginx منظمة جيدًا للغاية ومكتوبة جيدًا ، مع استثناء واحد يذكر. لن أتبع تقدمه عندما يتعلق الأمر بتوضيح محلل البروتوكول ؛ بدلاً من ذلك ، استخدم مولد محلل. لقد كتبت بعض الأشياء حول استخدام مولد محلل (Ragel) مع Nginx هنا:
http://www.evanmiller.org/nginx-modules-guide-advanced.html#parsing
ربما كان كل هذا أكثر معلومات مما تريد ، ولكن نأمل أن تجد بعضًا منه مفيدًا.