مقدمة
موضوع ال Scalability يعتبر من أهم المواضيع بالنسبة لمطورين الويب خصوصاً هذه الأيام مع تزايد عدد البيانات والمستخدمين سواء في التخزين أو المعالجة أو حتى في الارسال، والطلب على مطورين الويب الذي لديهم خبرة في ال Scalability أصبح اعلى بكثير من مبرمجي الويب بدون أي معرفة أو خبرة بهذا الموضوع.
وبالرغم من تزايد الطلب حول هذا الموضوع، وحتى في متطلبات المشاريع خصوصاً في الشركات الناشئة أصبح موضوع ال Scalability مهم ويدخل ضمن الاعتبار في أولى المراحل، الا أنه يندر وجود مقالات أو مواضيع تتناول هذا الموضوع بشكل جيد. ومن هذا المنطلق بدئت فكرة هذه السلسلة من المقالات التي تتحدث حول هذا الموضوع وتم الاعتماد على أحد الكتب الجيدة (راجع قائمة المصادر في آخر المقالة) في هذا المجال كمصدر أساسي بالإضافة الى خبرتي الشخصية في بناء بعض من المواقع والشبكات الاجتماعية والتي احتاجت ان تكون Scalable.
موضوع ال Scalability لا يعتبر من المواضيع السهلة، ولكن في هذه المقالة سوف نبدأ من اول الأساسيات ومن ثم تتدرج رويداً في المفاهيم، وأي مطور ويب ولو حتى مبتدئ سوف يستطيع إتمام هذه المقالة وبقية المقالات ان شاء الله. وبالطبع كل المفاهيم تطبق بغض النظر عن اللغة او المكتبة او حتى نظام التشغيل.
ما هي ال Scalability؟
كثيراً ما نسمع عن هذا المصطلح ولكن لا ندري كيف يمكن أن نقوم به فعلياً ونطور أنظمة تكون قابلة لتحمل المزيد من البيانات والمستخدمين وهذا هو حال غالب التطبيقات والخدمات الجديدة خصوصاً لل Startup، لذلك الطلب وفرص العمل ستكون أفضل لمطوري تطبيقات الويب الذي لديهم معرفة في هذا الموضوع.
من أحد تعاريف ال Scalability (قابلية التوسع): هو القدرة على جعل النظام يستطيع تحمل المزيد من البيانات، المستخدمين، الطلبات والعمليات بحيث يلبي أهدافك بتكلفة مناسبة بدون التأثير على أداء واستجابة النظام User Experience وفي نفس الوقت تستطيع ان تزيد Scale Up أو تقلل Scale Down متى ما أردت.
ال Scaling Down اقل أهمية من ال Scaling Up لكنه بالطبع يفيد في بعض الحالات مثلاً في الشركات الناشئة والتي تريد ان تقلل المنصرفات بأكبر وسيلة خصوصاً بعد ما يحصل تغير في العمل أو في بعض المتطلبات أو وجد أنه في وقت معين لا يوجد أي ضغط او استخدام على التطبيق فيمكن أن يقوموا بتقليل الموارد عليه في تلك الفترة.
عادة التحديات التي يحتاج أي نظام بدء الضغط عليه هي:
- التعامل مع المزيد من البيانات Data: وهي أول هذه التحديات وأشهرها ايضاً، فكلما توسع مشروعك وأصبح شائعاً فكلما زاد البيانات فيه أكثر وأكثر. لذلك عليك أن تتعامل معها بشكل أكثر كفاءة مثلاً حسابات المستخدمين User Accounts، المنتجات Products والخ من أي معلومات في نظامك. معالجة هذه المعلومات سوف يضع حملاً على النظام فهذه المعلومات تحتاج أن ترتب Sorted، أو تبحث خلالها Search، أو أن تجلبها من ملفات Reading، أو تكتبها على القرص Writing، أو ترسل عبر الشبكة Sending. وهذه الأيام مع توفر أدوات تحليل البيانات الضخمة Big Data Analytics فالشركات أصبحت شهيتها مفتوحة لتخزين المزيد والمزيد من البيانات.
- التعامل مع المزيد من الطلبات في نفس اللحظة Concurrency: ونعنى عدد المستخدمين الذين يمكن أن يستخدموا النظام في نفس اللحظة بدون التأثير على الأداء، وهذا الأمر صعب لأن السيرفرات التي يعمل فيها النظام لديها عدد محدود من الموارد (عدد معين من المعالجات CPUs) وال Threads ايضاً. وكلما زاد ال Concurrent Users كلما زاد عدد الطلبات المفتوحة Open Connections وزاد عدد ال Active Threads وزادت الأشياء التي ينبغي معالجتها في نفس اللحظة وبالتالي يزيد ال CPU Context Switching
- التعامل مع زيادة معدل ارسال واستقبال المعلومات Interaction Rate: ونقصد معدل ارسال واستقبال المعلومات بين المستخدمين والنظام وهي قريبة من فكرة ال Concurrency ولكن باختلاف بسيط. على سبيل المثال في المواقع العادية فإن المستخدمين يقوموا بالتحرك في صفحاته كل 15 او 20 ثانية بينما مثلاً في الألعاب المتعددة المستخدمين فمعدل ارسال واستقبال المعلومات يكون أكثر من مرة في الثانية. لذلك فال Interaction Rate يمكن أن يكون أكبر أو اقل على حسب نوع التطبيق الذي تقوم ببنائه بغض النظر عن عدد المستخدمين الحاليين. التحدي هنا هو في التباطئ Latency فكلما زاد هذا الرقم فأنت تريد أن يستجيب النظام بشكل سريع وهذا يتطلب سرعة في عمليات القراءة والكتابة.
ربما قد تكون قد لاحظت أن ال Scalability مرتبطة مع ال Performance ولكن هما ليسا نفس الشيء. فالأداء Performance يقيس كم الوقت المطلوب حتى يتم معالجة الطلب او القيام بعمل معين، بينما ال Scalability تقيس الى أي مدى ممكن ان نزداد Grow أو نقل Shrink.
مثال: إذا كان لديك 100 مستخدم حالي Concurrent وكل منهم يرسل طلب كل 5 ثواني ففي هذه الحالة سوف نحتاج الى ان تكون استجابة الموقع هي حوالي 20 طلب في الثانية ويمكن ان توضح ضمن المتطلبات للمشروع (أي Throughput requirement). فالأداء Performance هنا يقيس الوقت المطلوب لخدمة 20 طلب في الثانية، بينما ال Scalability تقيس كم أكبر عدد مستخدمين وطلبات يمكن معالجتهم بدون تقليل في الأداء.
أخيراً، فال Scalability لا تنحصر في جانب المشروع نفسه وانما ايضاً تدخل في المؤسسة أو فريق العمل نفسه، فكلما يكبر النظام فسوف تحتاج الى طريقة لترتيب العمل Organizational Scalability والا فلن يستطيع التغيير أو التكيف مع التغييرات بشكل سريع. وبالرغم من ان ال Organizational Scalability ليست متعلقة بالتقنية لكن لأنها تحدد بواسطة معمارية وتصميم المشروع. فاذا كان كود النظام مرتبط بشكل كبير Tightly Coupled فهذا يصعب زيادة عدد المطورين وادارتهم في هذا المشروع.
لكي تعرف كيف تؤثر ال Scalability على الشركات الناشئة فانظر من منظور الأعمال وأسأل نفسك “ما هي الأشياء التي تمنع المشروع من التقدم والكبر” فهي ليست في عدد المستخدمين والبيانات وانما يدخل بها طريقة التطوير Development Processes والفريق وبنية الكود ايضاً. وسوف يتم مناقشتها في آخر مقال في هذه السلسلة.
الانتقال من سيرفر واحد الى جمهور أكبر
سوف نوضح الآن مراحل التطور في مشروعك وكيف تصل من اول مرحلة صغيرة (استضافة صغيرة أو على سيرفر واحد) الى مرحلة تستطيع فيها أن تقوم بعملية ال Scaling وجعل تطبيقك يستحمل عدد أكبر بنفس الأداء (على عدة سيرفرات حول العالم).
بعض من هذه المراحل سوف تعمل فقط في حالة إذا كنت قد خططت لها منذ البدء في المشروع. لكن للأسف في الحياة الواقعية فأغلب الحالات لا تكون كذلك، وقد تحتاج لإعادة كتابة النظام أو أجزاء منه عدة مرات حتى تصل لتلك المرحلة. وفي اغلب الحالات فإن النظام يولد في مرحلة من هذه المراحل ويظل على ذلك طيلة فترة حياته أو ربما يقوم يصعد سلم أو اثنين في الدرج حتى يوصل الى مرحلة لا يمكن بها التحسين Architectural Limits.
كل النقاط سوف يكون بشكل مبسط high level، بحيث سوف يتم تغطية كل الأجزاء مجدداً في مقالات منفصلة حتى يتم الغوص في تفاصيل ذلك الجانب، وهكذا سوف تبقى المقدمة هذه هي المرجع لك للمراجعة وتذكر الشكل العام وكيف تعمل الأجزاء مع بعضها البعض.
الصورة 0 تبين مخطط المراحل وكيف أنك ستبدأ عادة من الدرج الأول (سيرفر واحد) وكيف يمكن أن تتطور وتضيف أمور تساعد في جعل المشروع قادراً على تحمل الضغط مع مرور الوقت. وسيتم تناول هذه المراحل فيما يلي.
تجنب إعادة كتابة التطبيق من الصفر بأي طريقة، خصوصاً لو هذه Startup. فكتابته من الصفر سوف تأخذ وقتاً أطول مما كنت تتوقعه وأصعب ايضاً مما تظن. وسوف توصل لنفس المشاكل في الكود والتصميم mess فقط بعد سنتين تاليتين.
بيئة مكونة من سيرفر واحد Single Server Configuration
لنبدأ من أسهل وأول طريقة تبدأ بها كل المشاريع، الا هي سيرفر واحد فقط يتم وضع عليها كامل التطبيق فيها. الصورة 1 تبين كل الطلبات للمستخدمين تعالج بواسطة نفس السيرفر، وغالباً ال Domain Name System (اختصاراً DNS) يكون بواسطة خدمة مدفوعة من شركة أخرى ولا تعمل على نفس السيرفر. في هذه الحالة المستخدمين سوف يتصلوا بال DNS لكي يحصلوا على عنوان ال Internet Protocol (اختصاراً IP) للسيرفر الذي يوجد عليه الموقع، بعد أن يحصلوا على ال IP يتم ارسال طلبات HTTP للويب سيرفر.
لأن هذه التركيبة (ال Setup) مكونة من جهاز واحد فهو يجب أن يقوم بكل المهام المطلوبة حتى يشغل تطبيقك، فقد يحتوي على نظام إدارة قاعدة البيانات MySQL أو Postgres أو أي نوع آخر، بالإضافة الى الصور واي محتوى اخر من التطبيق مثل الصور والفيديو والخ.
الصورة 1 تبين أيضاً توزيع الضغط Traffic في هذه البنية، فالمستخدمين سوف يتصلوا اولاً بال DNS لكي يقوموا بالحصول (تسمى عملية Resolve ) على ال IP لعنوان موقعك وبعدها يتم ارسال الطلبات الى ذلك الويب سيرفر.
وكل الصفحات والصور وملفات CSS والفيديو سوف يتم توليدها او ارسالها من هذا السيرفر. والخطوط في الصورة 1 (العريض أو النحيف) تبين مدى حجم الضغط على السيرفر أو على مزود ال DNS.
التطبيقات مثل هذه تكون مناسبة لموقع الشركات البسيطة التي تحتوي على بضعه منتجات ومدونة ومنتدى حوار ومجموعه من الخدمات الصغيرة. هذه المواقع الصغيرة لا تحتاج الى سيرفر فيزيائي خاص لها Dedicated Server وفي العادة يكفي سيرفر وهمي Virtual Private Server (اختصاراً VPS) أو حتى استضافة مشتركة Shared Hosting.
ال Virtual Private Server واختصاراً VPS هو مصطلح يستخدم لكي يشير الى وجود Virtual Server تستطيع تأجيرها، فعندما تقوم بذلك فسوف تكون موجودة هي وغيرها من ال Instances على سيرفر واحد. وال VPS تتعامل معه كأنه سيرفر عادي ففيه نظام تشغيل وكل الصلاحيات لديك. ولكنه أرخص من السيرفر الفيزيائي dedicated server لأن الشركة المزودة تضع أكثر من Instance على نفس السيرفر بعكس الكامل يكون كامل لك.
ال VPS هو بداية جيدة فهو رخيص ويمكن ان تزيد قدراته Upgraded سواء من الذاكرة Random Access Memory (اختصاراً RAM) أو من ناحية المعالج Central Processing Unit (اختصاراً CPU) بسهولة.
الاستضافة المشتركة Shared Hosting هي الارخص، فأنت تشتري حساب بدون أي صلاحيات إدارية، وحسابك يكون موجود على سيرفر مع العديد من حسابات العملاء الاخرين، ايضاً هو بداية جيدة للمواقع الصغيرة او صفحات الهبوط Landing Pages لكنه محدود لذلك لا ينصح به.
للمواقع التي لا يوجد ضغط عليها فسيرفر واحد يكفي لمعالجة طلبات المستخدمين. لكن هناك العديد من الأسباب التي تجعل هذه التركيبة Configuration لا تنفع من منظور ال Scalability:
- كلما زاد عدد المستخدمين، سوف يزيد الضغط traffic وهذا يستهلك الموارد مثل الذاكرة، وقت المعالج، وعمليات القراءة والكتابة على القرص.
- كلما زادت البيانات زادت حجم قاعدة البيانات، وسوف تصبح بطيئة في الاستعلام بسبب متطلبات المعالج والذاكرة وال I/O الإضافية.
- قد تضيف مجموعه من الخصائص الجديدة Features مستقبلاً في الموقع وهذا يضيف ايضاً حملاً على الموقع.
جعل السيرفر أقوى عن طريق Scaling Vertically
عندما يصل التطبيق لأخر حد في السيرفر بسبب زيادة الضغط أو كمية البيانات أو المستخدمين في نفس الوقت) فسوف تحتاج ان تقرر كيف سوف تقوم ب Scaling. وهناك طريقتين هما Vertical وHorizontal. سوف يتم توضحيهم فيما يلي وسنبدأ نبدأ بالأبسط والأكثر شيوعاً وهو ال Vertical Scalability.
ال Vertical Scalability تتم من خلال زيادة قدرة السيرفر سواء بزيادة مواصفات Upgrading hardware أو زيادة قدرة الشبكة Network throughput. وهي في العادة ابسط الحلول للقيام لعمل Scalability لفترة قصيرة (short-term scalability) حيث أنها لا تتطلب أي تغير في طريقة بناء architecture الكود). مثلاً إذا كانت الذاكرة في السيرفر هي 8GB فيمكن ان تجعلها 32GB أو حتى 128GB بسهولة عن تطريق تغيير القطع، ولا تحتاج لتغيير أي جزئية في الكود. إذا كنت تستضيف موقعك في VPS فال Vertical Scaling تكون سهلة من خلال عدة نقرات في شاشة لوحة التحكم لمزود الخدمة.
هناك عدة طرق لكي تقوم بال Vertical Scaling:
- إضافة المزيد من ال I/O عن طريق المزيد من الأقراص Hard Drives في Redundant Array of Independent Disks (اختصاراً RAID). ال I/O throughput وال Disk Saturation هي من أحد ال Bottleneck في قواعد البيانات. إضافة المزيد من الأقراص وتهيئة ال RAID يساعد في توزيع عمليات القراءة والكتابة على هذه الأقراص. في السنوات الأخيرة فال RAID 10أصبح شائعاً ويعطي المزيد من ال throughput وال Redundancy. من وجهة نظر التطبيق ال RAID Array هي كأنها قرص واحد Single Volume لكن بالأسفل هي مجموعه من الأقراص توزع عليها عمليات القراءة والكتابة.
- تحسين سرعة ال I/O من خلال استخدام ال Solid State Drive (اختصاراً SSDs). فال SSD أصبحت شائعة ايضاً والاسعار سوف تقل مع الوقت. عمليات القراءة والكتابة العشوائية أسرع بحوالي 10 الى 100 مرة على حسب طريقة ال Benchmark المستخدمة. وبتبديل الأقراص الى هذا النوع سوف تقلل وقت انتظار I/O في تطبيقك. لسوء الحط عمليات القراءة والكتابة المتسلسلة Sequential ليست سريعة ولن ترى أداء أفضل من الأقراص العادية. العديد من قواعد البيانات المفتوحة مثلاً MySQL حسنت داخلياً في هيكلتها والخوارزميات حتى تسمح بعمليات متسلسلة أكثر Sequential Disk Operation من العمليات العشوائية Random Access I/O. لكن بعض القواعد مثلاً Cassandra تستخدم عمليات متسلسلة بطيئة لكل عمليات القراءة والكتابة وبالتالي هذا يجعل ال SSD لا يفيد كثيراً هنا.
- تقليل ال I/O Operations عن طريق زيادة الذاكرة RAM، فحتى ال 128GB هي في المتناول هذه الأيام إذا كان لديك Dedicated Hardware. بإضافة المزيد من الذاكرة يعني المزيد من المساحة لل File System Cache وذاكرة أكبر للتطبيق. حجم الذاكرة مهم ايضاً في قواعد البيانات Database Servers.
- تحسين ال Network Throughput من خلال ترقية ال Network interface او إضافة المزيد منها، فاذا كان السيرفر يقوم بعمل Streaming للكثير من الوسائط والفيديو فيمكن أن تقوم بعمل upgrade لل network provider’s connection او upgrade لل network adapter حتى يسمح للمزيد من ال throughput.
- الانتقال الى سيرفر به معالجات أكثر أو Virtual Cores أكثر. السيرفر ب 12 او 24 ثريد (او Virtual Cores) أصبح متناول ايضاً، وكلما زاد المعالجات وال Virtual Cores كلما زادت المعالجة في نفس اللحظة، ويصبح النظام أسرع وليس فقط بسبب ان العمليات لن تتشارك كلها في معالج ولكن بسبب ان نظام التشغيل سوف يقوم بعمليات Context Switchingأقل ولن يحتاج لتشغيل أكثر من عملية في نفس ال Core.
ال Vertical Scalability هي خيار ممتاز خصوصاً للتطبيقات الصغيرة او إذا كنت قادر على تحمل تكاليف إضافة المزيد من ال Hardware. والشيء الجيد هنا أنك لا تحتاج لتغيير أي كود في التطبيق. لكن في المقابل هناك بعض من المشاكل فيها ايضاً، اولاً التكلفة. حيث ان ال Vertical Scalability سوف تصبح مكلفة جداً بعد مرحلة معينة.
الصورة 2 تبين ان ال scale up (ال Vertical Scaling) في البدء يكون رخيصاً ولكن بعد مرحلة معينة فسوف يصبح مكلفاً جداً، على سبيل المثال الحصول على 128GB من الذاكرة يكلف حوالي 3000$ ولكن ال 265GB تكلف حوالي 18000$ وهي أكثر من الضعف.
المشكلة الثانية في ال Vertical Scalability هي انها لها نهاية أيضاً. بعض النظر عن المبلغ الذي تود أن تدفعه فهناك نهاية لن تستطيع بعدها إضافة المزيد من الذاكرة او المعالجات او ال Cores أو حتى سرعة القرص. لذلك هناك نقطة نهاية ولن تجد hardware متوفر يستطيع ان يدعم ذلك النمو.
المشكلة الثالثة وهي أن نظام التشغيل والبرامج وحتى التطبيق نقسه قد لا يسمح بال Vertical Scaling بعد مرحلة معينة، على سبيل المثال لن تستطيع إضافة المزيد من ال CPUs لتحسين ال MySQL وذلك بسبب مشكلة زيادة ال lock contention (خصوصاً إذا كنت تستخدم المحرك القديم من ال MySQL الذي يعرف ب MyISAM).
ال Locks تستخدم لعمل ال Synchronization بين ال Threads التي تعمل على مورد مشترك مثلاً الذاكرة او ملف. مشكلة ال Lock Contention هي مشكلة في الأداء Performance Bottleneck بسبب عدم معالجة ال lock بشكل جيد. استخدام ال lock يجب أن يكون بشكل معقول والا فمعظم وقت البرنامج سوف يكون في انتظار إزالة ال Lock، وإذا وصلت لهذه المرحلة lock contention فإضافة المعالجات CPUs لن يضيف لك نتيجة جيدة
الصورة 3 تبين أن ال vertical scalability لا تغير من هيكلة وبنية النظام System Architecture ولن تغير أي شيء في الكود. فقط سوف تضيف قطعة hardware أو تبدلها بأخرى أسرع أو أفضل في الإمكانيات.
فصل الخدمات Services Isolation
ال Vertical Scalability ليس الخيار الوحيد في المراحل الأولى من التطور، هناك خيار بسيط وهو نقل أجزاء مختلفة من النظام على سيرفرات مختلفة وذلك بوضع كل خدمة على سيرفر مستقل physical machine. مثلاً وضع الموقع على ويب سيرفر في سيرفر منفصل، ووضع قاعدة البيانات على سيرفر آخر. وحتى ايضاً على مستوى الخدمات الأخرى فيمكن فصلها مثلاً File Transfer Protocol (اختصاراً FTP) أو ال DNS أو ال Cache فكل منهم يمكن ان تعمل على سيرفر منفصل.
ال Services Isolations هي تطور أفضل من ال Single Server Setup ولكن لن يأخذك بعيداً. على أي حالة بمجرد تنزيلك الخدمات على السيرفرات لن تستطيع لن تجد أي مساحة أخرى للنمو Grow.
ال Cache هو خدمة أو سيرفر مهمته تقليل التأخير والموارد وذلك بإرسال النتائج التي سبق وتم جلبها أو حسابها، وال Caching هي خطوة مهمة جداً في ال Scalability وسوف نتحدث عنها فيما بعد في مقالة مخصصة.
الصورة 4 تبين شكل ال Infrastructure لكل من هذه الخدمات حيث كل منها على سيرفر منفصل، وهذه البنية تبدوا مشابه لبنية السيرفر الواحد Single Server Setup ولكن هي فصلت ال load ووزعتهم على بعض السيرفرات. هذه السيرفرات سواء كانت VPS أو Dedicated فكلها في data center واحدة. وال data center هنا هي مجموعه من السيرفرات وكل منها لديه وظيفة معينة.
فصل الخدمات هي خطوة جيدة تأتي كخيار تالي ل Single Server Setup، حيث يتم توزيع ال load على العديد من السيرفرات وتستطيع ايضاً عمل Vertical Scaling لكل منهم بشكل منفصل.
هذه التركيبة Configuration شائعة في المواقع الصغيرة وفي شركات البرمجة التي تقدم خدمات للشركات، حيث يمكن مثلاً وضع كل مواقع العملاء الصغيرة في سيرفر واحد بينما العميل الكبير يوضع على سيرفر منفصل وايضاً على قاعدة بيانات منفصلة. وهذه إدارة جيدة للموارد.
بنفس الطريقة، يمكن أن يوضع الموقع على عدة أجهزة عن طريق تقسيم الموقع الى أجزاء منفصلة واستضافتها في سيرفرات منفصلة، مثلاً إذا كان هناك لوحة تحكم Administrative Console يستطيع العملاء إدارة حسابتهم فيمكن ان تكون على موقع منفصل وتوضع على سيرفر منفصل.
الفكرة من ال Services Isolation هي انه عليك تقسيم تطبيقك الكبير الى مجموعه من الوظائف التي يمكن ان تضعها على سيرفرات منفصلة، وعملية تقسيم النظام بناء على الوظائف حتى تقوم بعمل Scaling لأي وظيفة منها بشكل منفصل تسمى Functional Partitioning.
الصورة 5 تبين كيف يقوم الموقع بتقسم المهام functional partitioning لكي يوزع الضغط load على سيرفرات مختلفة. فكل جزء من التطبيق لديه subdomain وال traffic سوف يوجه اليه على حسب ال IP. لاحظ أن كل من هذه الوظائف سوف تكون على سيرفرات قد تختلف مواصفتها وكل منهم لديه احتياجات Vertical Scaling مختلفة. فهذه المرونة في ال Scaling لكل جزء من التطبيق امر جيد.
ال Content Delivery Network: عمل Scaling للموارد الثابتة Static Content
كل ما يكبر التطبيق ويزداد الضغط عليه بواسطة المستخدمين، فمن المفيد نقل الضغط offload traffic لأي جهة ثالثة third party تتولى مهمة ال Content Delivery Network (اختصاراً CDN).
ال Content Delivery Network هي خدمة تتولى توزيع الملفات الثابتة مثل الصور، ملفات الجافا سكربت، ال CSS، الفيديو. فهي تعمل ك HTTP Proxy. فعندما يريد المستخدم (المتصفح) تحميل الصور أو أي من الملفات الثابتة فسوف يتصل بأحد السيرفرات التي يقدمها ال CDN بدلاً من سيرفرك. وإذا لم يتوافر ذلك الملف على ال CDN فسوف يطلبها من سيرفرك وبعدها يقوم بالاحتفاظ بها Caching لديه. بعد ذلك أي طلب اخر على ذلك الملف سوف يرسل مباشرة بدون الحاجة الى الاتصال بسيرفرك مرة أخرى.
بربط تطبيقك مع ال CDN Provider سوف تقلل الكثير من ال Bandwidth وسوف تحتاج مجموعه صغيرة من السيرفرات حتى تخدم طلبات ال static content. ايضاً سوف يستفيد المستخدمين من ال Resources Locality حيث ان ال CDN Providers هي شركات لديها data centers موجودة في أماكن مختلفة في انحاء العالم. فاذا كان ال data center موجود على شمال أمريكا فالمستخدمين من أوروبا سوف يكون لديهم تأخير واضح higher latencies وفي هذه الحالة ال CDN سوف يسرع عملية تحميل الصفحة page load time لهؤلاء المستخدمين لأنه يزود بالملفات الثابتة من أقرب data center متوفر لهم.
الصورة 6 توضح كيف يرتبط التطبيق مع ال CDN Provider، العميل سوف يتصل بال DNS Server وبعدها يطلب الصفحات من سيرفر ويقوم بتحميل الموارد الأخرى مثل الصورة وملفات CSS من ال CDN Provider. والنتيجة هو أن سيرفرك سوف يقل عليه الضغط وتكون هذه مسؤولية ال CDN والتي سوف يحلها بشكل جيد وتكلفة أرخص مما لو كنت ستقوم بها بنفسك.
الشيء الذي يهم هنا هو أن هذه المرة الأولى التي نستخدم third party service للقيام بعملية ال Scaling. وربما قد تظنها أن هذه خدعة في عملية ال scalability ولكنها حقيقة خطوة جيدة خصوصاً للشركات الناشئة التي تكون في اول مراحل التطوير ولا تستطيع وضع جهد او مال في ذلك الموضوع.
توزيع الضغط traffic عن طريق ال Horizontal Scalability
كل المراحل evolution stages التي ذكرناها حتى الان تعتبر تعديلات بسيطة على تركيبة السيرفر الواحد Single Server Setup، بينما ال Horizontal Scalability هي أصعب في التطبيق وأغلب الأحيان تحتاج أن تضعها بالاعتبار قبل أن تبدأ في برمجة التطبيق. وفي حالات نادرة فيمكن ان تضاف لاحقاً عن طريق تعديل معمارية architecture المشروع لكن هذا يتطلب مجهود كبير في التطوير. تستطيع ان تتخيل الان انها عبارة عن تشغيل عدة مكونات على عدة سيرفرات وتستطيع إضافة عدة سيرفرات متى ما اردت. والأنظمة التي لديها القدرة على ال Horizontal Scaling لا تحتاج لسيرفرات قوية، بالعكس تماماً فهي عادة تعمل على سيرفرات عادية رخيصة.
ال Horizontal Scalability تكون عن طريق إضافة المزيد من السيرفرات، وهي الهدف في ال Scalability حيث تحل مشكلة التكلفة الضخمة المرتبطة بالسيرفرات القوية، وتستطيع إضافة العديد من السيرفرات ولا توجد نهاية في ذلك بعكس النهاية الموجودة في ال Vertical Scalability.
الصورة 7 توضح الفرق في التكلفة بين ال Horizontal Scalability وال Vertical Scalability، الخط المنقط يوضح التكلفة لل Vertical Scalability بينما الخط المتصل يوضح لل Horizontal Scalability.
عادة ما تتضح فائدة ال Horizontal Scaling في مراحل تالية في المشروع، حيث في البداية تكون تكلفتها اعلى لأنها تتطلب المزيد من العمل والتطوير لكي يدعم المشروع هذه الطريقة. وبعض الأحيان تكلف أكثر من ناحية السيرفرات المطلوبة في تشغيل المشروع بشكله الأولى. واحياناً بسبب أنك تحتاج لمهندسين لديهم خبرة أوسع في التطوير والتشغيل ايضاً.
النقطة المهمة هو انه بعد أن تتعدى نقطة معينة من ال capacity فال horizontal scalability سوف تتضح ثمرته، حيث تقل التكلفة ولن تصل لمرحلة النهاية التي تحصل في ال vertical scaling عندما لا تجد أي hardware اقوى.
أيضاً عمل ال Horizontal Scaling باستخدام ال CDN Provider يقلل عليك الكثير من الأمور مثل التكلفة وبالرغم من أنه سيتم محاسبتك بشكل أكبر كلما زاد الضغط على الموقع، لكن التكلفة او السعر هي ثابت لكل سعة تريدها وسوف تتضاعف التكلفة مثلاً إذا تضاعف عدد الزوار، لكن هناك بعض المزودين يقل السعر كلما زاد الضغط على الموقع مثلاً Amazon CloudFront سوف يحاسبك 0.12$ لكل GB حتى اول 10 TB بعد ذلك سوف يقل السعر الى 0.08$ لكل GB.
للنظر الى ال Infrastructure الان في هذه المرحلة بعد أن قمنا بوضع كل جزء من النظام على سيرفرات مختلفة سوف يكون كما في الصورة 8.
الشيء الذي يميز ال horizontal scaling عن المراحل السابقة هي أن كل سيرفر يمكن أن يقوى scaled عن طريقة إضافة المزيد من السيرفرات. وهذا يمكن تطبيقه على مراحل فمثلاً بعض الخدمات تكون Horizontal Scalable وبعضها تكون لا تكون. ولأن القيام بال Horizontal Scalability أمر صعب ومكلف فيجب أن تقوم بعمل scaling Horizontal في الأماكن السهل القيام بها مثلاً الويب سيرفر وال caches وبعدها انظر للمناطق الأكثر صعوبة مثلاً قواعد البيانات أو أي طرق التخزين الأخرى.
في هذه المرحلة من التطور بعض التطبيقات تستخدم Round Robin DNS لكي توزع ال traffic على العديد من السيرفرات. لكن ال Round Robin DNS هي ليست الطريقة الوحيدة لذلك، وسوف نناقش الطرق الأخرى في مقال آخر.
ال Round Robin DNS هو DNS Server يسمح بربط عنوان واحد domain name بعدة IPs. ال DNS العادي يأخذ Domain مثلاً informatic-ar.com ويجلب ال IP الوحيد له مثلاً 172.236.152.169. ولكن ال Round Robin يربط اسم الموقع بعدة عناوين وكل منها مرتبط بسيرفر منفصل. وهكذا كل ما يطلب العميل رقم ال IP للموقع name resolution فيقوم بال DNS بالرد بأحد العناوين الموجود عنده. الهدف هو توزيع الطلبات على السيرفرات الموجودة للموقع فالمستخدمين قد يتعاملوا مع سيرفرات مختلفة بدون أي يدروا عن ذلك.
ال Scalability لمستخدمين من كل انحاء العالم Global Audience
المواقع الكبيرة تصل لآخر مرحلة في ال evolution وهي للمستخدمين من كل انحاء العالم. فبمجرد أن يكون لديك ملايين من المستخدمين من كل انحاء العالم فسوف تحتاج لأكثر من data center. ال data center الواحد يحتوي على العديد من السيرفرات لكنه سوف يكون بطيئاً لمستخدمين في منطقة جغرافية أخرى. ولكن مع مجموعه من ال data center فهذا ايضاً يجعلك مهيئ للكوارث والاحداث النادرة مثلاً عاصفة أو حريق.
ال Scaling للمستخدمين من كل انحاء العالم في الكثير من التحديات ويحتاج المزيد من العمل. أحد الأمور التي ينبغي العمل عليها هو استخدام GeoDNS.
ال GeoDNS هو DNS Service تسمح لأسماء المواقع بأن ترتبط Resolved بعناوين IPs تكون على حسب مكان العميل. ال DNS العادي يحول اسم الموقع الى عنوان IP بينما ال GeoDNS يقوم بنفس المهمة من وجهة نظر المستخدم لكن يعطي رقم IP مختلف بناء على موقع العميل. مثلاً العميل المتصل من أوروبا يحصل على عنوان IP يختلف عن العميل المتصل من استراليا. النتيجة أن كل عميل يتصل بال data center الأقرب لمكانه وبالتالي يقلل تأخير الشبكة network latency.
إضافة أخرى في ال infrastructure هي باستضافة عدة من سيرفرات Edge-Cache تكون موجودة حول العالم لتقليل تأخير الشبكة أيضاً. استخدام ال Edge-Cache Servers يعتمد على حسب طبيعة التطبيق، فال Edge-Cache Servers تكون أكثر كفاءة عندما تعمل ك Reverse Proxy Servers تقوم بعمل Caching كل الصفحات لكن ايضاً يمكن جعلها تقوم بمهام أخرى.
ال Edge Cache هو HTTP Cache server يكون موجود قرب العميل، ويسمح للعميل باحتفاظ جزئي partially cache لل http traffic. الطلبات التي تأتي من متصفح العميل تذهب الى ال Edge-Cache server وهو الذي يقرر هل يخدم الطلب من ال Cache أو ان يجمع الأجزاء الناقصة من الصفحة عن طريق ارسال طلبات الى ال web servers وايضاً يقرر إذا كانت الصفحة غير محتفظة uncacheable ويقوم بجلبها كاملة من السيرفر. ال Edge-Cache يخدم اما الصفحات كاملة او أجزاء منها cache fragments of HTTP response.
الصورة 9 يوضح كيف تعمل عدة data centers وتخدم طلبات المستخدمين الموجودين في شتى انحاء العالم. المستخدمين الموجودين في أوروبا سوف يحصوا على ال IP لأحد ال Edge-Cache القريب من ذلك المكان ويمكن ان تتم خدمتهم من ال Cache أو من أحد ال Web Servers. وايضاً يتم تحميل الملفات الثابتة كالصور وال CSS من خلال CND Provider، ولأن ال CDN Provider لديه ايضاً data centers موجودة في عدة دول فهذا الملفات سوف ترسل من أقرب data center للعميل. وهكذا كل ما ينمو التطبيق سوف تقسم الى المزيد من ال data centers تكون أقرب للجمهور. وهذا يقلل التأخير والتكلفة ايضاً.
بعد أن ناقشنا هذه ال infrastructure بشكل مبسط، سوف ننظر كيف يعمل ال data center الواحد وكيف يدعم ال Scalability.
نظرة حول ال Data Center Infrastructure
سوف نتحدث الان حول عدة تقنيات مختلفة تستخدم في تطبيقات الويب الحديثة، وسوف نضع الشكل العام للآلية وكيفية تنتقل الطلبات بين الوحدات المختلفة.
الصورة 10 تبين الشكل العام للطلب Communication Flow بدئاً من جهاز المستخدم مروراً بعدة طبقات مختلفة في ال Infrastructure. وهذا التصميم يعتبر من الأمور المهمة في تصميم وتطبيق تطبيقات Scalable. لذلك يمكن ان تعتبرها كمرجعية لك تعود لها كلما تحدثنا في مقالات تالية عن موضوع ال Scalability. وايضاً المقالات التالية سوف تتحدث عن كل جزئ منهم بالتفصيل بحيث كل مقالة تتولى مهمة جزء (المرقمة بأرقام) من التصميم وتغطيه بشكل كامل.
العديد من الأجزاء التي في الصورة 10 لها مهمة واضحة ويمكن ان تضاف او تحذف بشكل مستقل. على أي حالة فمن الشائع أن ترى كل الأجزاء تعمل مع بعضها البعض في غالب التطبيقات الكبيرة. وسنبدأ نلقى الضوء على أي منهم بشكل مبسط.
الواجهة الامامية Font Line
الواجهة الأمامية هي الجزء الأول من ال Stack وهي مجموعه من المكونات التي يتعامل معها المستخدمين بشكل مباشرة. جزء من ال font line يمكن أن تكون داخل ال data center أو تكون خارجها وذلك حسب ال configuration وال third party services المستخدمة. هذه المكونات components لا يوجد بها أي business logic وهدفها الأساسي هي زيادة ال capacity والسماح بال Scalability.
لنبدأ بالطلب من المستخدم من الأعلى، حيث تذهب الطلبات الى ال GeoDNS Server ويقوم بعمل Resolving لاسم الموقع ويقرر ما هو ال data center المناسب لذلك العميل ويرجع له رقم ال IP لل Load Balancer على ذلك ال Data Center.
ال Load Balancer هو برنامج أو جهاز Software/Hardware يقوم بتوزيع الطلبات التي تأتي لرقم IP واحد الى عدة من السيرفرات والتي تكون مخفية أسفل ال Load Balancer. ال Load Balancer تأتيه كل الطلبات ويقوم بتوزيعها وهو يسمح للسيرفرات بأن تدخل أو تحذف، فلا مشكلة لأن كل الطلبات تأتي اليه وهو الذي يتولى توزيعها فالسيرفرات التي تضاف لن تؤثر على الخدمة.
الطلبات Traffic التي تأتي من الانترنت تكون موجهه الى رقم عنوان IP واحد ويكون وهو Hardware Load Balancer قوي، ويقوم بتوزيعها على ال Font Cache Servers (رقم 3 في الصورة) او مباشرة تذهب الى ال Web Application Servers (رقم 4 في الصورة).
ال Front Cache Servers هي اختيارية، ويمكن أن توضع Deployed على مكان آخر خارج ال data center او ان لا تضعها من الأساس. في بعض الحالات يفضل أن تكون لديك هذه الطبقة Font-End Cache والسيرفرات بها سوف تقلل الضغط Load الذي يوضع على بقية ال Infrastructure.
من الشائع استخدام أشياء جاهزة من جهة خارجية third party services مثلاً Load Balancer أو CDN أو Reverse Proxy servers. في هذه الحالات فأن هذه الطبقة قد تكون مستضافة على سيرفرات خاصة بمزود الخدمة. وسوف نتحدث عن الفوائد والعيوب في ال Scaling باستخدام جهة خارجية Third Party في مقالات تالية.
طبقة تطبيق الويب Web Application Layer
الطبقة الثانية في ال stack هي طبقة تطبيق الويب وهي تتكون من سيرفرات التطبيق (رقم 4 في الصورة) التي تكون مسؤولة عن معالجة طلب المستخدم وارجاع ال HTML أو البيانات من التطبيق. هذه السيرفرات تستخدم في الغالب مثلاً PHP, Java, Ruby, Groovy ويكون بها القليل من ال business logic لأن الهدف الأساسي من هذه السيرفرات هي عرض واجهة المستخدم User Interface. وسوف تقوم هذه الطبقة بمعالجة طلب المستخدم واستدعاء خدمات الويب المناسبة Web Services Call لتحقيق المهمة. وكلما تكون هذه الطبقة أخف Dumber كلما يكون أفضل ويكون كل ال business logic في ال web services. هكذا تزيد من ال Reuse وتقلل من التغييرات المطلوبة لأنه في الغالب ال Presentation Layer هي التي تتغير باستمرار.
سيرفرات تطبيق الويب من السهل ان تقوم عمل Scaling بها لأنها Stateless بشكل كامل (أو يفترض ذلك). وإذا كانت Stateless فإضافة ال capacity لها هي مجرد إضافة المزيد من السيرفرات في ال Load Balancer Pool. المقالة الثانية في هذه السلسلة سوف تتحدث عن ال front layer بالإضافة الى تطبيق الويب بتفاصيلهما.
طبقة ال Web Service
الطبقة الثالثة في ال Stack هي طبقة خدمات الويب Web Services (رقم 7 في الصورة). وهي طبقة مهمة لأنها تحتوي على كل ال Business Logic، حيث جعلنا ال Font-End Servers خفيفة بدون أي Business Logic حتى نفصل ال Presentation Layer عن Business Logic. ايضاً بإنشاء خدمات الويب فمن السهل القيام بعمل ال Functional Partitions حيث يمكن انشاء خدمات ويب مختصة بالقيام بمهام معينة ونقوم بتقويتها Scaling بشكل مفصول عن الخدمات الأخرى. على سبيل المثال في التطبيقات التجارية E-Commerce قد يكون لديك ويب سيرفس خاصة بالمنتجات وخدمة ويب خاصة بملف المستخدم وكل منهم لديها وظائف خاصة ولديها احتياجات Scalability مختلفة.
طريقة التواصل بين ال font-end applications مع ال web services تكون اما من خلال Representational State Transfer (اختصاراً REST) أو من خلال Simple Object Access Protocol (اختصاراً SOAP) من خلال بروتكول HTTP. وعلى حسب ال implementation فيمكن أن يكون خدمة الويب ايضاً سهلة ال Scaling. فطالما هي Stateless فال Horizontal Scaling سهلة بمجرد إضافة المزيد من الأجهزة على ال Pool.
مؤخراً في السنوات الأخيرة أصبح ال Integration مع تطبيقات الويب شائعاً لذلك من الشائع ان تجد ال Web Services متاحة مباشرة للعملاء ولذلك يتم وضعها بالتوازي مع ال font end application servers بدلاً من اخفائها بالأسفل. المقالة الثالثة من السلسلة سوف تتناول خدمات الويب وكيف يمكن تقسيمها بحيث تسهل التطوير وال Scalability.
مكونات أخرى Additional Components
لأن كل من سيرفرات ال font-end وال web services يجب أن تكون states. فان ال web application عادة ما يوضع به عدة مكونات إضافية مثل object caches (رقم 5 في الصورة) وال message queues (رقم 6 في الصورة).
سيرفرات ال caches تستخدم بواسطة ال font end application servers وايضاً ال web services لتقليل الضغط على قاعدة البيانات وتسرع ايضاً الرد لأنها تحفظ أجزاء من النتائج المسبقة حسابها partially precomputed results.
ال message queue ايضاً تستخدم لتأجيل postpone بعض المعالجة لمرحلة تالية وايضاً لإسناد هذه المهمة لمجموعة من أخرى من الأجهزة التي تتنظر هذه الرسائل لكي تقوم بمعالجتها (رقم 11 في الصورة). الرسائل messages عادة ترسل الى message queues من خلال ال font end applications او ال web services ويتم معالجتها بواسطة أجهزة مختصة لمعالجة الرسائل. بعض الأحيان يكون لل web application عدة cluster من السيرفرات التي تعمل على تنفيذ ومعالجة أشياء في الخلفية batch processing servers أو سيرفرات تقوم بعمل بعض من ال jobs في وقت schedule معين (بواسطة cron مثلاً). هذه السيرفرات (رقم 11 في الصورة) لن تدخل في توليد الرد response على طلبات المستخدمين وانما هي offline job processing servers تقوم بعمل مهام مثلاً asynchronous notification أو order fulfillment وغيرها من المهام والتي ان وضعت في التطبيق سوف تبطئ سرعة الرد والاستجابة high latency functions لذلك يتم فصلها.
سوف يتم مناقشة كل من ال caches وال message queues في مقالات منفصلة في هذه السلسلة.
طبقة تخزين البيانات Data Persistence Layer
وصلنا لطبقة تخزين البيانات (رقم 8 ورقم 9 في الصورة) وهي الطبقة الأصعب في ال horizontal scaling لذلك سوف تحتاج الكثير من النقاش حول الخيارات الموجودة لعمل ذلك ال scaling في هذه الطبقة. خصوصاً مع ظهور العديد من التقنيات الجديدة التي تسمى NoSQL أو Big Data حيث أن البيانات تزداد دائماً والتي تحتاج للتخزين والمعالجة بغض النظر عن المصدر والشكل. خلال ال 10 سنوات الماضية أصبحت هذه الطبقة بها بعض التغييرات فقد ذهبت الأيام التي تضع فقط قاعدة بيانات واحدة ضخمة single monolithic SQL database بها كل شيء. وكما قال Martin Fowler هي مرحلة ال Polyglot persistence حيث تستطيع استخدام عدة data store مع بعضهما حتى تضمن القيام ب scalability أفضل. سوف نتحدث عن هذه الطبقة في مقالة منفصلة.
رقم 9 في الصورة هي للبحث Search Engine ولأن البحث تغير خلال السنوات السابقة وأصبح هناك العديد من الخيارات خارج إطار قاعدة البيانات فقد وضعناها كمكون منفصل لأن لها ايضاً العديد من التفاصيل غير المتعلقة بطريقة التخزين، وسوف يكون لها مقالة منفردة تتحدث عن الأساليب والتقنيات التي تستخدم في البحث.
ال Data Center Infrastructure
حتى هذه اللحظة لدينا الكثير من التقنيات في ال infrastructure وايضاً كما تلاحظ زاد العقيد بشكل أكبر عما كان عليه في السابق عندما كان كل شيء على سيرفر واحد Single Server Setup. الذي انجزناه هو قابلية توزيع الضغط على العديد من السيرفرات. وكل مكون في الصورة 1-10 لديه مهمة معينة ويساعد في عمل ال Scaling لملايين من المستخدمين.
طريقة الطبقات ايضاً في الصورة كانت مقصودة حتى تقلل الضغط على المكونات البطيئة، فكما ترى أن كل الطلبات تأتي الى ال Load Balancer سوف تقسم على ال font end cache servers، ولأن بعض الطلبات هي cache hits فهذا يقلل ال traffic حيث يرجع ال font end servers النتيجة (رقم 4 في الصورة). ايضاً هناك ال application level caches (رقم 5 في الصورة) وال message queues (رقم 6 في الصورة) تساعد على تقليل الضغط بشكل أوسع وهذا يعني طلبات اقل سوف تصل لل backend web services (رقم 7 في الصورة). خدمات الويب تستطيع ايضاً استخدام ال message queue وال cache servers وإذا احتاجت فسوف تتعامل مع ال search engine وطريقة التخزين data store. بإضافة كل هذه ال scalable layer فوق ال data layer فتستطيع عمل ال scale على النظام بشكل جيد cost-effective way.
من المهم تذكر أنه قد لا تحتاج لكل من هذه المكونات لعمل ال Scaling، وعليك باستخدام أفضل تقنيات ممكنة لأن إضافة أي تقنية جديدة سوف تضيف المزيد من التعقيد والصعوبة في الصيانة والتكلفة ايضاً بها. وجود مكونات كثيرة ربما شيء مثير وتجربة جديدة لكن يجعل الإصدارات releases والصيانة maintenance وإجراءات ال recovery أكثر صعوبة. إذا كانت تطبيقك يحتاج مجرد صفحة بحث بسيطة فربما يكفي وجود font end servers وال search engine cluster وهذا ما تحتاجه لل scale. فاذا كنت تستطيع عمل scale لأي طبقة عن طريقة إضافة المزيد من السيرفرات وسوف يعمل ال business جيداً فلماذا تزعج نفسك بإضافة العديد من الطبقات الإضافية.
حول معمارية التطبيق Application Architecture
تحدثنا قبل قليل حول ال Infrastructure ومراحل تطويرها evolution stages والآن سوف ننظر الى التطبيق نفسه. معمارية التطبيق لا يجب أن تبنى حول أي تقنية أو framework معين، فالمعمارية Architecture هي ليست حول جافا أو PHP أو PostgreSQL أو حتى أي Database Scheme معينة، المعمارية يجب أن تبنى على حسب ال Business Model. هناك الكثير من الكتب والنقاشات حول موضوع ال domain-drive design ومعمارية الأنظمة يمكن ان تنظر لها للمزيد حول العادات الجيدة في بناء وتصميم البرمجيات. ولاتباع تلك العادة الجيدة سوف يكون ال business logic هو قلب المعمارية حيث أن متطلبات ال business هي التي سوف نعتمد عليها في أي قرارات نأخذها. وبدون هذه المتطلبات ال business logic الصحيحة وال domain model الواضح فربما كل طرق التخزين database أو ال message queues وحتى ال web formworks قد لا تكون مناسبة.
بغض النظر كان التطبيق هو social networking website أو خدمة للأطباء مثلاً او أي فكرة أخرى فهي في الأخير سوف يكون لها احتياجات ومتطلبات واضحة business need. وبوضع هذا الأمر في الاعتبار عند تصميم ووضع المعمارية سوف تكون متأكداً من ان المكونات التي تضعها لها هدف يخدم ذلك ال business وليس العكس. لذلك عندما تضع التقنية أو اللغة اولاً قبل النظر لل business ربما تحصل على تطبيق تقني جيد مثلاً Rails Application ولكن لن يكون تطبيق يخدم الهدف وال business جيداً.
ال domain model يمثل كل الأجزاء الأساسية في المشروع بلغة ال business وليس بلغة المطورين أو الأشخاص التقنيين. ال domain model يوضح المصطلحات، ال actors والعمليات بغض النظر عن طريقة تطبيقها التقنية. ال domain model مثلاً Automated teller machine (اختصاراً ATM) سوف تعني أشياء مثلاً الكاش cash، الحساب account، السحب credit الإيداع debit والصلاحيات authentication والسياسات الأمنية security polices وغيرها. وفي نفس الوقت ال domain model لا يهتم كثيراً بطريقة التطبيق سواء كان software أو hardware. ال domain model هو أداة لإنشاء الصورة العامة لمشكلة ال business التي يفترض أن يقوم تطبيقك بحلها.
الصورة 11 توضح الصورة المبسطة لكيف يمكن أن تكون أجزاء التطبيق من الداخل، والمستخدم سوف ينظر له على انه نظام واحد فقط لكنه من الداخل يكون موزع على العديد من الخدمات.
سوف نناقش الان كل من هذه المكونات بشكل مبسط، وبنفس الطريقة التي ناقشنا بها ال Infrastructure diagram سوف نتبع نفس الطريقة وهي أن يأتي الطلب من الأعلى من المستخدم.
ال Front End
ال Font End لديه هدف واحد وهو ان يكون واجهة المستخدم User Interface. حيث يتعامل معها المستخدم سواء عبر صفحات الموقع أو تطبيقات الجوال أو استدعاءات خدمات الويب. بغض النظر عن طريقة التواصل معها فال front end application هي طبقة تأخذ الطلبات التي تأتيها من المستخدم وتقوم باستدعاء خدمات الويب internal services call. ويمكن أن تعتبرها ك skin أو plugin للتطبيق تقدم خدمات النظام للمستخدمين. وهي لا يجب أن تكون قلب النظام بل تكون خفيفة بقدر المستطاع.
بجعل هذه الطبقة خفيفة dumb سوف تستطيع إعادة استخدام reuse ال business logic لأنها تكون موجود على طبقة خدمة الويب وبالتالي تتجنب خطر أن يكون هناك تشابك coupling مع ال presentation logic.
بالطبع كود ال font end يرتبط مع ال web framework المستخدم سواء Spring أو Rails المهم هو ان تعمل من خلال HTTP بالإضافة الى دعم AJAX وال Web Sessions. بإخفاء كل هذا في هذه الطبقة فسوف تكون طبقة الخدمات web services layer مختصة فقط بال business logic وليس العرض أو أي شيء متعلق بتقنية ما. لهذا الأمر فوائد عدة أولها أن ال business logic يكون مفصول وبالتالي يسمح للتطوير عليه بشكل مستقل، الفائدة الأخرى هذا يسمح باستخدام عدة تقنيات لكل طبقة بشكل مختلف مثلاً تستطيع تطوير ال font end من خلال PHP أو Groovy بينما خدمات الويب تكون مثلاً بالجافا.
يمكن ان تنظر لل font end application على انه إضافة plugin يمكن أن تحذف وتكتب بلغة أخرى وتضاف تلك الجديدة. مثلاً تستطيع حذف http front end وتضيف مثلاً Mobile application أو command line front end وهكذا يكون لديك الخيارات وفي نفس الوقت مفصولة عن ال business logic.
ال font end لا يجب أن تعرف أي شيء عن ال database أو أي خدمات أخرى، والمشاريع التي تسمح بوضع business logic في ال font end code سوف تعاني من مشاكل التعقيد ونسخ الأكواد وصعوبة ال Reuse.
اخر نقطة ال font end components يمكن ان ترسل رسائل الى message queues أو تستخدم cache back ends لأنهم يفيدان في السرعة فكل ما يكون لديك cache لكل صفحة ال html أو جزء منها كل ما قللت المعالجة وسرعت العملية.
خدمات الويب Web Services
خدمات الويب هي التي تحتوي على كل المعالجة وايضاً تحتوي على اغلب ال business logic. الصورة 1-11 بينت ال web service أنها قلب المعمارية وأنها في الوسط. وهذا في الغالب يدعى Service Oriented Architecture (اختصاراً SOA). مصطلح ال SOA له كثير من المعاني والتعاريف وقد يختلف على حسب السياق او الشخص ايضاً.
ال Service Oriented Architecture (اختصاراً SOA) هي معمارية تعتمد على ال Loosely coupled وال highly autonomous services وهدفها حل وتطبيق احتياجات ال business. في ال SOA فيفضل أن تكون لكل الخدمات عقد contract واضح وتستخدم نفس البروتوكول. بغض النظر عن ال Implementation سواء كان SOAP أو REST (باي صيغة JSON أو XML) لأن هذه تعتبر Implementation details. المهم هو ان الخدمات Loosely coupled ولديها هدف معين تريد القيام بها.
انظر للتقارب في المصطلحات بين ال SOA (service oriented architecture) وال SOAP (الاختصار الأول كان هو simple object access protocol) وقد تبدو متشابه SOA وال SOAP ولكن في الحقيقة ان ال SOA هو architecture style بينما ال SOAP هي مجموعة من التقنيات تستخدم لتعريف وإيجاد واستخدام خدمات الويب. فيمكن أن يكون لديك SOA بدون SOAP ويمكن أن تستخدم SOAP ايضاً في أي architecture styles أخرى.
تذكر أن ال SOA هي ليست حل لكل المشاكل وهناك طرق أخرى architecture styles مثلاً layered architecture وهناك ايضاً hexagonal architecture وهناك أيضاً event-driven architecture.
ال multilayer architecture هي طريقة لتقسم الوظائف الى مجموعه من الطبقات. المكونات في الطبقات السفلى تعطي Application Programming Interface (اختصاراً API) يمكن أن تتعامل معها الطبقة التي تكون أعلى منها ولكن لن تسمح لطبقة في الأسفل أن تعتمد على وظيفة معينة في أي من الطبقات الأعلى. مثال على ال Layered architecture هو في نظام التشغيل ومكوناته مثلاً الصورة 12 تبين ان هناك hardware وتعاريف الأجهزة ونواة نظام التشغيل، ومكتبات نظام التشغيل، والمكتبات الخارجية، واخيراً التطبيقات. كل طبقة منها تستخدم الخدمات التي تقدمها الطبقة التي تكون أسفل منها وليس العكس. مثال ايضاً هو بروتوكول TCP/IP حيث كل طبقة تضيف مهمة وتعتمد على ال contract التي يوجد في الطبقة التي أسفل منها.
تطبيق الطبقات بشكل صحيح تجبرك على عمل هيكلة structure وتقلل من التداخل لأن الطبقات التي في الأسفل سوف تكون بسيطة ولا تعتمد على شيء من النظام، ايضاً بالإمكان تبديل أي مكون في الطبقات السفلى بأي مكون طالما يطبق نفس ال API. لكن تغير ال API نفسها يكون أسهل في الطبقات الأعلى لأنه لا يوجد شيء تعتمد عليه بعكس الطبقات السفلى فعملية تغير ال API مكلفة لأن الطبقة الأعلى منها تعتمد عليها وتحتاج أن تتغير ايضاً.
ال Event Driven Architecture (اختصاراً EDA) ببساطة هي طريقة أخرى في التفكير حول الاحداث actions. وهو كما يدل اسمها فهي تكون حول كيف تتعامل مع الاحداث التي تحصل. الطريقة التقليدية هي الاستجابة للطلب بعد أن يصل وبعدها ينتهي الطلب وترجع النتيجة مثلاً تقوم باستدعاء دالة عمل الحساب createUserAccount وسوف تنتظر حتى تنتهي الدالة وتعود بالنتيجة. لكن في ال EDA انت لا تنتظر النتيجة، وفقط سوف ترسل ان الطلب تم ارساله userAccountFormSubmitted. طريقة التفكير هذه تقود الى العديد من الأشياء الجيد وسوف نتحدث عنها في مقالة منفصلة عن ال asynchronous processing.
بغض النظر عن ال architecture style الذي تستخدمه، فكل المعماريات سوف تحصل على الفائدة عندما تقسم الى أجزاء صغيرة مستقلة. والهدف منهم هو عمل abstraction أكبر بحيث يخفى التعقيدات ويقلل الاعتماديات dependencies ويسمح بال scaling لكل جزئية بشكل منفصل وايضاً يسهل لفريق العمل التطوير على الأجزاء بالتوازي.
فكر ان طبقة خدمات الويب هي مجموعه من الخدمات الذاتية highly autonomous applications وكل خدمة تكون تطبيق بحد ذاتها. وقد تعتمد خدمة الويب على خدمة اخر لكن كلما قلت الاعتمادية كلما صارت أفضل. وال abstraction الذي تقدمة هذه الخدمات يسمح لك بفهم النظام بسهولة حيث كل خدمة تخفي التفاصيل في كيفية عملها وتقدم لك API يسهل التعامل معها.
الصورة 14 توضح مجموعه من خدمات الويب لمنصة e-commerce وسوف تجد أن خدمة تحليل النصوص هي خدمة مستقلة مهمتها تحليل النصوص وفهم المواضيع على حسب المحتوى ومثل هذه الخدمة لا تحتاج أي مساعدة من خدمات أخرى.
لسوء الحظ، فأحيانا يكون من المستحيل فصل كل الخدمات بهذا الشكل، وفي غالب الوقت سوف تجد العديد من الاعتماديات بين الخدمات. مثلاً خدمة Customer Segmentation هي خدمة تعتمد على أنشطة المستخدم وبيانات الشبكات الاجتماعية أو أي معامل اخر، ولوضع المستخدمين الى أي من هذه ال segments قد تحتاج الى بيانات المستخدم وتفاصيل الأنشطة وقد تتصل بخدمات أخرى موجودة (بخلاف خدمة تحليل النصوص فهي مستقلة). وحتى لو كانت third party وبغض النظر عن ال implementation الموجود في طبقة خدمات الويب تذكر ان الهدف الأساسي هو solve business need.
تقنيات مساعدة Supporting Technologies
الصورة 1-11 أظهرت بعض الخدمات الأخرى المساعدة حول خدمات الويب مثلاً message queue وال application cache وال main data store وال search engine. وهي جميعهم مستقلة ويمكن ان تطبقها بتقنيات ولغات مختلفة وغالباً ما تستخدم مكونات third party جاهزة او برمجيات جاهزة بها ولذلك تستطيع ان تنظر لها ك black box عندما تتحدث عن المعمارية لمشروعك.
لاحظ ايضاً ان قاعدة البيانات (ال main data store) هي أيضاً صندوق صغير في الزاوية وذلك بسبب أن ال data store هي مجرد تقنية ومن وجهة نظر المعمارية هي وسيلة لكتابة وحفظ واسترجاع البيانات. بغض النظر عن كم عدد السيرفرات التي تحتاجها أو طريقة حفظ وتمثيل البيانات وما هي طريقة ال scalability بها أو ال replication أو حتى ال fault tolerance.
اعتبر ان ال data store مثلها مثل ال caches وال searching engine وال message queues عبارة عن إضافات plugin وإذا كنت تريد ان تحول طريقة التخزين او طريقة الكاش فكل ما عليك هو تغير ذلك المكون ولن تتغير المعمارية او التطبيق.
عن طريقة عمل ال abstraction لل data store فلك الحرية في استخدام أي نوع بها سواء MySQL او أي نوع آخر مثلاً NoSQL data store او حتى in-memory solution بناء على متطلبات النظام. تذكر أن ال data store ليست قلب المعمارية ولا يجب ان تحكم طريقة تطور النظام.
اخيراً لو لاحظت في الصورة 11 تم وضع بعض الخدمات الأخرى third party services وذلك لأن أغلب الأنظمة بالفعل تتعامل مع عشرات من الأنظمة الخارجية external system وربما تعتمد عليهم ايضاً. ولأنهم خارج سيطرتك فهي خارج حدود النظام وعزلها بطبقة فوقها هي طريقة جيدة لتقليل المخاطر بحيث تستطيع فيما بعد تبديل خدمة بخدمة أخرى بسهولة.
الخلاصة
المعمارية Architecture هي من وجهة نظر ال software engineer بينما البنية التحتية infrastructure من وجهة نظر ال system engineer وكلا وجهات النظر هما مجرد رؤية أخرى لنفس المشكلة الا وهي بناء Scalable software.
بعد هذه المقالة يجب أن تكون قادراً على بناء الصورة العامة في كيف يمكن أن تلعب ال Architecture وال Infrastructure دوراً في دعم ال Scalability للمشروع. وهذه النظرة العامة مهمة قبل ان ندخل في تفاصيل كل مكون بالتفصيل في مقالات تالية.
كما ترى فإن موضوع ال Scalability ليس بالسهل، لأنه يمس العديد من الجوانب في تصميم ومعمارية الأنظمة وايضاً يحتاج معرفة واسعة في العديد من التقنيات والأدوات المختلفة. ولعمل ال Scalability تحتاج فهماً لكل الأجزاء وكيف تعمل مع بعضها البعض وما هو دور كل جزء منها وأين هي مكامن قوة وضعف كل مهم.
لكي تصميم Scalable Web Application على بمعرفة تأثير المعمارية Architecture والبنية التحتية infrastructure والتقنيات والخوارزميات وحاجة ال business وماذا يريد.
المقالات التالية في هذه السلسلة سوف تبدأ بإلقاء النظر على المكونات والخدمات التي تم تناولها بالتفصيل.
رائع جدا , مجهود مقدر
مقال رائع و بانتظار باقي الأدزاء .. لكم كل الشكر
ملاحظة: أتمنى لو هناك إمكانية للحصول على news letter عن كل جديد بالموقغ
شكرا مقال واف
مقال جد متخصص….. و يعتبر اضافة للمهندس العربي .
أنا متخصص و أفدتني كثيرا كثيرا كثيرا .
أتمنى منك المواصلة.
مقال جد متخصص….. و يعتبر اضافة للمهندس العربي .
أنا متخصص و أفدتني كثيرا كثيرا كثيرا .
أتمنى منك المواصلة.
مقال ممتاز جداا واتمنى ان تكمل باقي التفاصيل وشكرا لك ولمجهودك الرائع
شكرا جزيلا على هذا المجهود الكبير مقال غني بالمعلومات ومفييد جدا