اري شرح مفهوم ال thread في ال web server

مثلا نحن الآن نتصفح arabia و كل شخص يعتبر client يرسل request الى ال server ، سؤالي هو عن كيفية تعامل ال server مع كل request بشكل منعزل عن الآخر هل تخصص لكل request thread خاص به وهل من الممكن ان تتضارب معلومات request بآخر بمعنى آخر ان اثنان request يمكن تنفيذهما ب thread واحدة ؟

ارجو وضع مصادر حول هذا الموضوع .

يرجى الدخول لحسابك أو تسجيل حساب لتستطيع إضافة تعليق
حساب جديد دخول

التعليقات

نعم لكل طلب HTTP Request يفتح الخادم Thread جديد, يقوم بالتعامل مع الطلب.

اذا كان الطلب لdynamic page يقوم الخادم اما بتشغيل الapplication الذى يقوم بتوليد الصفحة و اعطاءه المدخولات المناسبة فى شكل Environment variable (مثل الطلب و الIP للطالب و غير ذلك ما يحتاجه) , و ينتظر ان ينتهى الapplication من مهمته و يقوم باستلام الرد عبر الRedirect output,

هذا مثال لو كان السرفر يستخدم بروتوكول الcgi,

هناك العديد من البروتوكولات الاخرى, فمثلا فى حالة FastCGI يقوم السرفر بالتخاطب مع Service عبر Socket و يرسل اليه الطلب و ينتظر الرد.

فى حالة الISAPI تكون الWeb application عبارة عن مكتبة ربط ديناميكى, و يقوم السرفر باستدعائها و انتظار الرد منها.

أيا كانت الحالة, فان لكل Request يقوم السرفر بفتح Thread جديد للتعامل معه بحسب البروتوكول المستخدم ثم يغلقه بعد الانتهاء, و بعض المواقع تسمح بConnection -Alive حيث يقوم الخادم بترك الthread مفتوحا لتلقى الطلبات الجديدة من نفس الclient و الرد عليها, و هذا يوفر الوقت فى حالة كان الclient فى حالة اتصال دائم بالسرفر يرسل و يتلقى المعلومات دوريا.

أما بالنسبة للتضارب فلا يوجد تضارب لأن كل Thread يقوم بحجز الmemory الخاصة به و يعمل مستقلا عن بقية الthreads.

بعض التحسين على ما كتبته.

نعم لكل طلب HTTP Request يفتح الخادم Thread جديد, يقوم بالتعامل مع الطلب.

خطأ من الممكن لكل طلب process كامل جديد .. او لا يفتح لا process او thread جديد .. كل هذا يعتمد الانظمة المستخدمة

أيا كانت الحالة, فان لكل Request يقوم السرفر بفتح Thread جديد للتعامل معه بحسب البروتوكول المستخدم ثم يغلقه بعد الانتهاء

اغلاق thread ليس شرط .. ممكن الممكن ان يبقى مفتوح بعدها ويعالج طلب اخر

أما بالنسبة للتضارب فلا يوجد تضارب لأن كل Thread يقوم بحجز الmemory الخاصة به و يعمل مستقلا عن بقية الthreads.

معالجة الطلبات ب thread ليس بامن مثل process

thread عبارة عن stack + pc + register set

الباقي يتم مشاركته مع process

اي ان عملية حجز مساحة ل object معين او اي شئ اخر ممكن الممكن threads / process مشاهدته.

مصادر محاضرة

http://www.distributed-syst... /courses/ds/ كتاب operating system concepts

هذا مثال لو كان السرفر يستخدم بروتوكول الcgi, هناك العديد من البروتوكولات الاخرى, فمثلا فى حالة FastCGI يقوم السرفر بالتخاطب مع Service عبر Socket و يرسل اليه الطلب و ينتظر الرد.

الفرق بالجوهري بين CGI و FastCGI CGI لكل طلب يبدا ب process جديد وطبعا بعد انتهاء الطلب ينهي process FastCGI طلب قد يعالج من process موجودة مسبقا اي ان process الواحد يعالج عدة طلبات. ملاحظة هنا مثال على انه ليس بشرط ان يكون لكل طلب thread جديد

مصادر .. http://en.wikipedia.org/wik...

أيا كانت الحالة, فان لكل Request يقوم السرفر بفتح Thread جديد للتعامل معه بحسب البروتوكول المستخدم ثم يغلقه بعد الانتهاء, و بعض المواقع تسمح بConnection -Alive حيث يقوم الخادم > بترك الthread مفتوحا لتلقى الطلبات الجديدة من نفس الclient و الرد عليها, و هذا يوفر الوقت فى حالة كان الclient فى حالة اتصال دائم بالسرفر يرسل و يتلقى المعلومات دوريا.

كما في اول تعليق ليس بشرط ان يكون thread

ملاحظة لكتاب الموضوع .. اذا اردت اجابة ادق لاسؤالك اكتب بتفصيل عن ما تستخدمه حاليا .. نوع web server نوع module الخ

        خطأ من الممكن لكل طلب process كامل جديد .. او لا يفتح لا process او thread جديد .. كل هذا يعتمد الانظمة المستخدمة

لا انت خلطت بين ما يفعله الخادم Web Server و بين سكريبت الback end او الserver side, داخل الweb server نفسه يقوم بفتح Thread داخلى لنفسه لمعالجة الطلب, هذا الthread داخله يقوم بالتخاطب مع السكريبت, سواء اكان هذا السكريبت برنامج يشغله فى حالة الcgi مثلا, أو برنامج يعمل كservice. كمثال, لنفرض ان لدينا موقع يعمل على Apache و سكريبت php و cgi, عند تلقى طلب جديد, يقوم الأباتشى بفتح Thread لتلقى الطلب, و يقوم هذا الthread بتشغيل البرمجية php التى سوف تنفذ الطلب عبر تشغيل الphp interpreter, و هذا process جديدة, و ينتظر الرد, ثم يرسله الى الclient مرة اخرى ثم يقوم بقطع الاتصال و اغلاق الthread. هذه هى الطريقة المعروفة لتصميم الweb server, بما اننى قمت بتصميم ويب سرفر صغير يعمل ببروتوكول شبيه بالCGI.

       معالجة الطلبات ب thread ليس بامن مثل process 

هذا يعتمد على ادارتك للthreads, شخصيا فى برنامج متعدد الخيوط multi threading فانه يجب العناية بالمعلومات التى تقوم بتمريرها الى الthread و التعاطى معها, هذا ما يسمى ان يكون الكود Thread Safe.

       اغلاق thread ليس شرط .. ممكن الممكن ان يبقى مفتوح بعدها ويعالج طلب اخر

حدد هل تتكلم عن الweb server أم على السكريبت, فى السكريبت ممكن بالطبع, فى الويب سرفر نفسه مستحيل, لأن هناك thread أساسى server thread هو من يمرر الsocket للthread الخاص بالطلب.

داخل الweb server نفسه يقوم بفتح Thread داخلى لنفسه لمعالجة الطلب

فى الويب سرفر نفسه مستحيل, لأن هناك thread أساسى server thread هو من يمرر الsocket للthread الخاص بالطلب.

هذا module يتعامل مع الطلبات ب processes وليس ب threads

اقتنعت؟ لا يوجد شئ مستحيل

بنسبة sse ومشكلة تعليق اتركها للمبرمجين php وليس من اختصاصي

استخدم ال php على سيرفر appache

القي نظرة على هذا التعليق

هل ال thread تعتبر instance من التطبيق؟

هل ترك ال thread مفتوحا لتلقي الطلبات له علاقة بال socket ؟

في حال اردت ان يبقى سكربت شغال كان اضعه في infinity loop و يعمل داخل السيرفر دون تدخل ال client

ال cron jobs تعيد فتحه بعد فترة زمنية محددة انا اريده باستمرار

      هل ال thread تعتبر instance من التطبيق؟

الthread ليس instance جديدة من التطبيق, بل هو instance خاص داخل التطبيق, تقريبا هو بمثابة Process أو Instance جديدة لكن يمكنه تشارك الmemory مع الthread الرئيسى. أى برنامج هو عبارة عن Thread واحد على الاقل يسمى بالMain Thread, و يمكن للmain thread فتح بعد ذلك عدد لا محدود "نظريا" من الthreads بحسب الموارد المتوفرة. كل thread هو بمثابة خيط مستقل من التعليمات يعمل بالتوازى مع الmain thread لكن يمكنه تشارك الmemory مع الmain thread و مع الthreads الاخرى. فى حالة ترك الthread مفتوح فى loop هذا يتم فى حالة الconnection alive, و يكون الsocket مفتوحا أيضا, هذا ينفع كثيرا فى حالة الencrypted socket لأن تحميل التشفير يأخذ وقتا أطول نسبيا من الsocket العادى غير المشفر, و مفيد فى حالة اذا ما كان الموقع يحتاج الى اتصال دائم لتلقى updates. يدير الخادم الthreads المفتوحة "alive" بحسب موارده, معظم الخوادم تضع عددا محدودا من الthreads التى تظل مفتوحة فى الوقت نفسه, لأن معنى ان يظل الthread مفتوحا هو ان الذاكرة سوف تبقى محجوزة له و لن يستطيع تلقى طلبات جديدة.

  في حال اردت ان يبقى سكربت شغال كان اضعه في infinity loop و يعمل داخل السيرفر دون تدخل ال client 

اذا كنت تقصد عمل تطبيق يعمل فى الخلفية كService بعيدا عن خادم الويب فهذا ممكن طبعا, و يعتمد على نظام التشغيل الذى سوف تستخدمه. يمكنك ان تبرمجة مباشرة كWindows Service او background system application على ويندوز, أو كDeamon على انظمة unix و لينكس. لكن خدمات الاستضافة لن توفر لك هذا الخيار, يجب عليك اما تأجير Virtual Machine او استضافة الموقع على سرفر خاص بك.

شكرا لك شرح وافر :)

آخر سؤال

بالنسبة لل loop حاولت استخدم ال server sent event : sse و عملت infinity loop مع sleep 5 seconds و time out لا نهائي و كان مضمون ال loop هو استعلام من قاعدة البيانات لجلب تحديثات لكن الموقع بدأ بالتشنج عند فتح نفس الصفحة اكثر من مرة علماً انه لا يزال على ال localhost من هنا فكرت بان يكون ال sse request له thread موحدة على السيرفر و لكن انتهيت باستعمال ال ajax

و لكن ماذا سيكون حال التطبيق اذا كان عبارة عن chat مستعملا ال sse فما هي اساليب تقليل الضغط المستعملة ؟

لم اعمل على php من قبل, لكن بشكل عام,

لكل طلب يجب فتح thread جديد للتعامل معه بشكل منفصل, حتى تعمل الطلبات بشكل متوازى و ليس فى متتالية, و الا مع تعدد الطلبات سوف يتوقف الموقع عن الاستجابة.

لنأخذ مثال الchat, سواء فى حالة الويب او dekstop application,

فى الشات يكون كل مستخدم هو client يتصل بالسرفر, الclient يرسل طلب الى الخادم مرفق معه الرسالة التى يود توجيهها و الى من يود توجيهها,

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

المتلقى و هو ايضا client يقوم بطلب دورى من الخادم لتلقى الرسائل الجديدة, فيبعث له الخادم بالرسالة الجديدة.

يحتاج هذا النظام الى الكثير من العمل, فيجب ان تقوم بتصميم هيكل الطلبات, ربما فى شكل SOAP او غيره او يمكنك ابتكار هيكل للبيانات خاص بك. و يجب ان تصمم قاعدة بيانات فيها كل مستخدم و الرسائل المرسلة منه و اليه, و يجب ان يقوم الخادم بادارة كل هذا.

لكن بشكل عام, الclient يرسل طلب, اما بتوجيه رسالة جديدة او بتلقى الرسائل الجديدة.

يمكنك بالطبع فتح خط بين الclient و الserver دائم connection alive, و هذا أسرع فى حالة وجود عدد clients محدود, لكن مع العدد الكبير من المتصلين سوف يتوقف النظام عن العمل و لن يستطيع تلقى اتصالات جديدة.

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

في حال كان هناك ارتباط مع معطيات فغالبا ستكون مدارة من قبل مخدم معطيات لمعالجة الولوج المتعدد

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

أما إن أردت أن يكون هناك معالجة في حالة عمل دائم وتخدم كل الطلبات في آن واحد فأظن أنه يجب عمل تطبيق يتم تشغيله على السيرفر تلقائيا ويكون شغال دائما

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

هذا ما أعرفه وقد يكون هناك مباديء أخرى لعل من يعرفها يفيدك ويفيدنا بها .

نرجع لتعدد المهام (منذ أيام يونكس 1970) كيف يمكن لحاسوب له معالج أحادي النواة single core أن يكون multi-task.

طيب خليني أقرب لك الفكرة. هل تعرف أردوينو؟ لنقل أن لدينا متحكم دقيقي بمعالج AVR يعمل بسرعة 16 ميغاهيرتز الذاكرة الرام تعمل بنفس التردد. مع كل دقة من ال 16 مليون دقة للمذبب (أو لنقل الساعة) في الثانية يتم إحضار تعلمية جديدة وتنفيذها وهذا يحدث لأنه له ذاكرة تعرف باسم SRAM

لكن الحواسب العادية تعمل بتردد وتعمل ذواكرها الداخلية مثل الكاش بتردد آخر و الرام بتردد أقل بكثير وتعمل نواقل ال IO بين الأجزاء المختلفة بتردد مختلف. مما يعني أنه عندما ينتهي الحاسوب من تعليمة معينة قد لا تكون التعليمة التي تليها في الذاكرة فعليه أن ينام حتى تجهز. وعندما تكون التعليمة إرسال شيء في أحد قنوات النواقل IO قد يتم وضعها في الطابور queue buffer وينام الحاسوب حتى تصل للطرف الآخر بحسب سرعة الناقل (لا يوجد رامات بسرعة 3 مليار دقة بالثانية ولا يوجد ناقل فيديو بتلك السرعة ولا ناقل قرص صلب ...إلخ) لذا يمكن حتى لحاسوب بنواة واحدة أن يشغل أكثر من برنامج أو مهمة دفعة واحدة من خلال أن يعطي لكل مهمة شريحة زمنية معينة صغيرة تشعرك بأنهما يعملان معا بالتوازي. غالبا لا يستخدم البرنامج شريحته الزمنية بالكامل لأنه سيعمل شيء حتى يحصل أول مقاطعة (انتظار الرام أن تجهز أو المداخل والمخارج الخاصة بأي من النواقل ...إلخ).

هذا بالنسبة لل processes هناك أيضا نفس المفهوم لكن ضمن نفس ال process بمعنى نفس البرنامج وبنفس فضاء العنونة يكون عنده أشياء يريد أن يعملها معا. مثلا أنت تفتح كروم في أندرويد عندما تتصفح موقع google.com يكون هناك مسار thread في الخلفية يجلب محتويات الموقع وهناك مسار آخر يحدث شكل مؤشر التقدم progress indicator بالحركة ويتفاعل مع نقراتك ...إلخ.

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

وهناك مصطلح جديد ظهر اسمه green threads أو asyncio وله أسماء كثيرة مثل co-routine (مع بعض الفروق البسيطة) وهو أن عملية التبديل والإدارة تتم في فضاء المستخدم (التطبيق أو لغة البرمجة هي من تعمل تعالج أكثر من شيء دفعة واحدة) وليس في نظام التشغيل.

مثال بسيط خادم به وصلة إيثرنت واحدة فيه سلك واحد أو سن واحد ready to receive بمعنى إن كان يستقبل بت من شخص لا يمكن استقبال من آخر. الذي يجري أنه يعرف نافذة أو شريحة أو حصة أو نصيب لكل عميل client متصل به مثلا 20 ميلي ثانية أو 4096 بايت أيهما يأتي أولا. يتصل أحدهم ويطلب صفحة تحتاج query على قاعدة البيانات فيتم إرسالة الطلب لكن لا يتم عودة الرد بل يتم نقل المعالجة لمعالجة طلب من عميل آخر (ريثما يأتي رد قاعدة البيانات) العميل الآخر عميل بطيء يرسل 1024 بايت خلال 20 ميلي ثانية المخصصة له يتم وضعها في ذاكرة على جنب buffer ومعالجة عميل ثالث يرسل طلب يحتاج قراءة شيء ما من القرص الصلب يتم إرسال الطلب إلى القرص الصلب لكن لا يتم إنتظار رد القرص ويتم نقل التحكم للطلب الذي يله وبما أنه قد رجع رد قاعدة البيانات يتم معالجة صاحب أول طلب من خلال توليد الصفحة وإرسال أول 4096 بايت من الرد ثم الانتقال للطلب الي بعد مثلا نجلب ما بقي من ثاني طلب ثم ننتقل لمعالجة صاحب الطلب الثالث بعد أن وصل رد القرص الصلب ثم نعود لإرسال ما بقي من الطلب الأول وهكذا.

هذا يعتمد على نوع الـ

Server Back End

الاباتشي لها طريقة للتعامل مع هذه الطلبات وايضاً النود ونيجكس فيصعب توحيد الرد لانه يختلف من برمجية لبرمجية

كلام صحيح .. كل شئ يعتمد على النظام المستخدم واعدادته