اذهب إلى المحتوى

لوحة المتصدرين

  1. لتا عيس

    لتا عيس

    الأعضاء


    • نقاط

      2

    • المساهمات

      67


  2. محمود سعداوي2

    محمود سعداوي2

    الأعضاء


    • نقاط

      2

    • المساهمات

      604


  3. عمر قره محمد

    عمر قره محمد

    الأعضاء


    • نقاط

      2

    • المساهمات

      4096


  4. محمد الخضور

    محمد الخضور

    الأعضاء


    • نقاط

      2

    • المساهمات

      21


المحتوى الأكثر حصولًا على سمعة جيدة

المحتوى الأعلى تقييمًا في 11/22/22 في كل الموقع

  1. انا تركت تعلم البرمجة لي فترة اشتركت بدورة علوم الحاسوب وعديت التعلم مع البرنامج سكراتش ووصلت للمكونات الحاسوب واضني عديته وابغى ارجع اتعلم وش تنصحوني اعيده من البداية؟
    2 نقاط
  2. السلام عليكم. عندي api لإستلام أجوبة إختبار، وأقوم بإستلام الأجوبة على دفعة واحدة ك array of objects. كل object يحتوي على question_id, answer, file الخانة file عبارة عن ملف على هيئة صورة، وكل object به ملف.. يتم الإتصال بالapi وإرسال الأجوبة من الjavascript. أريد التحقق من وجود ملف في كل object ونقل الملف إلى السيرفر بإستخدام laravel. لأنه لا يجوز هنا استخدام ()request->hasFile$
    1 نقطة
  3. الحمد لله ، الموقع اشتغل بعد مراسلة مزود الخدمة ...........شكرا جزيلا ..
    1 نقطة
  4. راسل مزود الخدمة لديك
    1 نقطة
  5. كتبت اكواد Css وربطتها بملف Html ولكنها لا تظهر علي ملف Html ما الحل؟
    1 نقطة
  6. سلام عليكم! سؤالي اين يوجد اكبر مكان يحتوي على اسئلة مثل( if - for - وهكذاا )يمكن حلها بلغات مختلفة مثل dart وذلك لاتقان ؟؟؟
    1 نقطة
  7. السلام عليكم. عند النقر على selectedNote يقع إرجاع العنصر الأخير من المصفوفة. شيفرة NoteContainerAdded import React from 'react' import './NoteContainer.css' function NoteContainerAdded({title,content,deleteNoteHandler,selectedNote}) { return ( <div className='note-container'> <h2 className='title-added'>{title}</h2> <p className='content-added'>{content}</p> <div className='btns'> <button className='delete' onClick={()=>deleteNoteHandler(selectedNote)}>Delete</button> <button className='edit'>Edit</button> </div> </div> ) } شيفرة NoteContainer import React,{} from 'react' import './NoteContainer.css' import NoteContainerStart from './NoteContainerStart' import NoteContainerAdded from './NoteContainerAdded' function NoteContainer({title,content,showNote,deleteNoteHandler,selectedNote}) { return ( <> { !showNote ? <NoteContainerStart> <h2>Welcome To My ToDo</h2> <p>Please click on the button below to enter your first todo</p> </NoteContainerStart> : <NoteContainerAdded title={title} content={content} deleteNoteHandler={deleteNoteHandler} selectedNote = {selectedNote} /> } </> ) } export default NoteContainer; شيفرة App import React, {useState} from 'react' import Notes from './Notes/Notes'; import './App.css'; import AddNoteForm from './AddNoteForm/AddNoteForm'; import NoteContainer from './NoteContainer/NoteContainer'; function App() { const [notes,setNotes] = useState([]) const [title,setTitle] = useState('') const [content,setContent] = useState('') const [selectedNote,setSelectedNote] = useState(null) const [error,setError] = useState(false) const [creating,setCreating] = useState(false) const [showNote,setShowNote] = useState(false) const handleChange_title = (e) => { setTitle(e.target.value) } const handleChange_content = (e) => { setContent(e.target.value) } const saveNoteHandler = (e) =>{ e.preventDefault() if (title.length === 0 || content.length === 0) { setError(true) } else{ setError(false) const note = { id : new Date(), title : title, content : content } const updatedNotes = [...notes,note] setNotes(updatedNotes) setSelectedNote(note.id) } setTitle('') setContent('') } const handleAddNote = () => { setCreating(true) setTitle('') setContent('') } const noteClicked = (id) => { setCreating(false) let selectedNote = notes.find((note)=> note.id === id) setContent(selectedNote.content) setTitle(selectedNote.title) setShowNote(true) } const deleteNoteHandler = (selectedNote) =>{ const updatedNotes = [...notes] const findIndex = updatedNotes.findIndex(note => note.id === selectedNote ) console.log('===================================='); console.log(updatedNotes,"index: ",findIndex) } return ( <div className='app'> <Notes className='notes' notes={notes} handleAddNote={handleAddNote} noteClicked={noteClicked} /> { !creating ? <NoteContainer className='' title = {title} content = {content} showNote = {showNote} deleteNoteHandler = {deleteNoteHandler} selectedNote = {selectedNote} /> : <AddNoteForm className='add-note-form' saveNoteHandler={saveNoteHandler} handleChangeContent={handleChange_content} handleChangeTitle={handleChange_title} error={error} title={title} content={content} /> } </div> ); } export default App; أعتذر. في السطر الأول أقصد delete مكان selectedNote شكرا
    1 نقطة
  8. هنالك مشكلتان، الأولى في ملف الـ app وتحديداً في الوظيفة noteClicked : // الكود الخاص بك const noteClicked = (id) => { setCreating(false) let selectedNote = notes.find((note)=> note.id === id) setContent(selectedNote.content) setTitle(selectedNote.title) setShowNote(true) } // الكود الصحيح const noteClicked = (id) => { setCreating(false) // أو اي اسم آخر theClickedNote قم بتغير اسم المتغير إلى let theClickedNote = notes.find((note) => note.id === id) // selectedNote المسمات state قم بإضافته لل setSelectedNote(theClickedNote.id) setContent(selectedNote.content) setTitle(selectedNote.title) setShowNote(true) } حيث انك لم تكن تقوم بتعديل الـ state المسماة selectedNote في الوظيفة المسماة noteClicked. والمشكلة الثانية في ملف الـ Notes.js وتحديداً في السطر 13 حيث انك كتبت selectedNote بدلاً من note.id كباراميتر للوظيفة noteClicked الخاصة بتغيير الـ selectedNote وهذا ما سبب ان الـ selectedNote لا تتغير. // الكود الخاص بك noteClicked={() => noteClicked(selectedNote)} // الكود الصحيح هو noteClicked={() => noteClicked(note.id)}
    1 نقطة
  9. هل يمكنك مشاركة مجلد الـ src بالكامل حتى يسهل علي الاطلاع على المشروع الخاص بك.
    1 نقطة
  10. سيكون فيه تقريبا حوالي 5 جدوال جدول Customer جدول Order علاقة 1 لكثير مع Customer OrderItem علاقة 1 لكثير مع Order و Product جدول Product جدول Category علاقة واحد لكثير مع Product يمكنك تصفح بعض هذه المقالات للمزيد من الأفكار والمعلومات https://io.hsoub.com/programming/89766-ما-هو-نظام-mvc
    1 نقطة
  11. هذه المواقع تسميى بمواقع ال problem solving أو مايسمى بمواقع حل المشكلات هناك الكثير والكثير من المواقع , يمكنك فقط البحث عن Problem solving dart أو أي لغة أو أي مكتبة أو إطار عمل وكما قلت لك مواقع حلول المشاكل لاتنتهي تستطيع البحث عن أي لغة .
    1 نقطة
  12. يشير الناس عادةً لأي مجموعةٍ من مفاهيم الحوسبة المترابطة بمصطلح السحابة cloud، ولكن في الواقع السحابة هي مجموعةٌ من الأقراص والمعالجات والذواكر وغيرها من موارد عمليات المعالجة computing resources -سواءٌ كانت فيزيائية أو افتراضية- المستضافة عن بُعد remotely hosted والمُستخدمة في طرف العميل، سواء أكان هذا العميل صفحة ويب أو تطبيق للهاتف أو تطبيق سطح مكتب تقليدي، بهدف استثمار المساحات التخزينية وإمكانات الحوسبة العالية؛ ويُقصد بمصطلح الاستضافة عن بُعد remotely hosting طريقة توصيل التطبيقات وقواعد البيانات والملفات للمستخدمين من الخوادم البعيدة الموجودة خارج مراكز البيانات، إذ يمكن للمستخدم الوصول إلى التطبيق وبياناته من خلال تسجيل الدخول بأمان إلى الخادم البعيد عبر السحابة وذلك خلال متصفح الإنترنت عادةً)، وليس من السهل التفريق تمامًا بين مفهوم الحوسبة السحابية والحوسبة التقليدية القائمة على نموذج خادم/عميل؛ ولكن تتميز الحوسبة السحابية عمومًا بالقدرة على التوسُّع، أي زيادة الموارد تلقائيًا حسب الحاجة أثناء التشغيل؛ كما تتميز بآلية التصميم أيضًا، إذ تكون مصادر الحوسبة في السحابة أكثر مرونةً ومتعددة الأغراض وقابلةً للاستخدام لأي وظيفة مطلوبة على نحوٍ أكبر موارنةً بحوسبة الخوادم التقليدية. بعض الأمثلة على مفهوم السحابة لا يخلو موقع إلكتروني في أيامنا من مكون سحابي سواءٌ كان ظاهرًا لنا عند زيارته أم لا؛ أمّا بالنسبة للمستخدم العادي، فلا تمثّل السحابة سوى واجهة عرض الخدمة التي يتعامل معها، سواءٌ كانت منصة تواصل اجتماعي، أو متجرًا إلكترونيًا، أو إحدى خدمات بث الموسيقى، أو موقع حجز تذاكر طيران، أو غيرها من الخدمات المختلفة. يجب ألا ننسى أن واجهة المستخدم في موقع الويب ما هي إلا جزءٌ بسيطٌ من مجموعةٍ كبيرةٍ من العمليات الجارية في كواليس أيّ تطبيق ويب، إذ تعمل مكوناتٌ عديدة من قواعد بيانات وأدوات تسجيل الأحداث وصولًا إلى آليات التنقيب عن البيانات وأدوات الذكاء الاصطناعي وعدد من البرمجيات الموزعة الخاصة بتنفيذ المتطلبات أو الآلاف منها معًا لتشغّل خدمة ويب وتمكنَّك من استخدام أي أداة على الانترنت. وقد تتواجد المكونات المذكورة أعلاه على أي حاسوب في أي مكان، ولكن تتواجد غالبًا على السحابة. كيفية عمل السحابة صُممت مراكز البيانات لكي تحوي العديد من خوادم الأغراض العامة مع ما يلزم من إمكانات الحوسبة والتخزين، لمشاركة هذه الموارد بين التطبيقات المتعددة المُستضافة في هذه المراكز لتوفير البيانات الخاصة بها. وتُجمَّع في كثير من الحالات كافّة التطبيقات والمكتبات اللازمة لتشغيلها مع نظام التشغيل على أجهزة افتراضية virtual machines تعمل ضمن الجهاز الفيزيائي الفعلي بغض النظر عن نوع نظام تشغيله، وتدعى هذه التقنية باسم التقنية الافتراضية virtualization؛ وهي تجعل التطبيقات أكثر قابليةً للتنقل والعمل في بيئات مختلفة، شرط أن تكون قادرةً على تشغيل جهاز افتراضي ضمنها. من هنا أتى مفهوم الحوسبة المرنة elastic computing أو السحابة المرنة elastic cloud؛ فعندما يُصمّم تطبيق ليتوسع أو يتقلص حسب حجم الطلبات عليه فمن الممكن استخدام عدد أكبر أو أقل من الأجهزة الافتراضية بمرونة حسب الحالة؛ كما تعمل الأجهزة الافتراضية بمرونة أيضًا من ناحية التخزين، فمن الممكن استخدام محركات الأقراص الثابتة المتصلة بالعديد من الأجهزة الفيزيائية المختلفة والتعامل معها كما لو كانت موردًا واحدًا، مما يقلل من هدر الموارد ويسهّل عملية تطوير التطبيقات التي تتطلب كميات بيانات كبيرة جدًا. قد تكون مراكز البيانات التي تستضيف موارد الحوسبة السحابية عامّةً أو خاصّةً أو هجينة hybrid cloud؛ فمن الممكن استئجار موارد الحوسبة السحابية العامة من قبل مجموعة متنوعة من الشركات؛ وقد تقرر المؤسسة إنشاء سحابة خاصة مستضافة في مركز البيانات الخاص بها أو في جزء محجوز خصيصًا لها من مركز بيانات آخر من أجل الحصول على مستويات أعلى من الأمان والمرونة، أو حتى بهدف توفير التكاليف؛ أمّا السحب الهجينة فتتميز بقدرتها على الاستفادة من موارد السحب العامة والخاصة وذلك وفقًا لمتغيرات الطلب والأولوية. مفهوم السحابة مفتوحة المصدر إنّ أحد أهم التطورات التي حدثت مؤخرًا على أدوات وتقنيات التعامل مع السحابة هو الكم الكبير منها الذي غدا مفتوح المصدر، وقد أصبح ترخيص البرمجيات مفتوحة المصدر معيارًا لكيفية تطوير التقنيات الحديثة للتعامل مع السحابة، وفيما يلي بعض الأمثلة: OpenStack وهو مشروع مفتوح المصدر متخصص بإنشاء وإدارة البنية الأساسية للسحابة، بما يتضمن وسائط التخزين، وإمكانات الموارد الحاسوبية وإدارة الشبكات، كما يتضمّن العديد من المشاريع للمساعدة في التعامل مع كل ما يتعلّق بالسحابة بدءًا من إدارة حسابات المستخدمين وحتى استثمار قاعدة البيانات (المرحلة اللاحقة لتطويرها). حاويات Linux والتي ظهرت أصلًا بمثابة طريقة لتطوير تطبيقات السحابة، وتعتمد على الإجرائيات الخاصّة بالنواة Linux kernel مثل بديلٍ أسرع من الأجهزة الافتراضية التقليدية، كما أنّها تساعد المطورين على بناء الحاويات باستخدام مشاريع، مثل Docker و Kubernetes لتحقيق التناغم بين التطبيقات التي أُنشأت على عدّة حاويات. البيانات الضخمة و إنترنت الأشياء Internet of Things، وهما من أهم مستخدمي موارد الحوسبة السحابية، حيث تُطوَّر في كل منهما العديد من الأدوات لدعم التطبيقات لتكوت مفتوحة المصدر تمامًا. إضافةً للعديد من الأدوات الأخرى ابتداءً من حزم خوادم الويب Linux / Apache / MySQL / PHP وصولًا إلى تطبيقات التخزين السحابي ومحررات النصوص التشاركية. ترجمة -وبتصرف- للمقال what is the cloud?‎ من موقع opensource.com. اقرأ أيضًا الانتقال إلى الحوسبة السحابيّة تعلم الحوسبة السحابيّة: المتطلبات الأساسيّة، وكيف تصبح مهندس حوسبة سحابيّة
    1 نقطة
  13. أصبحت البيانات الضخمة Big Data حديث الناس في الآونة الأخيرة، ولكن ما هي البيانات الضخمة حقيقةً؟ كيف بإمكانها تغيير طريقة فهم الباحثين للعالم سواءً كانوا يعملون في الشركات، أو الهيئات غير الربحية، أو الجهات الحكومية، أو المؤسسات وغيرها من المنظمات؟ ما هي مصادر البيانات، كيف تُعالج، وكيف تُستخدم مخرجات عملية المعالجة؟ ولماذا يُعَد مفهوم المصادر المفتوحة أساسيًا في الإجابة عن التساؤلات السابقة؟ سنتعرّف في هذا المقال على كل ما يتعلّق بمفهوم البيانات الضخمة وأهميته في عالمنا المتغير. ما هي البيانات الضخمة؟ عندما نتحدث عن البيانات الضخمة فلن يحدد حجم قاعدة البيانات كونها ضخمةً أم لا، فلا يوجد قيدٌ صارمٌ ودقيق لحجم البيانات ضمن قاعدة البيانات كي نعدّها "ضخمة"، ولكن ما يحدد ذلك هو مقدار حاجتنا لاستخدام تقنياتٍ وأدواتٍ جديدة لمعالجة هذه البيانات. إذًا، للتعامل مع البيانات الضخمة، لابدّ من استخدام برامج تربط عدّة أجهزة فعلية أو افتراضية لتعمل معًا بتناغم في معالجة جميع البيانات خلال مدةٍ زمنيةٍ مقبولة. يتطلب تشغيل البرمجيات لكي تتخاطب فيما بينها بفعالية عندما تكون موزعةً على عدّة أجهزة تقنياتٍ برمجية خاصّة، بحيث تُوزَّع مهام معالجة البيانات بكفاءة، لتكون كل برمجية مسؤولةً عن قسمٍ محددٍ من البيانات لمعالجتها، وبذلك نستطيع تجميع مخرجات المعالجة من كل الأجهزة معًا بطريقةٍ نحقق من خلالها مفهوم البيانات الكبيرة. عند التفكير في تحديات التعامل مع البيانات الضخمة، لا بدّ من الأخذ في الحسبان أهمية توزيع البيانات في عناقيد clusters وكيفية ربط هذه العناقيد شبكيًا مع بعضها، وذلك نظرًا للمقارنة مع حقيقة أنّ وصول البرامج إلى البيانات المخزنة على جهاز محليًا أسرع بكثير من الوصول إليها شبكيًا. ما هي أنواع مجموعات البيانات التي تعد بيانات ضخمة؟ تتنوع استخدامات البيانات الضخمة بقدر كبر حجمها تقريبًا، وأحد أبرز الأمثلة المألوفة لمعظمنا هو كيفية تحليل شبكات التواصل الاجتماعي لبيانات مستخدميها بهدف الحصول على مزيدٍ من المعلومات عنهم، وبالتالي عرض محتوى وإعلانات ذات صلة باهتماماتهم، أو طريقة تحديد محركات البحث للعلاقة ما بين الاستعلامات والنتائج المعروضة، بحيث تقدّم إجابات أفضل على تساؤلات مستخدميها. استخدامات البيانات الضخمة أعم من ذلك بكثير، وأحد أكبر مصادر البيانات بكميات هائلة هي البيانات المالية، متضمِّنًا أسعار الأسهم والبيانات المصرفية وسجلات دفعات التجار، والمصدر الثاني هو بيانات أجهزة الاستشعار، إذ تأتي معظم هذه البيانات من ما يعرف باسم إنترنت الأشياء Internet of Things -أو اختصارًا IoT-، والتي قد تمثّل بيانات القياسات المأخوذة من قبل الروبوتات العاملة على خط إنتاج آلي في أحد مصانع السيارات، أو بيانات تحديد المواقع في شبكة اتصالات خلوي ما، أو بيانات كميات استهلاك الكهرباء اللحظية في المنازل والشركات، وصولًا إلى معلومات حركة الركاب الواردة من شركات النقل. تتمكن المؤسسات بتحليل هذه البيانات من معرفة صعود أو هبوط البيانات المسجَّلة ومعلومات الأشخاص الذين يمثّلون مصدر هذه البيانات. والآمال معقودة بأن يوفّر تحليل البيانات الضخمة خدمات أكثر تخصّصًا، وكفاءة إنتاجية أعلى في أي مجال صناعي تُجمع منه البيانات. كيفية تحليل البيانات الضخمة تُعد طريقة MapReduce إحدى أهم طرق تحويل البيانات الخام إلى معلوماتٍ مفيدة، وهي منهجية لإجراء العمليات الحسابية على البيانات من خلال عدة حواسيب وعلى التوازي؛ فهي تمثّل نموذجًا لكيفية برمجة العملية، ويُستخدم المصطلح MapReduce غالًا للإشارة إلى التطبيق الفعلي لهذا النموذج. تتألف منهجية MapReduce بصورةٍ رئيسية من جزأين، إذ يتمثَّل الأول في دالة التعيين Map function، والتي تفرز وترشِّح البيانات عبر توزيعها ضمن فئات مما يسهّل عملية تحليلها؛ أمّا الجزء الثاني فهو دالة التقليص Reduce function، التي تختصر البيانات عبر تجميعها معًا. وقد أصبح MapReduce مصطلحًا شاملًا يشير إلى نموذجٍ عام تستخدمه العديد من التقنيات، ويعود الفضل في ذلك إلى حدٍ كبير للبحث الذي أجرته جوجل Google حول هذا النموذج. ما هي الأدوات المستخدمة لتحليل البيانات الضخمة؟ تُعدّ Apache Hadoop الأداة الأكثر تأثيرًا وثباتًا في تحليل البيانات الضخمة؛ فهي إطار عملٍ واسع النطاق مفتوح المصدر يصنِّف ويعالج البيانات؛ كما يمكن لهذه الأداة أن تعمل على عتاد عادي استهلاكي commodity hardware (أو ما يُعرف باسم off-the-shelf hardware، وهي حواسيب أو أيٌ من تجهيزات تقانة المعلومات غير المكلفة وشعبية التوفّر، وتكون عادةً جدوى استبدالها بالكامل في حال حدوث أعطال أكبر من جدوى إصلاحها)، مما يجعلها فعّالة في الاستخدام مع مراكز البيانات الحالية، أو حتى لإجراء تحليل بيانات سحابي. وتُقسم Hadoop إجمالًا إلى أربعة أجزاء رئيسية: HDFS وهو مخزن بيانات يعتمد على نظام الملفات الموزعة، ومصمّمٌ للعمل مع حيز نطاق تراسلي عالٍ جدًا. منصة YARN المسؤولة عن إدارة موارد الأداة Hadoop وجدولة البرامج التي ستعمل على التجهيزات التي تستخدم هذه الأداة. نموذج إنجاز معالجة البيانات الضخمة وهو MapReduce المشروح أعلاه. مجموعة من المكتبات الشائعة الحاوية على نماذج معالجة بيانات أخرى قابلة للاستخدام. كما يوجد أدوات أخرى للتعامل مع البيانات الضخمة، إذ تُعد Apache Spark إحدى هذه الأدوات التي تحظى باهتمام بالغ؛ فهي متميزة بقدرتها على تخزين كمية كبيرة من البيانات في الذاكرة لمعالجتها. وبذلك، وعلى عكس آلية التخزين على الأقراص، تُعد Apache Spark أسرع بكثير لا سيما لبعض أنواع تحليل البيانات، ففي بعض التطبيقات سيحصل المحللون باستخدام هذه الأداة على نتائج أسرع بمئات المرات أو أكثر. ويمكن للأداة Spark استخدام نظام الملفات الموزعة HDFS أو غيره من مخازن البيانات، مثل Apache Cassandra، أو OpenStack Swift؛ كما من الممكن تشغيل Spark على جهاز محلي، مما يسهّل عمليات الاختبار والتطوير. بعض الأدوات الأخرى للتعامل مع البيانات الضخمة يوجد إجمالًا عددٌ غير محدود من الحلول مفتوحة المصدر للتعامل مع البيانات الضخمة، وقد خُصِّصت عدّة حلول منها لتوفير ميزات وأداء أمثل لمجال معين أو حتى لتجهيزات معينة ذات إعدادات خاصّة، وما سنعرضه فيما يلي لا يمثّل سوى جزءٍ من الأدوات التي تتعامل مع البيانات الضخمة. تدعم مؤسسة أباتشي Apache للبرمجيات Apache Software Foundation -أو اختصارًا ASF- عدّة مشاريع للبيانات الضخمة، ونذكر من هذه المشاريع المفيدة ما يلي: Apache Beam وهو نموذجٌ موّحدٌ لتعريف مجاري pipelines كلٍ من الدفعات batches وتدفقات البيانات المتوازية parallel، كما يسمح هذا النموذج للمطورين بكتابة الترميزات البرمجية التي تعمل على عدّة محركات معالجة. Apache Hive وهو مخزن بيانات مبني على Hadoop، ويُعد أحد مشاريع Apache عالية المستوى، إذ يسهّل قراءة وكتابة وإدارة مجموعات البيانات الكبيرة باستخدام SQL. Apache Impala وهو محرّك استعلامات في SQL يعمل مع الأداة Hadoop، وقد ضمِّن إلى حزمة Apache واشتُهر بقدرته على تحسين أداء استعلامات SQL باستخدام واجهة بسيطة مألوفة. Apache Kafka توفّر آلية تسمح للمستخدمين بالاتصال المستمر مع مصادر البيانات للحصول على البيانات باستقبال البيانات وتحديثاتها لحظيًا، وتهدف إلى تحقيق موثوقية عالية لدى استخدام أنظمة التخاطب المختلفة في نقل البيانات. Apache Lucene وهي مكتبة برمجية مختصّة بعمليات البحث وفهرسة البيانات؛ وتوفّر استعلامًا نصيًا لغويًا متقدّمًا لقواعد البيانات أو المستندات النصية full-text indexing؛ كما تستخدم أداة تصفية بيانات بالاعتماد على خوارزميات التعلم الآلي للتوصية بالعناصر الأكثر صلة لمستخدم معين recommendation engines، وتشكّل هذه المكتبة أساسًا للعديد من مشاريع البحث الأخرى مثل محركات البحث Solr وElasticsearch. Apache Pig وهي منصة لتحليل مجموعات البيانات الضخمة التي تعمل على الأداة Hadoop، وقد طورتها شركة ياهو Yahoo لإنجاز مهام MapReduce على مجموعات البيانات الضخمة، وكانت قد ساهمت ياهو في عام 2007 بها ضمن مشروع ASF. Apache Solr وهي منصة بحث متخصّصة للشركات، بُنيت اعتمادًا على مكتبة Lucene. Apache Zeppelin وهو مشروع احتضان (والاحتضان هو مرحلة وليس مكان، إذ تُحتضن المشاريع الجديدة لمدة عام أو عامين بهدف التطوير قبل الطرح). يتيح Apache Zeppelin إمكانية تحليل البيانات التفاعلية باستخدام لغة الاستعلامات SQL ولغات البرمجة الأخرى. تتضمّن الأدوات المفتوحة المصدر للتعامل مع البيانات الضخمة والتي قد ترغب بالتعرف عليها ما يلي: Elasticsearch وهو محرّك بحث آخر للمؤسسات يعتمد على مكتبة Lucene، ويمثّل جزءًا من محرك البحث المُسمى المكدس المرن Elastic stack والمعروف باسم مكدّس ELK كونه مؤلفًا من ثلاث مكونات، هي: Elasticsearch و Kibana و Logstash (محرك بحث للاستعلام النصي المتقدّم للمستندات النصية، ذو واجهة ويب HTTP يعتمد أيضًا على مكتبة Lucene). يستطيع المحرك Elasticsearch توليد نتائجٍ من البيانات سواءً كانت هذه البيانات مهيكلة أم لا. Cruise Control والتي طوِّرتها شركة لينكد إن LinkedIn لتشغيل مجموعات Apache Kafka على نطاقٍ أوسع. TensorFlow وهي مكتبة برمجية للتعلّم الآلي، تطورت هذه المكتبة سريعًا عندما جعلتها شركة غوغل Google مفتوحة المصدر في أواخر عام 2015، ولطالما أُشيد بها لسهولة استخدامها وتوفُّرها للجميع. وهكذا تستمر البيانات الضخمة بالنمو حجمًا وأهميةً، وبالتالي ستستمر الأدوات المفتوحة المصدر التي تتعامل معها بالنمو بكل تأكيد. ترجمة -وبتصرف- للمقال An introduction to big data من موقع opensource.com. اقرأ أيضًا المفاهيم الأساسية لتعلم الآلة نظرة سريعة على لغة الاستعلامات الهيكلية SQL
    1 نقطة
  14. ناقشنا بالمقال السابق عدة أمثلة على البرمجة الشبكية، حيث تعلّمنا طريقة إنشاء اتصالٍ شبكيٍ وطريقة تبادل المعلومات عبر تلك الاتصالات، ولكننا لم نتعامل مع واحدةٍ من أهم خاصيات البرمجة عبر الشبكة، وهي حقيقة كون الاتصال الشبكي غير متزامن asynchronous. بالنسبة لبرنامج معين بأحد طرفي اتصال شبكي معين، قد تصِل الرسائل من الطرف الآخر بأي لحظة؛ أي يكون وصول رسالةٍ معينة حدثًا خارج نطاق تحكُّم البرنامج المُستقبِل للرسالة، ولذلك ربما تكون الاستعانة بواجهة برمجة تطبيقات API مبنيةٍ على الأحداث وخاصةٍ بالشبكات فكرةً جيدةً تُمكِّننا من التعامل مع الطبيعة غير المتزامنة للاتصالات عبر الشبكة؛ ولكن لا تعتمد جافا في الواقع على تلك الطريقة، حيث تَستخدِم برمجة الشبكات بلغة جافا الخيوط threads عمومًا. مشكلة الدخل والخرج المعطل Blocking I/O كما ناقشنا في مقال تواصل تطبيقات جافا عبر الشبكة، تَستخدِم برمجة الشبكات المقابس sockets، والتي تشير إلى أحد طرفي اتصال شبكي. يَملُك كل مقبس مجرى دْخَل input stream ومجرى خرج output stream، وتُنقَل البيانات المُرسَلة إلى مجرى الخرج بأحد طرفي الإتصال عبر الشبكة إلى مجرى الدْخَل بالطرف الآخر. إذا أراد برنامجٌ معينٌ قراءة البيانات من مجرى الدْخَل الخاص بالمقبس، فعليه استدعاء أحد توابع قراءة البيانات من مجرى الدْخَل. قد تكون البيانات قد وصلت بالفعل قبل استدعاء التابع، وفي تلك الحالة يَسترجِع التابع البيانات ويعيدها على الفور. ومع ذلك، قد يضطّر التابع لانتظار وصول البيانات من الطرف الآخر من الاتصال؛ أي يُعطَّل block كُلًا من التابع والخيط الذي استدعاه إلى أن تَصِل البيانات. قد يتعطَّل أيضًا تابع إرسال البيانات إلى مجرى الخرج الخاص بالمقبس؛ حيث يحدث ذلك إذا حاول البرنامج إرسال البيانات إلى المقبس بسرعةٍ أكبر من سرعة نقل البيانات عبر الشبكة. يَستخدِم المقبس مخزنًا مؤقتًا buffer لحمل البيانات المُفترَض نقلها عبر الشبكة. تذكَّر أن المخزن المؤقت هو مساحةٌ من الذاكرة تَعمَل بطريقةٍ مشابهةٍ للرتل queue. يضع تابع الخرج البيانات بالمخزن المؤقت، ثم يقرأها برنامج منخفض المستوى، ويُرسِلها عبر الشبكة. إذا كان المخزن ممتلئًا، يتعطَّل تابع الخرج إلى أن تتوفَّر مساحةٌ بالمخزن. يَستخدِم الاتصال الشبكي دخلًا وخرجًا مُعطِّلًا؛ لأن عمليات الدْخَل والخَرْج عبر الشبكة قد تتسبَّب بحدوث تعطّيلٍ لفتراتٍ غير محددة، ولذلك لا بُدّ أن تكون البرامج المُستخدِمة للشبكات مهيأةً للتعامل مع ذلك التعطيل. في بعض الحالات، قد يكون إغلاق البرنامج لجميع العمليات الأخرى وانتظار البيانات المطلوبة مقبولًا، مثلما يحدث عندما يُحاوِل برنامج سطر أوامر قراءة البيانات التي ينبغي أن يُدْخِلها المُستخدِم. في الواقع، تُعدّ مدخلات المُستخدِم نوعًا من الدْخل والخَرْج المُعطِّل. ومع ذلك، تَسمَح الخيوط لبعض أجزاء البرنامج بالاستمرار بالعمل بينما بعض الأجزاء الأخرى مُعطَّلة. على سبيل المثال، ربما يكون من المناسب اِستخدَام خيطٍ واحدٍ مع برنامج عميل client شبكي يُرسِل طلباتٍ إلى خادم server، إذا لم يكن هناك أي شيءٍ ينبغي للبرنامج فعله بينما ينتظر رد الخادم. في المقابل، قد يتصل برنامج خادم شبكي مع عدة عملاء بنفس الوقت، وبالتالي بينما ينتظر الخادم وصول البيانات من العميل، سيكون لديه الكثير ليفعله خلال تلك الفترة، مثل الاتصال مع عملاءٍ آخرين. عندما يَستخدِم الخادم خيوطًا مختلفةً لمعالجة الاتصالات مع العملاء المختلفة، لن يؤدي التعطُّل الناتج عن عميلٍ معين إلى إيقاف تعامل الخادم مع العملاء الآخرين. يختلف استخدام الخيوط للتعامل مع مشكلة الدْخَل والخَرْج المعُطِّل جذريًا عن استخدامها لتسريع عملية المعالجة. عندما نَستخدِم الخيوط لزيادة سرعة المعالجة -كما ناقشنا بالقسم مجمع الخيوط وأرتال المهام من مقال الخيوط threads والمعالجة على التوازي في جافا السابق- كان من المنطقي استخدام خيطٍ واحدٍ لكل معالج. إذا كان الحاسوب يحتوي على معالج واحد، فلن يزيد اِستخدَام أكثر من خيط ن سرعة المعالجة إطلاقًا، بل قد يُبطئها نتيجةً للحمل الزائد overhead الناتج عن إنشاء الخيوط وإداراتها. من الجهة الأخرى، إذا كان الهدف هو حل مشكلة الدْخَل والخَرْج المُعطِّل، فسييكون من المنطقي اِستخدَام خيوطٍ بعددٍ أكبر مما يحتويه الحاسوب من معالجات؛ لأن كثيرًا من تلك الخيوط قد يتعطَّل بأي لحظة، وستتنافس بالتالي الخيوط غير المُعطَّلة فقط على زمن المعالجة. إذا أردنا تشغيل جميع المعالجات على الدوام، فلا بُدّ من وجود خيطٍ واحدٍ نشطٍ لكل معالج (في الواقع، أقل من ذلك بعض الشيء لنَسمَح بالاختلافات بين عدد الخيوط النشطة من فترةٍ لأخرى). تقضِي الخيوط ببرامج الخوادم مثلًا معظم الوقت مُعطَّلة بانتظار اكتمال عمليات الدخل والخرج؛ فإذا كانت الخيوط مُعطَّلةً بنسبة 90% من الوقت مثلًا، فسنحتاج إلى خيوطٍ بعددٍ يُقارِب عشرة أضعاف عدد المعالجات؛ أي تستطيع الخوادم الاستفادة من اِستخدَام عددٍ كبيرٍ من الخيوط حتى لو كان الحاسوب يحتوي على معالجٍ واحد. برنامج محادثة عبر الشبكة غير متزامن سنفحص الآن المثال الأول على استخدام الخيوط ببرامج الاتصال الشبكي، وسيكون برنامج محادثة بواجهة مُستخدِم رسومية GUI. اِستخدَمنا بروتوكولًا للاتصال في برامج المحادثة عبر سطر الأوامر CLChatClient.java و CLChatServer.java في مقال تواصل تطبيقات جافا عبر الشبكة المشار إليه بالأعلى؛ حيث بعدما يُدْخِل المُستخدِم بأحد طرفي الاتصال رسالةً، لا بُدّ له أن ينتظر ردًا من الطرف الآخر. سيكون من الأفضل لو أنشأنا برنامج محادثة غير متزامن asynchronous، حيث سيتمكَّن المُستخدِم من الاستمرار بكتابة الرسائل وإرسالها دون انتظار أي ردودٍ من الطرف الآخر، كما ستُعرَض الرسائل الآتية من الطرف الآخر بمجرد وصولها. في الواقع، من الصعب تنفيذ ذلك ببرنامج سطر أوامر، ولكنه بديهي ببرنامجٍ ذي واجهة مُستخدِم رسومية. تتمثل فكرة البرنامج باختصار في إنشاء خيطٍ وظيفته قراءة الرسائل القادمة من الطرف الآخر من الاتصال، وتُعرَض للمُستخدِم بمجرد وصولها، ثم يُعطَّل خيط قراءة الرسائل إلى أن تَصِل رسائلٌ أخرى. تستطيع الخيوط الأخرى الاستمرار بالعمل بينما ذلك الخيط مُعطَّل؛ حيث سيتمكَّن خيط معالجة الأحداث events بالتحديد من الاستجابة لما يفعله المُستخدِم، وسيتمكَّن بالتالي من إرسال الرسائل بعد أن يكتبها المُستخدِم مباشرةً. يَعمَل برنامج "GUIChat" مثل عميلٍ أو خادم.و يحتوي البرنامج على زر "Listen"، وعندما ينقر عليه المُستخدِم، يُنشِئ البرنامج مقبس خادم يَستمِع إلى طلبات الاتصال القادمة، وبالتالي يَعمَل البرنامج خادمًا. يحتوي البرنامج أيضًا على زر "Connect"، وعندما يَنقُر عليه المُستخدِم، يُرسِل البرنامج طلب اتصال، وبالتالي يَعمَل البرنامج عميلًا. يَستمِع الخادم كما جرت العادة إلى رقم منفذٍ port number معين، ولا بُدّ أن يعرف العميل الحاسوب الذي يَعمَل عليه الخادم ورقم المنفذ الذي يَستمِع إليه. تحتوي نافذة البرنامج "GUIChat" على صناديق إدخال تَسمَح للمُستخدِم بإدخال تلك المعلومات. بمجرد بدء الاتصال بين برنامجي "GUIChat"، يستطيع المُستخدِم الموجود بأي طرفٍ من طرفي الاتصال إرسال الرسائل إلى المُستخدِم بالطرف الآخر. تحتوي النافذة على صندوق إدخالٍ يَسمَح للمُستخدِم بكتابة الرسائل، ثم النقر على زر العودة الى بداية السطر لإرسالها. يستجيب خيط معالجة الأحداث إلى الحدث الناشئ عن كتابة الرسالة بإرسالها. وفي المقابل، تُستقبَل الرسائل القادمة بخيطٍ منفصلٍ جُلّ ما يفعله هو انتظار الرسائل القادمة. يكون ذلك الخيط مُعطَّلًا أثناء انتظاره؛ وعند وصول رسالة، يَعرِضها للمُستخدِم. تحتوي نافذة البرنامج على مساحةٍ كبيرةٍ لِعرض الرسائل المُرسَلة والمُستقبَلة إلى جانب بعض المعلومات الأخرى عن الاتصال الشبكي. يُفضَّل أن تُصرِّف compile شيفرة البرنامج GUIChat.java، وتُجرِّبه. إذا أردت تجريبه على حاسوبٍ واحد، يُمكِنك تشغيل نسختين من البرنامج على نفس الحاسوب، وإنشاء الاتصال بين نافذتي البرنامج باستخدام "localhost" أو "127.0.0.1" على أنه اسمٌ للحاسوب. حاوِل أيضًا قراءة الشيفرة المصدرية للبرنامج. سنناقش بعضها فقط فيما يلي. يَستخدِم البرنامج الصنف المُتداخِل ConnectionHandler المُشتَق من الصنف Thread لمعالجة معظم المهام المُتعلّقة بالشبكة، حيث يتولى الخيط المُمثَّل بواسطة الصنف ConnectionHandler مهمة إنشاء الاتصال الشبكي، وقراءة الرسائل القادمة بعد فتح الاتصال. نضمَن عدم تعطُّل واجهة المُستخدِم الرسومية أثناء إنشاء الاتصال بوضعنا الشيفرة المسؤولة عن إنشاء الاتصال واستقبال الرسائل بخيطٍ منفصل. يُعدّ فتح الاتصال عمليةً مُعطِّلة، مثل عملية قراءة الرسائل، وقد تَستغرِق بعض الوقت. يُنشِئ الصنف ConnectionHandler الاتصال بكلا الحالتين؛ أي عندما يَعمَل البرنامج خادمًا أو عميلًا. يُنشَأ ذلك الخيط عندما ينقر المُستخدم على زر "Listen" أو زر "Connect"؛ حيث يؤدي زر "Listen" إلى عمل البرنامج على أنه خادم؛ بينما يؤدي زر"Connect" إلى عمله عميلًا. يُميّز الصنف ConnectionHandler بين تلك الحالتين بتعريف بانيين constructors معروضين بالأسفل. يَعرِض التابع postMessage()‎ رسالةً بالمساحة النصية الموجودة بالنافذة لكي يراها المُستخدِم. ألقِ نظرةً على تعريف كلا البانيين: // 1 ConnectionHandler(int port) { // For acting as the "server." state = ConnectionState.LISTENING; this.port = port; postMessage("\nLISTENING ON PORT " + port + "\n"); try { setDaemon(true); } catch (Exception e) {} start(); } // 2 ConnectionHandler(String remoteHost, int port) { // For acting as "client." state = ConnectionState.CONNECTING; this.remoteHost = remoteHost; this.port = port; postMessage("\nCONNECTING TO " + remoteHost + " ON PORT " + port + "\n"); try { setDaemon(true); } catch (Exception e) {} start(); } حيث: [1]: تعني اِستمِع إلى طلب اتصالٍ برقم منفَّذٍ مُخصَّص. لا يفعل الباني أي عملياتٍ شبكية، وإنما يضبُط فقط بعض متغيرات النسخ ويُشغِّل الخيط. يَستمِع الخيط إلى طلب اتصالٍ واحدٍ فقط، ثم يَغلِق مقبس الخادم. [2]: تعني اِفتح اتصال مع الحاسوب برقم المنفَّذ المُخصَّص. لا يفعل الباني أي عمليات شبكية، وإنما يضبُط فقط بعض متغيرات النسخ ويُشغِّل الخيط. لاحِظ أن state هو متغير نسخة instance variable من نوع التعداد enumerated type التالي: enum ConnectionState { LISTENING, CONNECTING, CONNECTED, CLOSED }; تُمثِّل قيم ذلك التعداد الحالات المختلفة للاتصال الشبكي. يُفضَّل غالبًا التعامل مع الاتصال الشبكي مثل آلة حالة state machine (انظر قسم آلات الحالة من مقال تعرف على أهم الأحداث والتعامل معها في مكتبة جافا إف إكس JavaFX)؛ نظرًا لاعتماد الاستجابة إلى الأحداث المختلفة عادةً على الحالة التي كان عليها الاتصال عند وقوع الحدث. يُحدِّد الخيط ما إذا كان عليه التصرف مثل خادمٍ أو عميل أثناء إنشاء الاتصال من خلال ضبط قيمة المتغير state إلى القيمة LISTENING أو CONNECTING. بمجرد بدء تشغيل الخيط، يُنفَّذ التابع run()‎ المُعرَّف على النحو التالي: // 1 public void run() { try { if (state == ConnectionState.LISTENING) { // أنشِئ اتصالًا بصفة خادم listener = new ServerSocket(port); socket = listener.accept(); listener.close(); } else if (state == ConnectionState.CONNECTING) { // أنشِئ اتصالًا بصفة عميل socket = new Socket(remoteHost,port); } connectionOpened(); // 2 while (state == ConnectionState.CONNECTED) { // 3 String input = in.readLine(); if (input == null) connectionClosedFromOtherSide(); // أغلق المقبس وبلِّغ المُستخدِم else received(input); // بلِّغ الرسالة إلى المُستخدم } } catch (Exception e) { // 4 if (state != ConnectionState.CLOSED) postMessage("\n\n ERROR: " + e); } finally { // Clean up before terminating the thread. cleanUp(); } } حيث أن: [1]: يُستدعَى التابع run()‎ بواسطة الخيط. يَفتَح التابع اتصالًا مثل خادمٍ أو عميل بالاعتماد على نوع الباني المُستخدَم. [2]: جهِّز الاتصال بما في ذلك إنشاء كائن من الصنف BufferedReader لقراءة الرسائل القادمة. [3]: اقرأ سطرًا نصيًا واحدًا من الطرف الآخر من الاتصال وبلِّغه للمُستخدِم. [4]: حدث خطأ. بلِّغ المُستخدِم إذا لم يكن قد أغلق الاتصال، لأنه قد يكون الخطأ المُتوقَّع حدوثه عند غلق مقبس الاتصال. يَستدعِي هذا التابع مجموعةً من التوابع الأخرى لإنجاز بعض الأمور، ولكن بإمكانك فهم الفكرة العامة لطريقة عمله. بعد فتح الاتصال مثل خادمٍ أو عميل، يُنفِّذ التابع run()‎ حلقة while يَستقبِل خلالها الرسائل من الطرف الآخر من الاتصال ويعالجها إلى أن يُغلَق الاتصال. من المهم فهم طريقة غلق الاتصال؛ حيث تُوفِّر نافذة البرنامج GUIChat الزر "Disconnect"، وعندما ينقر عليه المُستخدِم، يُغلَق الاتصال. يَستجِيب البرنامج إلى ذلك الحدث بغلق المقبس المُمثِّل للاتصال، وكذلك بضبط حالة الاتصال إلى CLOSED. في تلك الأثناء، قد يكون خيط معالجة الاتصال مُعطَّلًا بانتظار الرسالة التالية نتيجة لاستدعائه التابع in.readLine()‎. عندما يُغلِق خيط واجهة المُستخدِم الرسومية المقبس، يفشل ذلك التابع ويُبلِّغ عن استثناءٍ exception يتسبَّب بانتهاء الخيط. إذا كان خيط معالجة الاتصال واقعًا بين لحظتي استدعاء التابع in.readLine()‎ عند غلق المقبس، تنتهي حلقة while لأن حالة الاتصال تتبدَّل من CONNECTED إلى CLOSED. يؤدي غلق نافذة البرنامج إلى غلق الاتصال بنفس الطريقة. علاوةً على ذلك، قد يُغلَق الاتصال بواسطة المُستخدِم على الطرف الآخر، ويُغلَق في تلك الحالة مجرى الرسائل القادمة، ويُعيد التابع in.readLine()‎ بهذا الطرف من الاتصال القيمة null، وهو ما يُشير إلى نهاية المجرى، ويُمثِّل إشارةً إلى أن المُستخدِم الآخر قد أغلق الاتصال. سنُلقِي نظرةً أخيرة على شيفرة البرنامج GUIChat وخاصةً على التوابع المسؤولة عن إرسال الرسائل واستقبالها. يَستدعِي الخيطان تلك التوابع؛ حيث يَستدعِي خيط معالجة الأحداث التابع send()‎ بغرض إرسال رسالةٍ إلى المُستخدِم على الطرف الآخر من الاتصال استجابةً لفِعِل المُستخدِم. قد تؤدي عملية إرسال البيانات إلى حدوث تعطيل -وإن كان احتمال ذلك ضئيلًا- إذا أصبح المخزن المؤقت buffer الخاص بالمقبس ممتلئًا. ربما يأخذ برنامج أكثر تطورًا ذلك الاحتمال بالحسبان. يَستخدِم التابع كائنًا من النوع PrintWriter، اسمه هو out، لإرسال الخرج إلى مجرى الخرج الخاص بالمقبس. لاحِظ أن التابع متزامنٌ ليَمنَع تعديل حالة الاتصال أثناء إجراء عملية الإرسال. انظر شيفرة التابع: // 1 synchronized void send(String message) { if (state == ConnectionState.CONNECTED) { postMessage("SEND: " + message); out.println(message); out.flush(); if (out.checkError()) { postMessage("\nERROR OCCURRED WHILE TRYING TO SEND DATA."); close(); // أغلِق الاتصال } } } وتعني [1]: يُرسِل رسالةً إلى الطرف الآخر من الاتصال ويعرضها على الشاشة. ينبغي أن يُستدعَى هذا التابع عندما تكون حالة الاتصال ConnectionState.CONNECTED فقط. يتجاهل التابع الاستدعاء بالحالات الأخرى. يَستدعِي خيط معالجة الأحداث التابع received()‎ بعد قراءة رسالةٍ من المُستخدِم على الطرف الآخر من الاتصال، حيث يعرِض التابع الرسالة للمُستخدِم. لاحِظ أن التابع متزامن لتجنُّب حالة التسابق race condition التي يُمكِنها أن تحدُث إذا بدَّل خيطٌ آخر حالة الاتصال بينما ما يزال التابع قيد التنفيذ. ألقِ نظرةً على شيفرة التابع: // 1 synchronized private void received(String message) { if (state == ConnectionState.CONNECTED) postMessage("RECEIVE: " + message); } [1] يُستدعَى هذا التابع بواسطة التابع run()‎ عند استقبال رسالةٍ من الطرف الآخر من الاتصال. يُظهِر التابع الرسالة على الشاشة إذا كانت حالة الاتصال CONNECTED فقط؛ لأنها قد تَصِل بعد أن ينقر المُستخدم على زر "Disconnect"، وبالتالي لا ينبغي أن يراها المُستخدِم. خادم شبكي متعدد الخيوط تُستخدَم الخيوط عادةً ببرامج الخوادم؛ لأنها تَسمَح للخادم بالتعامل مع مجموعةٍ من العملاء بنفس الوقت. عندما يبقى عميلٌ معينٌ متصلًا لفترةٍ طويلةٍ نسبيًا، لا ينبغي أن يضطّر العملاء الآخرون إلى انتظار الخدمة، وحتى إن كان من المتوقَّع أن يكون تعامل الخادم مع كل عميلٍ قصيرًا للغاية، حيث لا يُمكِننا أن نفترض أن ذلك سيكون هو الحال دائمًا؛ فقد يُسيء عميلٌ معينٌ التصرف، ويبقى متصلًا دون أن يُرسِل البيانات التي يتوقَّعها الخادم؛ لذلك ينبغي أن نأخذ تلك الاحتمالية بالحسبان، لأننا إن لم نفعل، فإنه قد يؤدي إلى غلق الخيط تمامًا. في المقابل، إذا اعتمد الخادم على الخيوط، سيكون هناك خيوطٌ أخرى بإمكانها الرد على العملاء الآخرين. يُعدّ المثال التوضيحي DateServer.java من مقال تواصل تطبيقات جافا عبر الشبكة برنامج خادم بسيطٍ للغاية؛ فهو لا يَستخدِم الخيوط، ولذلك لا بُدّ أن ينتهي الخادم من اتصاله مع عميلٍ معين قبل أن يَقبَل اتصالًا من عميلٍ آخر. سنرى الآن كيفية تحويل ذلك البرنامج إلى خادمٍ مبني على الخيوط. في الواقع، يُعَد هذا الخادم بسيطًا جدًا لدرجة أن اِستخدَام الخيوط معه لا معنى له، ولكن الفكرة أنه من الممكن تطبيق نفس تلك التقنيات على الخوادم الأكثر تعقيدًا. ألقِ نظرةً على تمرين 12.5 على سبيل المثال. لنناقش الآن المحاولة الأولى من البرنامج DateServerWithThreads.java، حيث يُنشِئ هذا البرنامج خيطًا جديدًا بكل مرة يَستقبِل خلالها طلب اتصال بدلًا من مُعالجة الاتصال بنفسه باستدعاء برنامجٍ فرعي subroutine. يُنشِئ البرنامج main الخيط ويُمرِّر إليه الاتصال. يَستغرِق ذلك وقتًا قصيرًا للغاية، والأهم أنه لن يتسبَّب بحدوث تعطيل. في المقابل، يُعالِج تابع الخيط run()‎ الاتصال بنفس الكيفية التي عالجنا بها الاتصال بالبرنامج الأصلي. تُعد برمجة ذلك سهلة، ويمكنك إلقاء نظرةٍ على النسخة الجديدة من البرنامج بعد إجراء التعديلات؛ حيث يمكننا ملاحظة أن الباني constructor الخاص بخيط الاتصال لا يَفعَل شيئًا تقريبًا، ولا يُسبِّب تعطيلًا، وهذا أمرٌ مهم؛ لأنه يُنفَّذ بالخيط الرئيسي: import java.net.*; import java.io.*; import java.util.Date; // 1 public class DateServerWithThreads { public static final int LISTENING_PORT = 32007; public static void main(String[] args) { ServerSocket listener; // اِستمِع لطلبات الاتصال القادمة Socket connection; // للتواصل مع البرنامج المتصِل // استمر باستقبال طلبات الاتصال ومعالجتها للأبد إلى أن يحدث خطأ ما try { listener = new ServerSocket(LISTENING_PORT); System.out.println("Listening on port " + LISTENING_PORT); while (true) { // اِقبَل طلب الاتصال التالي وأنشِئ خيطًا لمعالجته connection = listener.accept(); ConnectionHandler handler = new ConnectionHandler(connection); handler.start(); } } catch (Exception e) { System.out.println("Sorry, the server has shut down."); System.out.println("Error: " + e); return; } } // end main() // 2 private static class ConnectionHandler extends Thread { Socket client; // يُمثِّل اتصالًا مع عميل ConnectionHandler(Socket socket) { client = socket; } public void run() { // (code copied from the original DateServer program) String clientAddress = client.getInetAddress().toString(); try { System.out.println("Connection from " + clientAddress ); Date now = new Date(); // التوقيت والتاريخ الحالي PrintWriter outgoing; // مجرى لإرسال البيانات outgoing = new PrintWriter( client.getOutputStream() ); outgoing.println( now.toString() ); outgoing.flush(); // تأكّد من إرسال البيانات client.close(); } catch (Exception e){ System.out.println("Error on connection with: " + clientAddress + ": " + e); } } } } //end class DateServerWithThreads إذ أن: [1]: يمثّل هذا البرنامج خادمًا يَستقبِل طلبات الاتصال برقم المنفذ الذي يُخصِّصه الثابث LISTENING_PORT. يرسِل البرنامج عند فتح اتصال التوقيت الحالي إلى المقبس المتصِل، ويستمر باستقبال طلبات الاتصال ومعالجتها إلى أن يُغلَق بالضغط على CONTROL-C على سبيل المثال. تُنشِئ هذه النسخة من البرنامج خيطًا جديدًا لكل طلب اتصال. [2]: يُعرِّف خيطًا لمعالجة الاتصال مع عميلٍ واحد. انظر إلى نهاية التابع run()‎، حيث أضفنا clientAddress إلى رسالة الخطأ؛ لنتمكَّن من معرفة الاتصال الذي تشير إليه رسالة الخطأ. نظرًا لأن الخيوط تُنفَّذ على التوازي، قد يَختلِط خرج الخيوط المختلفة؛ أي ليس من الضروري أن تَظهَر الرسائل الخاصة بخيطٍ معين معًا، وإنما قد يَفصِل بينها رسائلٌ من خيوطٍ أخرى. يُمثِّل ذلك واحدًا فقط من ضمن التعقيدات الكثيرة التي ينبغي الانتباه لها عند تعاملنا مع الخيوط. استخدام مجمع الخيوط لا يُعدّ إنشاء خيطٍ جديدٍ لكل اتصال الحل الأفضل، خاصةً إذا كانت تلك الاتصالات قصيرة. لحسن الحظ، يُمكِننا أن نَستخدِم مُجمّع خيوط الذي ناقشناه بقسم مجمع الخيوط وأرتال المهام من المقال السابق. يُعدّ البرنامج DateServerWithThreadPool.java نسخةً مُحسنَّةً من الخادم؛ حيث يَستخدِم مجمع خيوط. يُنفِّذ كل خيطٍ ضمن ذلك المُجمّع حلقة تكرار لا نهائية infinite loop يُعالِج كل تكرارٍ منها اتصالًا. علينا أن نَجِد طريقةً تُمكِّن البرنامج main من إرسال الاتصالات إلى الخيوط. ومن البديهي أن نَستخدِم رتلًا مُعطِّلًا blocking queue لذلك الغرض، وسيكون اسمه هو connectionQueue. تقرأ خيوط معالجة الاتصال الاتصالات من الرتل؛ ونظرًا لكونه رتلًا مُعطِّلًا، تتعطَّل الخيوط عندما يكون الرتل فارغًا، وتستيقظ عند إتاحة اتصالٍ جديدٍ بالرتل. لن نحتاج إلى أي تقنيات مزامنة أو اتصال أخرى؛ فكل شيءٍ مبنيٌ مُسبقًا بالرتل المُعطِّل. تعرض الشيفرة التالية التابع run()‎ الخاص بخيوط معالجة الاتصال: public void run() { while (true) { Socket client; try { client = connectionQueue.take(); // تعطَّل إلى أن يُتاح عنصر جديد } catch (InterruptedException e) { continue; // إذا قُوطِعَ، عدّ إلى بداية حلقة التكرار } String clientAddress = client.getInetAddress().toString(); try { System.out.println("Connection from " + clientAddress ); System.out.println("Handled by thread " + this); Date now = new Date(); // التاريخ والتوقيت الحالي PrintWriter outgoing; // مجرى لإرسال البيانات outgoing = new PrintWriter( client.getOutputStream() ); outgoing.println( now.toString() ); outgoing.flush(); // تأكّد من إرسال البيانات فعليًا client.close(); } catch (Exception e){ System.out.println("Error on connection with: " + clientAddress + ": " + e); } } } يُنفِّذ البرنامج main()‎ حلقة تكرارٍ لا نهائية تَستقبِل الاتصالات وتُضيفها إلى الرتل: while (true) { // اقبل طلب الاتصال التالي وأضِفه إلى الرتل connection = listener.accept(); try { connectionQueue.put(connection); // تعطَّل إذا كان الرتل ممتلئًا } catch (InterruptedException e) { } } لاحِظ أن الرتل بهذا البرنامج من النوع ArrayBlockingQueue<Socket>‎؛ أي أن لديه سعةً قصوى، وبالتالي إذا كان الرتل ممتلئًا، سيؤدي تنفيذ عملية put()‎ إلى حدوث تعطيل. ولكن ألسنا نريد تجنُّب حدوث أي تعطيلٍ بالبرنامج main()‎؟ لأنه إذا تعطُّل، فلن يستقبل الخادم أي اتصالاتٍ أخرى، ويضطّر العملاء الذي يحاولون الاتصال إلى الانتظار. أليس من الأفضل اِستخدام الصنف LinkedBlockingQueue بسعةٍ غير محدودة؟ في الحقيقة، تُعدّ الاتصالات الموجودة بالرتل المُعطِّل قيد الانتظار على أية حال، أي أنها لم تُخدَّم بعد؛ وإذا ازداد حجم الرتل بدرجةٍ غير معقولة، فستضطّر الاتصالات الموجودة بالرتل إلى الانتظار إلى فتراتٍ غير معقولةٍ أيضًا. وبالتالي، إذا ازداد حجم الرتل إلى ما لانهاية، لا يَعنِي ذلك سوى أن الخادم يَستقبِل طلبات اتصال بسرعةٍ أكبر من سرعة قدرته على معالجة تلك الاتصالات. قد يحدث ذلك لعدة أسباب: ربما يكون خادمك غير قوي كفاية لمعالجة كمية الاتصالات المطلوبة، وينبغي في تلك الحالة أن تشتري خادمًا جديدًا؛ أو ربما بسبب عدم احتواء مجمع الخيوط على عددٍ كافٍ من الخيوط بدرجة تَسمَح بالاستفادة من إمكانيات الخادم بالكامل، وينبغي في تلك الحالة زيادة حجم مجمع الخيوط ليتوافق مع إمكانيات الخادم؛ أو ربما يتعرَّض الخادم لهجوم الحرمان من الخدمات Denial Of Service، أي أن هناك شخصٌ معينٌ يحاول متعمّدًا إرسال طلبات اتصال إلى الخادم بقدرٍ أكبر مما يَستطيع احتماله في محاولة لمنع العملاء من الوصول إلى الخدمة. في جميع الأحوال، يُعدّ الصنف ArrayBlockingQueue ذو السعة المحدودة هو الخيار الأصح. ينبغي أن يكون الرتل قصيرًا حتى لا تضطّر الإتصالات الموجودة به إلى الانتظار لفتراتٍ طويلة قبل وصولها إلى الخدمة. بالنسبة للخوادم الحقيقية، لا بُدّ من ضبط كُلٍ من حجم الرتل وعدد خيوط المجمع بما يتناسب مع الخادم؛ كما ينبغي أن يُؤخَذ العتاد والشبكة التي يَعمَل عليها الخادم بالحسبان؛ وكذلك طبيعة طلبات العملاء التي يُفترَض معالجتها، وهو ما يُمثِّل تحديًا صعبًا عمومًا. بالمناسبة، هناك احتماليةٌ أخرى قد تسوء الأمور نتيجة لها: لنفترض أن الخادم يحتاج إلى قراءة بعض البيانات من العميل، ولكن العميل لا يرسل أية بيانات. في تلك الحالة، قد يتعطَّل الخيط الذي يحاول قراءة البيانات إلى الأبد بانتظار المُدْخَلات. إذا كنا نَستخدِم مجمع خيوط، فقد يَحدُث ذلك لجميع الخيوط الموجودة بالمجمع، وعندها، لن تحدث أي معالجةٍ أخرى. يتمثل حل تلك المشكلة بإيقاف الاتصال إذا بقي غير نشطٍ لفترةٍ طويلة من الوقت. ينتبه كل خيط اتصال عادةً إلى آخر توقيت استقبل به بياناتٍ من العميل. يُشغِّل الخادم خيطًا آخر يُطلَق عليه أحيانًا اسم "خيط reaper" تيمُنًا بفرقة "Grim Reaper"، ويوقظه دوريًا؛ حتى يَفحَص خيوط الاتصال، ويرى فيما إذا كان هناك خيطٌ غير نشط لفترةٍ طويلة. إذا بقي خيطٌ قيد الانتظار لفترة طويلة، فإنه يُنهَى، ويحلّ محله خيطٌ جديد. تُمثِّل الإجابة على سؤال "كم من الوقت ينبغي أن تكون تلك الفترة الطويلة؟" تحديًا آخر. الحوسبة الموزعة لقد رأينا طريقة اِستخدام الخيوط لإجراء المعالجة على التوازي؛ حيث تَعمَل عدة معالجات معًا لإنجاز مهمةٍ معينة. كان افتراضنا حتى الآن هو أن جميع تلك المعالجات موجودةٌ ضمن حاسوبٍ واحد مُتعدِّد المعالجات، ولكن يُمكِن إجراء المعالجة على التوازي باستخدام معالجاتٍ موجودة بحواسيبٍ مختلفة شرط أن تكون تلك الحواسيب متصلةً عبر شبكةٍ معينة؛ ويُطلَق على هذا النوع من المعالجة المتوازية -أي أن تَعمَل عدة حواسيب معًا لإنجاز مهمةٍ عبر الشبكة- اسم الحوسبة المُوزَّعة distributed computing. يُمكِننا أن ننظر لشبكة الانترنت وكأنها نموذجٌ ضخمٌ لحوسبةٍ موزَّعة، ولكننا في الواقع معنيون بالكيفية التي يمكن أن تتعاون من خلالها الحواسيب المتصلة عبر شبكةٍ على حل مشكلة حوسبية. هناك طرائقٌ متعددة للحوسبة الموزّعة، وتدعم جافا بعضًا منها. على سبيل المثال، تُمكِّن كُلًا من تقنية استدعاء التوابع عن بعد Remote Method Invocation - RMI وتقنية كوربا Common Object Request Broker Architecture - CORBA برنامجًا مُشغَّلًا على حاسوبٍ معين من استدعاء توابع كائناتٍ موجودة بحواسيبٍ اخرى. يَسمَح ذلك بتصميم برنامجٍ كائني التوجه object-oriented تُنفَّذ أجزاءه المختلفة بحواسيب مختلفة. تدعم RMI الاتصال بين كائنات جافا فقط؛ بينما تُعدّ CORBA المعيار الأكثر عمومية، حيث تَسمَح للكائنات المكتوبة بأي لغة برمجية، بما في ذلك جافا، بالتواصل مع بعضها بعضًا. كما هو الحال مع الشبكات، لدينا مشكلة تحديد موقع الخدمات (المقصود بالخدمة هنا هو الكائن المُتاح للاستدعاء عبر الشبكة)، أي كيف يستطيع حاسوبٌ معين معرفة الحاسوب الذي تَعمَل عليه خدمةٌ معينة ورقم المنفذ الذي تَستمِع إليه؟ تحلّ تقنيتي "RMI" و "CORBA" تلك المشكلة باستخدام "وسيط طلب request broker"؛ حيث يمثّل ذلك الوسيط برنامج خادم يَعمَل بعنوانٍ معروف، ويحتوي على قائمة الخدمات المتاحة بالحواسيب الأخرى، وتُبلِّغ الحواسيب المُقدِّمَة لخدمات الوسيط بخدماتها. ينبغي أن تعرف الحواسيب التي تحتاج خدمةً معينةً عنوان الوسيط للتواصل معه وسؤاله عن الخدمات المُتاحة وعناوينها. تُعدّ "RMI" و "COBRA" أنظمةً معقدة وليس من السهل تمامًا استخدامها، وذُكرت هنا لأنها جزءٌ من واجهة برمجة تطبيقات API جافا للشبكات القياسية، ولكننا لن نناقشها إلى أبعد من ذلك. بدلًا منها، سنفحص مثالًا أبسط على الحوسبة المُوزَّعة يَستخدِم أساسيات الشبكات فقط. يتشابه هذا المثال مع ذلك الذي اِستخدمناه بالبرنامج MultiprocessingDemo1.java ونُسخه المختلفة بالمقالين البرمجة باستخدام الخيوط threads في جافا والمقال السابق، وهو مثال حساب ألوان صورةٍ معقدة، ولكننا لن نُنشِئ هنا برنامجًا بواجهة مُستخدِم رسومية، ولن نعرض الصورة على الشاشة. تَستخدِم عملية المعالجة أبسط أنواع المعالجة على التوازي بتقسيم المشكلة إلى عدة مهام يُمكِن تنفيذها باستقلالية دون الاتصال مع المهام الأخرى. لتطبيق الحوسبة المُوزَّعة على هذا النوع من المشكلات، سنَستخدِم برنامجًا رئيسيًا master يتولى مسؤولية تقسيم المشكلة إلى عدة مهام وإرسالها عبر الشبكة إلى البرامج العاملة worker لتُنفِّذها. ينبغي أن تُرسِل تلك البرامج نتائجها إلى البرنامج الرئيسي الذي يَدمِج نتائج جميع المهام معًا ليكوِّن حلًا لكامل المشكلة. يُطلَق على البرامج العاملة ضمن هذا السياق اسم "البرامج التابعة slaves"، ويُقال أن البرنامج يَستخدِم أسلوب "البرنامج الرئيسي والبرنامج التابع master/slave" لإجراء الحوسبة المُوزَّعة. يتكوَّن هذا البرنامج من ثلاثة ملفات؛ حيث يُعرِّف الملف CLMandelbrotMaster.java البرنامج الرئيسي، بينما يُعرِّف الملف CLMandelbrotWorker.java البرامج العاملة التابعة؛ وأخيرًا يُعرِّف الملف CLMandelbrotTask.java الصنف CLMandelbrotTask الذي يُمثِّل المهمة التي تُنفِّذها البرامج العاملة. يُقسِّم البرنامج الرئيسي master المشكلة إلى عدة مهام، ثم يُوزِّعها على البرامج العاملة، التي تُنفِّذ تلك المهام، ثم تُعيد النتائج إلى البرنامج الرئيسي. ويُطبِّق البرنامج الرئيسي بالنهاية نتائج جميع المهام المفردة على المشكلة الأساسية. لتشغيل البرنامج، سنبدأ أولًا بتشغيل البرنامج "CLMandelbrotWorker" على عدّة حواسيب (ربما بتنفيذها بسطر الأوامر). يَستخدِم ذلك البرنامج الصنف CLMandelbrotTask، ولذلك يجب أن يكون كل من الملف CLMandelbrotWorker.class والملف CLMandelbrotTask.class متوفرين بالحواسيب المُمثِّلة للبرامج العاملة. بعد ذلك، سنُشغِّل البرنامج المسمى "CLMandelbrotMaster" على الحاسوب المُمثِل للبرنامج الرئيسي، مع ملاحظة أنه يحتاج إلى الصنف CLMandelbrotTask أيضًا. يجب أن نُمرِّر اسم أو عنوان بروتوكول الانترنت IP address الخاص بجميع الحواسيب العاملة إلى البرنامج المسمى "CLMandelbrotMaster" مثل وسطاءٍ عبر سطر الأوامر. تستمع البرامج العاملة إلى طلبات الاتصال القادمة من البرنامج الرئيسي، ولهذا يجب أن يعرف البرنامج الرئيسي العناوين التي سيُرسِل إليها تلك الطلبات. على سبيل المثال، إذا كان البرنامج العامل مُشغَّلًا على ثلاثة حواسيب عناوينها هي: 172.21.7.101 و 172.21.7.102 و 172.21.7.103، يُمكِننا أن نُشغِّل البرنامج "CLMandelbrotMaster" بكتابة الأمر التالي: java CLMandelbrotMaster 172.21.7.101 172.21.7.102 172.21.7.103 سينُشِئ البرنامج الرئيسي اتصالًا شبكيًا مع البرنامج العامل بكل عنوان بروتوكول إنترنت، وستُستخدَم تلك الاتصالات للتواصل بين كُلٍ من البرنامج الرئيسي والبرامج العاملة. يُمكِننا تشغيل عدة نسخٍ من البرنامج "CLMandelbrotWorker" على نفس الحاسوب، ولكن ينبغي أن يستمع كُلًا منها إلى الاتصالات الشبكية القادمة عبر أرقام منافذٍ مختلفة. كما يُمكِننا تشغيل البرنامج "CLMandelbrotWorker" على نفس الحاسوب الذي يَعمَل عليه البرنامج "CLMandelbrotMaster"، ولربما ستلاحظ عندها زيادة سرعة البرنامج إذا كان حاسوبك يحتوي على عدة معالجات. ألقِ نظرةً على التعليقات الموجودة بشيفرة البرنامج لمزيدٍ من المعلومات. نستعرض فيما يلي بعض الأوامر المُمكِن استخدامها لتشغيل البرنامج الرئيسي مع نسختين من البرنامج العامل على نفس الحاسوب. اُكتُبها بنوافذ سطر أوامر مختلفة: java CLMandelbrotWorker (Listens on default port) java CLMandelbrotWorker 2501 (Listens on port 2501) java CLMandelbrotMaster localhost localhost:2501 يَحلّ البرنامج "CLMandelbrotMaster" نفس المشكلة بالضبط في كل مرةٍ نُشغِّل بها. في الواقع، طبيعة المشكلة ذاتها غير مهم، ولكنها تمثّل هنا حساب البيانات التي يتطلَّبها رسم جزءٍ صغير من صورة مجموعة ماندلبرو Mandelbrot Set الشهيرة. إذا كنت تريد رؤية الصورة الناتجة، ألغِ التعليق الموجود فوق الاستدعاء saveImage()‎ بنهاية البرنامج main()‎ المُعرَّف بالملف CLMandelbrotMaster.java). يُمكِنك تشغيل البرنامج "CLMandelbrotMaster" مع عددٍ مختلف من البرامج العاملة لرؤية مدى اعتمادية الزمن الذي يتطلَّبه حل المشكلة على عدد البرامج العاملة. لاحِظ استمرار البرامج العاملة بالعمل حتى بعد انتهاء البرنامج الرئيسي؛ أي يُمكِنك تشغيل البرنامج الرئيسي عدة مرات دون الاضطرار لإعادة تشغيل البرامج العاملة في كل مرة. علاوةً على ذلك، إذا شغَّلت البرنامج "CLMandelbrotMaster" دون أن تُمرِّر إليه أي وسطاء، فإنه سيحلّ المشكلة بالكامل بمفرده، ويُمكِنك بذلك رؤية الزمن الذي يتطلَّبه حل المشكلة بدون الحوسبة المُوزَّعة. في الواقع، جرَّبنا ذلك بإحدى الحواسيب القديمة والبطيئة جدًا، ووجدنا أن البرنامج "CLMandelbrotMaster" قد استغرق 40 ثانية لحل المشكلة بمفرده؛ في حين استغرق 43 ثانية عند تشغيل برنامجٍ عاملٍ واحد. تُمثِّل تلك الزيادة العمل الإضافي المطلوب لاستخدام الشبكات، حيث يتطلَّب إنشاء الاتصال الشبكي، وإرسال الرسائل عبر الشبكة المزيد من الوقت. في المقابل، اِستغرَق البرنامج 22 ثانية فقط لحل المشكلة عند تشغيل برنامجين عاملين بحواسيبٍ مختلفة. في تلك الحالة، نفَّذ كل برنامجٍ منهما نصف العمل على التوازي، ولذلك أنُجزَت العملية بنصف الوقت تقريبًا. يستمر الزمن بالنقصان مع زيادة عدد البرامج العاملة، ولكن إلى حدٍ معين؛ لأن البرنامج الرئيسي لديه أيضًا بعض العمل الواجب إنجازه مهما ازداد عدد البرامج العاملة، وعليه لا يُمكِن للزمن الكلي المطلوب لحل المشكلة أن يكون أقل من الزمن الذي يستغرقه البرنامج الرئيسي لتنفيذ عمله. وفي تلك الحالة، بدا أن أقل زمنٍ ممكنٍ هو 5 ثوانٍ تقريبًا. والآن، لنرى طريقة برمجة هذا التطبيق المُوزَّع. سيُقسِّم البرنامج الرئيسي المشكلة إلى مجموعة مهام؛ بحيث تُمثَّل كل مهمة منها باستخدام كائنٍ ينتمي إلى الصنف CLMandelbrotTask. تُرسَل تلك المهام إلى البرامج العاملة، التي ينبغي لها أن تعيد نتائجها بعد أن تحسبها. يَعنِي ذلك أننا بحاجة إلى نوعٍ من البروتوكول للتواصل؛ ولذلك قررنا استخدام مجرى محارف character stream لهذا الغرض. سيُشفِّر البرنامج الرئيسي كل مهمةٍ بهيئة سطرٍ نصي يُرسَل إلى البرنامج العامل، الذي سيَفك التشفير ويُعيد السطر إلى كائنٍ من الصنف CLMandelbrotTask ليتمكَّن من فهم المهمة المفترض تنفيذها. بعد ذلك، يُنجِز البرنامج العامل المهمة، ثم يُشفِّر النتائج بهيئة سطرٍ نصي آخر يُرسَل عائدًا إلى البرنامج الرئيسي. أخيرًا، يَفُك البرنامج الرئيسي الشيفرة، ويَدمِج النتيجة مع نتائج المهام الأخرى. بعد اكتمال جميع المهام ودمج نتائجها معًا، تكون المشكلة قد حُلَّت. لا يستقبل كل برنامجٍ عاملٍ مهمةً واحدةً فقط، وإنما متتاليةً من المهام؛ فبمجرد أن يُنجز مهمةً معينة، ويُرسِل نتائجها، تُسنَد إليه مهمةٌ جديدة. يَستقبِل البرنامج العامل الأمر "close" بعد اكتمال جميع المهام ليخبره بأن عليه إغلاق الاتصال. يُجرَى كل ما سبق ضمن تابعٍ، اسمه handleConnection()‎ بالملف CLMandelbrotWorker.java، حيث يُستدعَى ذلك التابع لمعالجة اتصالٍ قد اُنشئ بالفعل مع البرنامج الرئيسي. يَستخدِم ذلك التابع بدوره تابعًا آخر، اسمه readTask()‎ لفك تشفير المهمة التي استقبلها من البرنامج الرئيسي؛ كما يستخدِم التابع writeResults()‎ بهدف تشفير نتائج المهمة قبل إرسالها إلى البرنامج الرئيسي. يجب عليه أيضًا معالجة أي أخطاءٍ ممكنة. انظر تعريف التابع: private static void handleConnection(Socket connection) { try { BufferedReader in = new BufferedReader( new InputStreamReader( connection.getInputStream()) ); PrintWriter out = new PrintWriter(connection.getOutputStream()); while (true) { String line = in.readLine(); // رسالة من البرنامج الرئيسي if (line == null) { // واجهنا نهاية المجرى. لا ينبغي أن يحدث ذلك throw new Exception("Connection closed unexpectedly."); } if (line.startsWith(CLOSE_CONNECTION_COMMAND)) { // يُمثِّل الانتهاء الطبيعي للاتصال System.out.println("Received close command."); break; } else if (line.startsWith(TASK_COMMAND)) { // يُمثِل مهمةً من النوع‫ CLMandelbrotTask ينبغي أن ينفذها الخيط CLMandelbrotTask task = readTask(line); // فك تشفير الرسالة task.compute(); // نفِّذ المهمة out.println(writeResults(task)); // أرسِل النتائج out.flush(); // تأكّد من إرسال النتائج } else { // ليس هناك أي رسائل أخرى ضمن البروتوكول throw new Exception("Illegal command received."); } } } catch (Exception e) { System.out.println("Client connection closed with error " + e); } finally { try { connection.close(); // تأكّد من إغلاق المقبس } catch (Exception e) { } } } لا يُنفَّذ التابع المُعرَّف بالأعلى بخيطٍ thread مُنفصل، فالبرنامج العامل لديه شيءٌ واحدٌ فقط ليفعله بأي لحظة، ولا يحتاج إلى عدة خيوط. لنعود الآن إلى البرنامج الرئيسي CLMandelbrotMaster.java، حيث نواجه وضعًا أكثر تعقيدًا. يجب أن يُنشِئ البرنامج اتصالًا مع مجموعةٍ من البرامج العاملة عبر مجموعةٍ من الاتصالات الشبكية، وسيَستخدِم البرنامج لإنجاز ذلك عدة خيوط؛ بحيث يُعالِج كل خيطٍ منها الاتصال مع برنامج عاملٍ واحد. تُوضِّح الشيفرة الوهمية pseudocode التالية الفكرة العامة للبرنامج main()‎: // أنشِئ المهام التي ينبغي تنفيذها وضفها إلى الرتل create the tasks that must be performed and add them to a queue // إذا لم تُمرَّر أي وسائط بالأمر if there are no command line arguments { // يُنفِّذ البرنامج الرئيسي كل شيء بنفسه Remove each task from the queue and perform it. } else { // تُنفِّذ البرامج العاملة المهام for each command line argument: // احصل على معلومات العامل من وسيط سطر الأوامر Get information about a worker from command line argument. // أنشِئ خيطًا جديدًا وشغِّله لكي يُرسِل المهام إلى البرامج العاملة Create and start a thread to send tasks to workers. // انتظر اكتمال جميع الخيوط Wait for all threads to terminate. } // جميع المهام قد انتهت بفرض عدم حدوث أخطاء تُوضَع المهام بمتغيرٍ اسمه tasks من نوع الرتل ConcurrentBlockingQueue<CLMandelbrotTask>‎؛ وتَقَرأ خيوط الاتصال المهام من ذلك الرتل، وتُرسِلها إلى البرامج العاملة. يُستخدَم التابع tasks.poll()‎ لقراءة مهمةٍ من الرتل؛ فإذا كان الرتل فارغًا، فسيُعيد القيمة null، والتي تُعدّ إشارةً إلى أن جميع المهام قد أُسنَدت بالفعل وأن بإمكان خيط الاتصال أن ينتهي. يتولى كل خيط اتصال مهمة إرسال متتاليةٍ من المهام إلى خيطٍ عاملٍ معين؛ واستقبال النتائج التي يعيدها ذلك الخيط العامل؛ كما أنه مسؤولٌ عن إنشاء اتصالٍ مع الخيط العامل بالبداية. تُوضِّح الشيفرة الوهمية pseudocode التالية الفكرة العامة للعملية التي يُنفِّذها خيط الاتصال: // أنشِئ مقبسًا متصلًا مع البرنامج العامل Create a socket connected to the worker program. // أنشِئ مجرى دخل ومجرى خرج للتواصل مع البرنامج العامل Create input and output streams for communicating with the worker. while (true) { Let task = tasks.poll(). If task == null break; // جميع المهام قد أسنَدت // شفِّر‫ المهمة إلى رسالة وأرسلها إلى البرنامج العامل Encode the task into a message and transmit it to the worker. // اقرأ رد العامل Read the response from the worker. // فك تشفير الرد وعالجه Decode and process the response. } // أرسِل الأمر‫ "close" إلى البرنامج العامل Send a "close" command to the worker. Close the socket. سيَعمَل ذلك بطريقة مناسبة، ولكن هناك بعض الملاحظات: أولًا، يجب أن يكون الخيط مُهيأً للتعامل مع أخطاء الشبكة. على سبيل المثال، قد تُغلَق إحدى البرامج العاملة بصورةٍ غير متوقَّعة، وسيتمكَّن البرنامج الرئيسي من إكمال عمله في تلك الحالة نظرًا لوجود برامجٍ عاملةٍ أخرى. (عندما تُشغِّل البرنامج، يُمكِنك أن تُجرِّب ما يلي: أوقف إحدى البرامج العاملة بالضغط على "CONTROL-C"، وسترى أنه بإمكان البرنامج الرئيسي أن يكتمل بنجاح). تَنشَأ المشكلة إذا حدث خطأٌ بينما يَعمَل الخيط على مهمةٍ معينة؛ ونظرًا لأننا نهدف إلى حل المشكلة كاملةً، لا بُدّ إذًا من إعادة إسناد تلك المهمة إلى برنامجٍ عاملٍ آخر. يُمكِننا تحقيق ذلك بإعادة المهام غير المكتملة إلى رتل المهام. لسوء الحظ، لا يُعالج البرنامج الذي نَستعرِضه هنا جميع الأخطاء المحتملة. على سبيل المثال، إذا فَشَل خيط العامل الأخير، فلن يكون هناك عملاء آخرين نُسنِد إليهم المهام غير المكتملة. علاوةً على ذلك، إذا عُلّقَ الاتصال الشبكي دون أن يُولِّد خطأً فعليًا، سيُعلَّق البرنامج أيضًا نتيجة انتظاره لرد العامل. لا بُدّ لأي برنامج متين أن يجد طريقةً يَكشِف من خلالها عن تلك المشكلة ومن ثم يُعيد إسناد المهمة. ثانيًا، تترك الطريقة الموضحة بالأعلى البرنامج العامل دون أي عملٍ أثناء معالجة البرنامج الرئيسي لرد العامل. سيكون من الأفضل لو أُسندت مهمةٌ جديدةٌ إلى البرنامج العامل قبل معالجة ردّه على المهمة السابقة؛ حيث سيُبقِي ذلك البرنامج العامل مُنشغِلًا؛ كما سيَسمَح بتنفيذ العمليتين على التوازي بدلًا من تنفيذهما على التوالي. بهذا المثال، تستغرق معالجة الرد زمنًا قصيرًا للغاية، ولذلك قد لا يُمثِل ترك العامل منتظرًا أو تشغيله على الفور فارقًا كبيرًا، ولكن ينبغي عمومًا تطبيق التوازي بأقصى قدرٍ ممكن. ألقِ نظرةً على التصور العام للخوارزمية بعد التعديل: try { // أنشِئ مقبسًا متصلًا مع البرنامج العامل Create a socket connected to the worker program. // أنشِئ مجرى دخل ومجرى خرج للتواصل مع البرنامج العامل Create input and output streams for communicating with the worker. Let currentTask = tasks.poll(). // شفِّر‫ `currentTask` إلى رسالة وأرسلها إلى البرنامج العامل Encode currentTask into a message and send it to the worker. while (true) { // اِقرأ الرد من البرنامج العامل Read the response from the worker. Let nextTask = tasks.poll(). If nextTask != null { // أرسل‫ `nextTask` إلى البرنامج العامل قبل معالجة الرد على المهمة `currentTask` // شفِّر‫ `nextTask` إلى رسالة وأرسلها إلى البرنامج العامل Encode nextTask into a message and send it to the worker. } // فك تشفير الرد على المهمة‫ `currentTask` وعالجه Decode and process the response to currentTask. currentTask = nextTask. if (currentTask == null) break; // جميع المهام قد أسنَدت } // أرسِل الأمر‫ "close" إلى البرنامج العامل Send a "close" command to the worker. // أغلق المقبس Close the socket. } catch (Exception e) { // أعِد المهمة غير المكتملة إن وجدت إلى رتل المهام مرة أخرى Put uncompleted task, if any, back into the task queue. } finally { // أغلق المقبس Close the connection. } يُمكِنك الإطلاع على الصنف المتداخل WorkerConnection المُعرَّف بالملف CLMandelbrotMaster.java لترى طريقة تحويل الشيفرة الوهمية السابقة إلى شيفرة جافا. ترجمة -بتصرّف- للقسم Section 4: Threads and Networking من فصل Chapter 12: Threads and Multiprocessing من كتاب Introduction to Programming Using Java. اقرأ أيضًا المقال السابق: الخيوط threads والمعالجة على التوازي في جافا البرمجة باستخدام الخيوط threads في جافا مقدمة إلى الخيوط Threads في جافا كيفية إنشاء عدة خيوط وفهم التزامن في جافا تواصل تطبيقات جافا عبر الشبكة
    1 نقطة
  15. هذا الجزء الثاني من سلسلة من جزأين تتحدث عن الحوسبة السحابيّة. نرجو أن تكون قرأت موضوع تعلم الحوسبة السحابيّة: المتطلبات الأساسيّة، وكيف تصبح مهندس حوسبة سحابيّة قبل قراءة هذا المقال، إذ يحوي المقال السابق معلومات مهمة، وشرحًا للمصطلحات المستخدمة في هذا الموضوع. ينقسم هذا المقال إلى قسمين، يناقش القسم الأول عيوب الحوسبة السحابيّة والمشكلات التي يمكن أن تواجهها، ويعدّ مقدّمة للقسم الثاني. أما القسم الثاني، فيتحّدث عن الانتقال إلى الحوسبة السحابيّة والمزايا والعيوب وسيساعدك على تجهيز خطّة للانتقال الأمثل، بحيث تستفيد من المزايا وتتجنب المساوئ في الانتقال. مقدمة إذا كنت ترغب في تقديم خدمات رقميّة أيًّا كان نوعها، فعليك تقدير كلّ أنواع الموارد، بما في ذلك المعالج والذاكرة والتخزين والشبكة. إن اختيار أيّ الموارد ستستخدم لتقديم تلك الخدمات - سواء سحابيّة أو محليّة - عائد لك. ولكنّك ستحتاج بكل تأكيد للبحث والتخطيط. ستحتاج إلى فهم مزايا وعيوب الحوسبة السحابيّة وكيف تأخذ نقاط ضعفها في الحسبان. لقد أفادت الخدمات السحابية العديد من المؤسسات، وذلك بتقليل التكاليف، وتمكينها من التركيز على الجانب المتعلّق بالأعمال الخاصّة بها، بدلًا من القضايا المتعلّقة بتقنيّة المعلومات والبنية التحتيّة لها. وعلى الرغم من الكثرة الحديث عن أهميتها في الأوساط التقنيّة، إلّا أنّها قد لا تخلو من العيوب، وخاصّة في الأعمال الصغيرة. لدى معظم الشركات حمل واحد على الأقل يعمل في نظام حوسبة سحابية. رغم هذا، فالانتقال إلى الحوسبة السحابيّة قد لا يكون الخيار الصحيح للجميع. وعلى الرغم من أنّ البيئات السحابيّة عامّة تكون قابلة للتوسعة، ويعتمد عليها، ومتاحة دائمًا، يجب أن لا تدع هذه النواحي وحدها تقود قراراتك. بالنسبة للشركات التي تبحث في الانتقال إلى الحوسبة السحابيّة لأوّل مرّة، فهناك الكثير من النواحي التي يجب أخذها بعين الاعتبار؛ مثل الفوائد والمخاطر التي يتضمّنها كل نوع من أنواع الحوسبة السحابيّة المناسبة لشركتك. سنناقش هنا العناصر الأساسيّة التي عليك أخذها بعين الاعتبار عندما تفكّر بالانتقال إلى الحوسبة السحابيّة. سنتحدث عن بعض العيوب الرئيسيّة، وسنعرض بعض النصائح والطرق السليمة لاستخدامها والتي من الممكن أن تستخدمها الفرق التقنية للتعامل مع تلك العيوب. يمكنك صياغة نمط محدّد لهذه العمليّة، وذلك باستخدام توجُّه مُفصَّل ومجهًَز مُسبقًا لفهم أمن الحوسبة السحابيّة. بالنسبة للشركات التي تبحث في الانتقال إلى الحوسبة السحابيّة لأوّل مرّة، فهناك الكثير من النواحي التي يجب أخذها بعين الاعتبار؛ كالفوائد والمخاطر التي يتضمّنها كل نوع من أنواع الحوسبة السحابيّة المناسبة لشركتك. سنناقش في هذا المقال العناصر الأساسيّة التي عليك أخذها بعين الاعتبار عندما تفكّر بالانتقال إلى الحوسبة السحابيّة. توضيح عيوب الحوسبة السحابيّة 1. انقطاع الخِدمة يُعدّ انقطاع الخدمة (downtime) أحد أهمّ عيوب الحوسبة السحابيّة. بما أن أنظمة الحوسبة السحابيّة تعتمد على الإنترنت، فيحتمل حدوث انقطاع في الخدمة في أيّ وقت، ويمكن أن يحدث لأيّ سبب كان. هل يمكن لشركتك أن تتحمل انقطاع الخدمة أو بطئها؟ لقد كلّف انقطاع خدمة الحوسبة السحابيّة التابعة لأمازون (AWS) عام 2017 شركات مساهمة عامّة أكثر من 150 مليون دولار أمريكيّ. للأسف، لا توجد شركة آمنة من هذا، وخاصّة بالنسبة للأعمال الحسّاسة التي لا تتحمل أن تنقطع. في شهري حزيران وتمّوز (5 و6) من عام 2019، تعرّض عدد كبير من الشركات لانقطاع في الخدمة، بما في ذلك Cloudflare (وهو مزوّد خدمة مهمّ لمواقع الإنترنت)، وGoogle، وAmazon، وShopify، وReddit، وVerizon، وSpectrum. أفضل الممارسات لتقليل انقطاع الخدمة المخطط له في بيئة الحوسبة السحابيّة تصميم خدمات متاحة باستمرار مع أخذ الاسترجاع من الكوارث بعين الاعتبار. استفِد من ميزة تعدّد المناطق (multi-availability zones) التي يتيحها مزودو الخدمة السحابيّة في البنية التحتيّة لديك. إذا كانت خدماتك لا تتحمّل انقطاع الخدمة، فخذ بعين الاعتبار نشر خدمتك في عدّة مناطق، مع تدارك آليّ للانقطاعات لتتجنّب انقطاع الخِدمة قدر الإمكان. حدِّد ونفِّذ خطّة للاسترجاع من الكوارث تتوافق مع أهداف مؤسستك لتقليل وقت الاسترجاع من الكوارث قدر الإمكان (RTO) وأهداف نقطة الاستعادة (RPO). خذ بعين الاعتبار تنفيذ خدمة اتصال مخصّصة مثل AWS Direct Connect أو Azure ExpressRoute أو Dedicated Interconnect أو Partner Interconnect. تقدّم هذه الخدمات اتصال شبكة مخصّص بينك وبين مكان وجود الخدمة السحابيّة. يمكن أن يقلِّل هذا من العرضة إلى خطر انقطاع الخدمة المؤقت الذي قد تسببه الإنترنت. اقرأ تفاصيل اتفاقيّة الخدمة (Service Level Agreement - SLA). هل تضمن لك أن تكون الخدمة متاحة 99.9% من الوقت أو حتى أكثر من ذلك؟ هذا الانقطاع الذي يشكِّل 0.1% يساوي 45 دقيقة شهريًّا أو حوالي ثماني ساعات في العام. 2. الأمن والخصوصيّة على الرغم من إنّ مزودي الخدمة ينفذون أفضل معايير الأمن والإجراءات التي يتطلّبها المجال، إلّا أنّ تخزين البيانات والملفات المهمّة عند مزوّدي خدمة خارجيّين يفتح دائمًا المجال للمخاطرة. يجب أن تغطّي أيّ محادثة تتعلّق بالبياناتِ الأمنَ والخصوصيّةَ، وخاصّة عندما يتعلّق الأمر بإدارة البيانات الحسّاسة. يجب أن لاننسى ما حدث لـCode Space واختراق لوحة تحكّمهم على AWS، والذي أدى إلى حذف بياناتهم مما تسبب في أغلاق الشركة. إن اعتمادهم على بنية تحتيّة بعيدة معتمدة على الخدمات السحابيّة يعني المخاطرة بجعل كلّ ما يتعلّق بهم لدى شركة أخرى. إن كلّ مزود خدمة سحابيّة يتوقّع منه إدارة وتأمين البنية التحتيّة العتاديّة التي تقوم عليها الخدمة. وعلى الرغم من ذلك، تقع على عاتقك مسؤوليّة إدارة وصول المستخدمين، ولهذا عليك أن توازن بحذر كلّ حالات الخطر المحتملة. وعلى الرغم من أن الاختراقات التي كشفت معلومات بطاقات بنكيّة ومعلومات الدخول إلى حسابات على الإنترنت لا تزال جليّة في أذهان العامّة، إلّا أنه قد تم اتخاذ إجراءات لتأمين البيانات؟ ومن الأمثلة على هذه الإجراءات القانون العامّ لتأمين البيانات ( General Data Protection Rule - DGPR )، والذي تم سنّه في الاتحاد الأوروبيّ لإعطاء المستخدمين قدرة اكبر على التحكّم ببياناتهم. وعلى الرغم من ذلك، ما زلت بحاجة إلى معرفة المسؤوليات التي تقع على عاتقك، وأن تتّبع أفضل الممارسات المتعلّقة بهذا الشأن. أفضل الممارسات لتقليل مخاطر الأمن والخصوصيّة هذه النقطة مهمّة: افهم نموذج التشارك في المسؤوليّة لدى مزوّد خدمة الحوسبة السحابية الذي تتعامل معه. ستتحمل أنت مسؤولية ما يحدث في داخل شبكتك ومنتجك. نفّذ الإجراءات الأمنيّة في كلّ مستوى من مستويات خدمتك. اعرف من المفترض أن يكون لديه وصول لكل مورِد وخدمة، وقيّد الوصول قدر الإمكان. إذا خان أحد الموظفين الأمانة (أو أخطأ في أمر ما) وكان لديه وصول إلى الخدمة التي تقدّمها، فسترغب بأن تكون الأضرار في أضيق إطار ممكن. تأكّد من أنّ مهارات فريقك ترقى إلى المستوى المطلوب. إن مقال أهم عشرة أشياء يجب على المختصّين في الأمن الإلكترونيّ معرفتها ممتاز لفهم طريقة تجنب المشكلات المتعلّقة بالأمن والخصوصيّة في الحوسبة السحابيّة. اعتمد توجّها مبنيًّا على تقييم المخاطر من أجل تأمين الموارد التي في النظام السحابيّ واجعل سياسة الأمن تشمل الأجهزة. استخدم نظام استيثاق متعدد الجوانب لكل الحسابات التي تصل إلى البيانات الهامّة في النظام. عليك بالتشفير والتعميّة، ثم عليك بالتشفير والتعمية. فعّل التشفير أينما استطعت. الأهداف السهلة للّصوص هي أماكن تخزين الأشياء، وهذا ينطبق على الحوسبة السحابيّة؛ مكان تخزين البيانات مثل Amazon S3 أو Azure Blob Storage هي أماكن تخزين معلومات الزبائن، وهي هدف مهم للمخترقين. إنّ مجرّد تفعيل التشفير على S3 كان سيكفي لمنع الاختراق الذي حصل في شهر تمّوز عام 2019 - لو أنه استُخدِم - والذي كشف بيانات مئة مليون شخص. 3. التعرّض للهجوم إنّ جميع مكونات الحوسبة السحابيّة متّصلة بالإنترنت، مما يجعلها معرّضة للاختراق في حال وجود ثغرات لم يعرف عنها الفريق المسؤول عن النظام أو لم يغلقها؛ بل إنّ أفضل الفرق تعاني من هجمات واختراقات أمنيّة من وقت لآخر. وبما أنّ الحوسبة السحابيّة مبنيّة كخدمة عامّة، فستجد البعض بدأ الركض قبل أن يتعلّم المشي، إذا صحّ التعبير. فعلى أيّ حال، لا أحد من مزودي الخدمات السحابيّة يختبر مدى براعتك في إدارة النظام قبل أن يعطيك خادمًا لتديره: كل ما يُطلب منك هو أن تدفع لاستخدام الخدمة وحسب. أفضل الممارسات للمساعدة في تقليل الهجمات الإلكترونيّة على الخدمة السحابيّة اجعل الأمن محورًا مهمًا لجميع العمليات التقنيّة. ابقِ جميع الفرق التي تعمل معك على اطّلاع على كلّ ما يتعلّق بأفضل الممارسات لأمن الحوسبة السحابية أولًا بأوّل. تأكّد من تفقُّد ومراجعة السياسات والإجراءات الأمنيّة باستمرار. أمِّن سرّيّة المعلومات وقيّد الوصول إليها لتتجنب المشكلة قبل حدوثها. استخدم الخدمات السحابيّة مثل AWS Inspector، وAWS CloudWatch، وAWS CloudTrail، وAWS Config لجعل التحكّم بالالتزام تلقائيًّا. اكتشف المشاريع والاختبارات الخارجة عن أهداف المؤسسة. امنع الدخول باستخدام كلمة المرور عن الحسابات التي لا تحتاج الولوج إلى النظام. غيِّر مفاتيح الوصول وكلمات المرور باستمرار. تابع المدونات والمواقع المتعلّقة بأمن المعلومات وما تعلن عنه لتكون على دراية بالهجمات المعروفة. طبّق أفضل ممارسات الأمن للبرمجيات مفتوحة المصدر التي تستخدمها. نكرر، استخدم التشفير كلّما أمكن وأينما أمكن. ستساعد هذه الممارساتِ المؤسّسةَ على مراقبة حركة البيانات الهامّة ومدى عرضتها للمشكلات الأمنيّة، وستساعدها كذلك على حماية الأنظمة الهامّة من الهجمات والاختراقات، وعلى استيثاق الوصول إلى البنية التحتيّة والبيانات، وذلك من أجل الحماية من المخاطر الإضافيّة المحتملة. 4. الوصول المحدود والمرونة بما أنّ البنية التحتيّة المعتمدة على الحوسبة السحابيّة بأكملها مملوكة ومدارة ومراقبة من مزوّد خدمة الحوسبة السحابيّة، فهي تبقي القليل فقط من التحكّم في يد الزبون. قد يجد مستخدمو الحوسبة السحابيّة أنّ التحكمَ الذي لديهم في الوظائف والتنفيذ للخدمات في البنية التحتية المستضافة سحابيًّا محدودٌ، وذلك بدرجات متفاوتة، حسب الخدمة التي يقدّمونها. قد تقيّد اتفاقية استخدام الخدمة السحابيّة والسياسات الإداريّة ما يمكن للزبائن فعله بتطبيقاتهم. يحتفظ الزبائن بحقّ التحكّم بتطبيقاتهم وبياناتهم وخدماتهم، ولكن قد لا يكون لديهم نفس القدر من التحكم فيما يتعلّق بالبنية التحتيّة للنظام الخلفيّ وبما يجري خلف الكواليس. أفضل الممارسات لضمان قدرٍ من التحكّم والمرونة خذ بعين الاعتبار الاستفادة من شريك يقدّم خدمة الحوسبة السحابيّة ليساعدك على تنفيذ وتشغيل ودعم خدمات الحوسبة السحابيّة. افهم مسؤوليّاتك ومسؤوليّات مقدّم الخدمة السحابيّة في نموذج المسؤوليّة المشتركة، وذلك من أجل الحدّ من التنصّل من المسؤوليّة وكذلك للحدّ من الأخطاء المحتملة. خذ الوقت الكافي لفهم مستوى الدّعم الأساسيّ الذي يقدّمه مزوّد الخدمات السحابيّة الذي تتعامل معه. هل يفي هذا المستوى من الخدمة بمتطلّباتك؟ يقدّم مزودو خدمة الحوسبة السحابيّة دعمًا إضافيًّا فوق الدعم الأساسيّ مقابل تكلفة إضافيّة. تأكّد من فهمك لاتفاقيّة مستوى الخدمة (Service Level Agreement - SLA) المتعلّقة بالبنية التحتيّة والخدمات التي ستستخدمها وكيف ستؤثّر الاتفاقيّة على زبائنك. 5. البقاء عالقًا عند مزوّد معيّن من العيوب التي تُأخذ بالحُسبان عند التعامل مع الحوسبة السحابيّة هي احتمال أن تبقى عالقًا عند مزوّد خدمة سحابيّة معيّن. إن الانتقال بسهولة بين مزودي الخدمة السحابيّة لم يصل إلى المستوى المطلوب من التطور، وقد تجد المؤسسات صعوبة في نقل خدماتها من مزوّد خدمة إلى آخَر.قد تنشأ صعوبات نتيجة للاختلاف بين مزودي الخدمة مما قد يتسبب بتكاليف إضافيّة وتعقيدات في الإعداد. إنّ الفجوات التي يمكن أن يتسبب بها الانتقال من مزوّد إلى آخر من شأنها أن تؤدي إلى تعريض أمن وخصوصيّة البيانات إلى الخطر. أفضل الممارسات لتقليل الاعتماد على مزوّد الخدمة صمِّم نظامك بما يتوافق مع أفضل ممارسات هندسة الحوسبة السحابيّة. تتيح كلّ خدمات الحوسبة السحابيّة فرصًا لتحسين الإتاحة والأداء، وفصل الطبقات المختلفة، والحدّ من عنق الزجاجة في الأداء. إذا بنيت خدماتك بما يتوافق مع أفضل ممارسات هندسة الحوسبة السحابيّة، فسيقل احتمال أن تواجه مشكلات تتعلق بالانتقال من منصّة حوسبة سحابيّة إلى أخرى. افهم جيدًا ما يسوّقه لك مزودو الخدمة لتتجنّب أن تعلق عندهم. طبّق استراتيجيّة تعدد السحابات لتجنب أن تعلق عند مزود خدمة معيّن. على الرغم من أن هذا قد يتسبب بتعقيدات في كلّ من التطوير والتشغيل، إلّا أنها لن تكون بالضرورة معقدة لدرجة أن تثنيك عن ذلك. يمكن تدريب الفرق لتكون مستعدّة لهندسة واختيار أكثر التقنيات والخدمات اتساقًا مع احتياجاتك. اتبع سياسة المرونة المضمّنة عندما تصمِّم تطبيقات، وذلك من أجل جعلها قابلة للنقل في أيّ وقت. ابن تطبيقاتك مستخدمًا الخدمات التي تقدّم ميزة الاستفادة من مزايا الحوسبة السحابيّة كإحدى أولويّاتها، كأن تتكون من برمجيّات وخدمات مصغّرة ومجزّأة وقابلة للنقل. فكّر باستخدام الحاويات وKubernetes. 6. القلق من ارتفاع الكلفة يمكن أن يُنظَر إلى اعتماد حلول الحوسبة السحابيّة على نطاق ضيّق ولمشاريع قصيرة الأمد على أنّها مكلفة. رغم هذا، تنبع أهمّ فوائد الحوسبة السحابيّة من إمكانيّة خفض التكلفة. يمكن أن تقدِّم خدمات الدفع حسب الاستخدام مرونة أكثر وتكلفة عتاد أقلّ، ولكن قد ينتهي المطاف بفاتورة عليها رقم أكبر من المتوقّع. إلى أن تتأكّد من ما يناسبك، يُنصَح بأن تجرّب عددًا من العروض. يمكنك أيضًا استخدام حاسبة التكلفة التي يقدّمها مزودو الخدمة، مثل AWS و Google Cloud Platform. أفضل الممارسات لخفض التكلفة حاول أن لا تحدّد مدى استخدام خدماتك، بل ابحث عن الخدمات المتغيّرة ذاتيًّا حسب الاستخدام. تأكّد من إمكانيّة تقليل مواصفات الخدمة بقدر إمكانيّة زيادتها. ادفع مسبقًا واستفد من الخدمات المحجوزة إذا كنت تعلم الحدّ الأدنى لاستخدامك. اضبط خدماتك لتبدأ وتتوقّف آليًّا لتوفير المال عندما لا تستخدمها. أنشئ تنبيهات لتتبّع نفقات الحوسبة السحابيّة. الفوائد المحتملة للانتقال إلى الحوسبة السحابيّة العديد من المشاكل يمكن حلّها بالانتقال إلى الحوسبة السحابيّة. فيما يلي بعض الحالات التي يمكن أن تستفيد فيها من الانتقال. يواجه تطبيقك ازديادًا في كميّة البيانات المارّة فيه، مما يصعّب زيادة الموارد لحظيًّا لتناسب الطلب. تحتاج إلى تقليل التكلفة التشغيليّة بينما تزيد كفاءة تقنية المعلومات. يتطلب زبونك تنفيذًا ونشرًا سريعين للتطبيق، ولهذا يريد تطويرًا أكثر وتقليلًا للتأخير الذي قد ينشأ من البنية التحتيّة. يريد زبائنك توسيع أعمالهم جغرافيًّا، ولكنك تعتقد بأن تجهيز بنية تحتيّة متعدّدة الأقاليم سيكون تحدّيًا كبيرًا، وذلك لما فيه من مجهود متعلّق بالإدارة والوقت والكوادر البشريّة والسيطرة على الأخطاء. مواكبة النمو المتزايد للاحتياج إلى تخزين البيانات صارت أكثر صعوبة وتكلفة. تحتاج إلى بناء فريق تطوير موزّع جغافيًّا. تسمح بيئة الحوسبة السحابيّة للموظفين البعيدين الوصول إلى التطبيقات واستخدامها عبر الإنترنت. تحتاج إلى تأسيس نظام استرجاع من الكوارث ولكن تجهيزه لمركز بيانات بأكمله قد يضاعف التكلفة، وسيحتاج أيضًا إلى خطة معقّدة للاسترجاع من الكوارث. يمكن تطبيق أنظمة الاسترجاع من الكوارث المعتمدة على الحوسبة السحابيّة أسرع، وستعطيك تحكّمًا أفضل بكثير بالموارد التي لديك. تتبُّع وتطوير البرمجيات التي يحويها الخادم يأخذ وقتًا، ولكنه مهم، ويحتاج إلى تطوير دوريّ وأحيانًا فوريّ, سيهتم مزود خدمة الحوسبة السحابيّة بهذا الأمر في بعض الأحيان تلقائيًّا. وكذلك، تهتم بعض نماذج الحوسبة السحابية ببعض الأمور الإدارية كالنسخ الاحتياطيّ لقواعد البيانات وتحديث البرمجيّات والصيانة الدوريّة. تكلفة رأس المال والتكاليف التشغيليّة: تحوِّل الحوسبةُ السحابيّةُ تقنيةَ المعلوماتِ إلى نموذج الدفع مقابل الاستخدام، وهي ميزة مغريةٌ وخاصّةً للشركات الناشئة. المخاطر المحتملة نتيجة الانتقال إلى الحوسبة السحابيّة رغم أن المخاطر التي تنطبق على كلّ حالة تعتمد كثيرًا على طبيعة البيئة المراد نقلها، إلّا انّ هناك عيوب عامّة تتعلق بالانتقال إلى الحوسبة السحابيّة التي عليك أخذها بعين الاعتبار. إذا كان تطبيقك يخزّن ويسترجع بيانات حسّاسة جدًّا، فقد لا تتمكن من إبقائها في النظام السحابيّ. وكذلك قد تحُدّ متطلّبات التوافق خياراتك. إذا كان الإعداد الموجود لديك من قبل يفي باحتياجاتك، ولا يحتاج الكثير من الصيانة والتحجيم والإتاحة، وكان جميع زبائنك راضين عنه، فلِمَ تعبث به؟ إذا كانت بعض التقنيات التي تعتمد عليها حاليًّا مملوكة، فقد لا يُسمَح لك قانونًا بنشرها على نظام سحابيّ. قد تعاني بعض العمليات من تأخير إضافيّ عند استخدام تطبيقات سحابيّة عبر الإنترنت. إذا كان العتاد بين يدي شخص آخر أو جهة أخرى، فقد تخسر الشفافية والتحكم اللازمين لتتبع مشاكل الأداء. قد يسبب "الجيران" في بعض الأحيان "إزعاجًا" عبر الموارد المشتركة (الإنترنت). قد لا يتبع تتصميم ومعمارية تطبيقك معمارية الحوسبة السحابيّة الموزّعة، ولهذا قد يتطلّب بعض التعديلات قبل نقلها إلى الحوسبة السحابيّة. البقاء عالقًا عند مزود خدمة سحابيّة معيّن: قد يكون من الصعب المغادرة أو الانتقال إلى منصّة سحابيّة أخرى بمجرد أن تبدأ باستخدام بيئة سحابيّة معيّنة. انقطاع الخدمة: يحدث هذا للجميع، ولكنك قد لا ترغب بأن تكون الأمور بيد شخص آخر. باتّباع هذا الأسلوب في التفكير، إذا كنت تفكّر بنقل أعمالك إلى الحوسبة السحابيّة، فقد تسأل نفسك عن العثرات الشائعة التي يمكن أن تواجهها عند النقل. ما نموذج الحوسبة السحابيّة الذي تحتاجه؟ إذا كنت قررت تجربة الحوسبة السحابيّة، فسيكون عليك اختيار نموذج الحوسبة السحابيّة الذي من الممكن ان تستخدمه. فيما يلي أكثر هذه النماذج شيوعًا: البنية التحتيّة كخدمة: Infrastructure as a Service (مثل AWS، وAzure، وGoogle Cloud، و Alibaba Cloud). المنصّة كخدمة: Platform as a Service (مثل AWS Elastic، وBeanstalk، وHeroku، وGoogle App Engine، وEngine Yard). البرنامج كخدمة: Software as a Service (مثل Google G Suite، وOffice 365، وSalesforce، وNetSuite). وهنا يكمن قرار مهمّ عليك اتّخاذه. النوع الأول هو الأفضل للشركات التي لا مانع لديها من استضافة تطبيقاتها في مراكز بيانات شركة أخرى، وتفضِّل أن يهتم غيرها بالبنية التحتيّة العتاديّة لتركّز بالكامل على تطوير ونشر ومتابعة تطبيقها. رغم هذا، إذا كنت تفضّل أن تكون تطبيقاتك قابلة للنقل، فقد ترغب في أن تضع البرمجية في منصّة PaaS متينة تقدّم بيئة بنية تحتيّة كاملة (وواضحة). إنّ تبّني PaaS سيقلّل أيضًا الوقت الذي تحتاجه لتكون جاهزًا للسوق - وذلك لأنها ستكون مجهّزة مسبقًا بمعظم المتطلّبات اللازمة لتشغيل برمجيّاتك. ستحتاج إلى نشر أعلى طبقة في تطبيقك فقط، وفي بعض الأحيان التطبيق نفسه وحسب. أمّا عن SaaS، فهو نموذج توصيل محتوى تكون البرمجيات الانتاجيّة فيه مستضافة مركزيًّا ومرخّصة حسب الاشتراك. فيما يلي جدول يوضّح ما توفّره كلّ من النماذج الثلاثة المذكورة أعلاه. IaaS PaaS SaaS تخزين البيانات منصّة التطبيق برنامج إدارة الزبائن الأجهزة الظاهريّة قاعدة البيانات إدارة الأعمال نظام توصيل محتوى التطوير الأمن الشبكة التكامل الأدوات الحوسبة table { width: 100%; } thead { vertical-align: middle; text-align: center; } td, th { border: 1px solid #dddddd; text-align: right; padding: 8px; text-align: inherit; } tr:nth-child(even) { background-color: #dddddd; } خاصّة أم عامّة أم هجينة؟ لنفترض أنّك اخترت نموذجًا سحابيًّا، وقد حان الوقت لاختيار النوع. لديك ثلاثُ خيارات أساسيّة: عامّ: جميع الموارد التي لديك مستضافة بالكامل لدى واحد أو أكثر من مزودي خدمة الحوسبة السحابيّة، مثل AWS، Azure، GCP، Alibaba، DigitalOcean، …إلخ. خاصّ: تُنشئ نظام الحوسبة السحابيّة الخاصّ بك بنفسك باستخدام منصّة مثل OpenStack أو VMWare vCloud. هجين: مواردك موزّعة على منصات خاصّة وعامّة، مع اتصالات بينها تتابعها أنت. يمكن أن يكون الخيار الهجين جذّابًا بسبب مزجه الجيد لكل من الاستخدام عند الطلب والاستقرار والإتاحة الدائمة والأمن والتكلفة التشغيلية القليلة. باستخدام هذا النوع يمكنك أن تجمع بين مزايا النوعين. سنشرح فيما يلي كيف تعمل الحوسبة السحابيّة الهجينة في شركة معيّنة. لنتخيّل أنّ تطبيقك المبنيّ للإنترنت يزدهر من ناحية الشعبية وعدد المستخدمين. ستحتاج إلى الموارد اللازمة للتوسعة باستمرار، وذلك من أجل أن تواكب الطلب المتزايد عليه. يجب أن تتمكن من زيادة الموارد المستخدمة إلى أقصى حدّ عندما يصل الاستخدام حدّه الأقصى، وأن تقلل تلك الموارد عندما لا تحتاجها وذلك لخفض التكلفة. يمكن فعل ذلك في الحوسبة السحابيّة العامّة. افترض بأن البيانات التي يجعمها تطبيقك سرّيّة جدًّا، ولا يمكن تخزينها خارج نطاق المؤسّسة. وهنا يمكن أن نستفيد من النوع الهجين. يمكنك في هذه الحالة أن تختار الأجزاء التي يمكنها أن تسكن السحابة العامّة، والأجزاء التي ستبقى في مركز البيانات عندك. يقول موقع RightScale في تقرير له أنّ الشركات تتبنى استراتيجيّة تعدد مزودي الخدمة 84%، وأنّ 58% منها تخطط لاستخدام حوسبة سحابيّة هجينة. تقييم التطبيقات للنقل إلى الحوسبة السحابيّة ما إن تختار النموذج والنوع، يبدأ التحدّي الحقيقيّ. لقد حان الوقت لنرى إذا كانت التطبيقات التي لديك جاهزة للنقل إلى الحوسبة السحابيّة. فيما يلي بعض العوامل التي عليك أخذها بعين الاعتبار: تعقيد تصميم التطبيق بعض التطبيقات القديمة معقدة جدًا ومترابطة داخليًّا إلى حد بعيد، مما يجعل مستخدميها غير راغبين في إعادة برمجتها. رغم هذا، فالمتطلب الرئيسيّ لأي انتقال ناجح هو أن تتبع التطبيقات معمارية موزعة، ويجب أن تكون من أساسها قابلة للتحجيم. يمكن لأدوات مثل PaaSLane و Cloudamize أن تساعدك على تقييم إلى أيّ مدى تطبيقاتك جاهزة لنقلها إلى منصّة سحابيّة. إنّ خدمة AWS’s Migration Hub تحوي كلّما تحتاجه من أدوات لاكتشاف وتقييم ذلك. تعقيدات التكامل لكل تطبيق نقاط تكامل، كبوابات الدفع، وخوادم البريد، وخدمات الويب، والتخزين الخارجي، والمزودين الخارجيين. من الضروريّ جدًّا تحليل أثر الانتقال إلى الحوسبة السحابية على هذه الاعتماديات. ستواجه في بعض الأحيان تحديات غير متوقعة تتعلق بالاتصال والاستيثاق، وعليك تحديدها وحلّها قبل حدوثها. أكثر المهام أهميّة (ومللًا) تحديد كلّ نقاط التكامل هذه. وبما أن التطبيقات القديمة قد يكون توثيقها ضعيفًا، وقد يكون المطورون الملمّون بتفاصيلها غير متاحين، فقد تحتاج إلى تفقّد أجزائها كلّها يدويًّا. تزداد المهمّة تعقيدًا إذا كنت تفكّر بترحيل مئات التطبيقات التي تعمل حاليًّا في مركز البيانات لديك. يمكن مواجهة العديد من هذه التحديات بالاعتماد على معرفة فريقك للتطبيقات، وعلى أداة اكتشاف الموارد (سواء مفتوحة المصدر أو تجارية). يمكن لأداة اكتشاف الموارد مساعدتك على تحديد كلّ إعدادات الخوادم في شبكتك، بما في ذلك تفاصيل الاتصال. على سبيل المثال، لنقل أن لديك مركز بيانات فيه شبكة تستضيف مئة تطبيق. يمكن لأداة الاكتشاف تلك أن تقدم لك نظرة عامّة للنظام بأكمله. ويمكنها أيضًا أن تعطيك تفاصيل متفرقة يمكنها مساعدتك في تقييم إدارة السعة العامّة (general capacity management، مصطلح إداريّ). من أدوات اكتشاف الموارد المعروفة BMC Atrium و HP DDMA. تقدّم Cloudamize أداة يمكنها اكتشاف التطبيقات والأجهزة آليًّا، ويمكنها أيضًا عمل خرائط باعتماديات التطبيقات آليًّا، وذلك من أجل اكتشاف الاعتماديات بين التطبيقات. نظام التشغيل المضيف ما إن تقرّر الانتقال إلى الحوسبة السحابيّة، من الضروريّ أن تعلم إذا كان باستطاعتك نشر تطبيقك على نفس نظام التشغيل. يمكن أن يعمل تطبيقك على نظام تشغيل محدّد (أو إصدار محدّد من نظام التشغيل). إذا لم يكن هذا النظام متوافقًا مع مزود الخدمات السحابيّة، فسيكون عليك أن تجد نظام تشغيل بديل يمكن استخدامه، أو مزود خدمات سحابيّة آخر، أو أن تلغي مشروع النقل من أساسه. على سبيل المثال، لا يتيح معظم مزودي الخدمات السحابيّة خيارات لأنظمة تشغيل 32بت، وقد يكون لدى البقيّة متطلّبات اشتراك غير متوقّعة. من الضروريّ أن تجري بحثًا في هذا الأمر قبل التخطيط للنقل. قاعدة بيانات التطبيق من المعروف أن قاعدة البيانات جزء هامّ من أيّ تطبيق. يستثمر الزبائن كثيرًا في خوادم قواعد البيانات، وغالبًا في تراخيصها أيضًا. إضافة إلى ذلك، قد لا ترغب في نقل قواعد البيانات الآن، وذلك بسبب تعقيدها وحساسيّة البيانات التي فيها، كما أن نقل كميات ضخمة من البيانات ليست بالأمر السهل. في جميع الأحول، عليك أن تتأكد من أن طرق النقل التي ستستخدمها يمكن الاعتماد عليها إلى حدّ بعيد، ويمكن كذلك عكسها في حال حصول مشكلة كبيرة غير متوقّعة. يوفّر معظم مزودي الخدمات السحابيّة أدوات نقل خاصّة بهم. ولهذا من الضروريّ أن تقيّم هذه الخدمات قبل أن تضغط زرّ البدء. فمثلًا، تقدم AWS خدمة Migration Hub، والتي - على حد تعبيرهم - "تسهّل وتسرّع الاكتشاف والنقل من مراكز بياناتك إلى AWS Cloud". وهناك العديد من من مزودي خدمة نقل البيانات كطرف ثالث، مثل Attunity CloudBeam، وATADATA ATAmotion، وCloudEndure Live Migration، وRacemi DynaCenter. الشبكة لا تدعم معظم بيئات الحوسبة السحابيّة ميزة multicasting، ولهذا إذا كان تطبيقك يعتمد على هذه الميزة، فعليك أن تفكّر جيدًا قبل أن تخطو أيّ خطوة. موازنة الأسعار لدى العديد من مزودي الخدمات السحابيّة حاسبات تكلفة من شأنها أن تساعدك على تقدير التكاليف الحقيقيّة التي ستواجهها عند الانتقال إلى الحوسبة السحابية، ومقارنتها بالتكلفة الحاليّة، ومنها AWS TCO (Total Cost of Ownership) calculator و Azure Pricing Calculator. يسمح لك موقع Cloudamize بمقارنة التكاليف لدى كلّ من AWS وAzure و Google Cloud Platform (GCP)، بحيث يمكنك من الاختيار بينها بما يتوافق مع مدى الحمل الذي يقوم به تطبيقك. إثبات المفاهيم (Proof of Concept) من الأفكار الرائعة دائمًا بناء "إثبات للمفاهيم" (أي تجربة الأمر عمليًّا على نظام بديل ومنفصل عن النظام الحقيقيّ الذي تستخدمه، وذلك للتأكد من أن كل شيء يعمل كما يجب) على نطاق صغير قبل نقل التطبيق الحقيقيّ إلى الحوسبة السحابيّة. لن تتوقع هذه النماذج كل المشاكل التي يمكن أن تحصل، ولكنها ستوضّح التحديات التي يمكن أن تواجهها بوضوح أكثر، وستساعدك على فهمها. من الأمور التي عليك البحث فيها أثناء تنفيذ هذه الخطوة: مقارنة الأداء مع التطبيق الموجود فعليًّا. مستويات التعقيد أثناء ترحيل التطبيق. التحديات المتعلقة بالشبكة والتي يجب العمل على حلّها. إمكانيّة الاعتماد عليها. تقييم دعم مزود الخدمة. خُلاصة القول تستفيد العديد من المؤسسات من المرونة التي تقدّمها خدمات الحوسبة السحابيّة، فيما يتعلّق بإمكانية تشغيلها وإيقافها وتغيير حجمها ومزاياها والدفع حسب الاستخدام. رغم هذا، وكما في أيّ خدمة بنية تحتيّة، يجب عليك تقييم مدى ملاءمة الحوسبة السحابيّة لحالة الاستخدام لديك تحديدًا، وذلك لعمل تقييم مبني على المخاطر المحتملة (risk-based evaluation). خصِّص وقتًا للبحث والتخطيط لتفهم كيف ستؤثِّر الحوسبة السحابيّة في أعمالك. لا يمكن حصر كلّ التحديات التي يمكن أن تواجهها عند النقل في مقال واحد، ولكننا حاولنا هنا الوقوف على بعض المشاكل الشائعة التي يجب أن تأخذها بعين الاعتبار قبل بدء هذا العمل. شاركنا تجربتك في نقل عملك إلى الحوسبة السحابية في التعليقات. ترجمة -وبتصرف- للمقالين: Disadvantages of Cloud Computing لصاحبه Andrew Larkin. Cloud Migration Risks & Benefits لصاحبه Jeremy Cook.
    1 نقطة
  16. هذا المقال هو الجزء الأول من جزأين يشرحان موضوع الحوسبة السحابيّة. يناقش هذا المقال المتطلبات المسبقة وما تحتاج إلى معرفته قبل بدء رحلتك في الحوسبة السحابية. ويناقش كذلك بعض الافتراضات الخاطئة المتعلقة بالحوسبة السحابية، ويعمل على تصحيح المفاهيم المتعلقة بها، كما ويوضح مفهومي الأجهزة الافتراضيّة (الأجهزة الظاهريّة)، والحوسبة السحابيّة العامّة والخاصّة. ومن ثمّ يناقش أحد المفاهيم المتعلّقة بالحوسبة السحابية والتي تتردّد كثيرًا، وهو مفهوم "مهندس حوسبة سحابية" (Cloud Architect)؛ سنناقش في هذا المقال ما يقوم به مهندس الحوسبة السحابية، وسنحلّل المهارات والشهادات اللازمة لتصبح مهندس حوسبة سحابيّة. وسنذكر كذلك بعض أنواع الوظائف المتاحة إذا قرّرت جعل هذا المجال حرفتك. المتطلبات المسبقة لتعلم الحوسبة السحابية يسأل العديد من المهتمين: "ما المتطلبات والمعرفة المسبقة اللازمة لبدء تعلم الحوسبة السحابية؟" سنعطي - في هذا المقال - المعلومات اللازمة للإجابة على هذا السؤال، لتكون جاهزًا لبدء تعلم الحوسبة السحابية دون قلق. يشير مفهوم الحوسبة السحابية إلى مجال واسع من تقنية المعلومات تشمل: البنية التحتية العتادية، والبنية التحتية البرمجية، ومنشآت مراكز البيانات (data centers)، وتقنيات الأجهزة الافتراضية (أو الأجهزة الظاهرية - Virtualization)، ومفاهيم هندسة البرمجيات. كلّ هذه المجالات متصلة ببعضها وتوفر لك معرفة أولية جيدة تسهّل عليك رحلتك في استكشاف وتعلّم استخدام منصات الحوسبة السحابية والعمل فيها؛ ولكننا سنركّز في هذا المقال على مزودي خدمة البنية التحتية السحابية (Infrastructure as a Service - IaaS)، مثل خدمات أمازون (Amazon Web Services - AWS)، و Microsoft Azure، و Google Compute Engine و Rackspace Cloud، وكذلك على مزودي خدمة المنصة السحابية (Platform as a Service - PaaS)، مثل Salesforce.com، و Microsoft Azure، و Google App Engine. يمكننا البدء بافتراض أنّك لن تحتاج شهادة جامعية في أحد مجالات الحاسوب لتعلم الحوسبة السحابية. يمكنك بدء تعلم الحوسبة السحابية من الصفر حتى وإن كانت مهاراتك في تقنية المعلومات بسيطة جدًّا. افتراضات مغلوطة عن الحوسبة السحابية 1. لتعلم الحوسبة السحابية يجب أن تجيد البرمجة يمكنك أن تبدأ تعلم الحوسبة السحابية باستخدام خدمة حوسبة سحابية - عامّة أو خاصّة - حتّى وإن لم تكن مطوّر برمجيات. 2. يجب أن تكون لديك خبرة سابقة في عالم تقنية المعلومات الحوسبة السحابية تقنية مستخدمة في كل المجالات وحول العالم، ومن شأن فهمها أن يساعد الجميع، وليس فقط ذوي الاهتمامات التقنيّة؛ بل غالب الظنّ أنك تعمل في مؤسّسة تستخدم الحوسبة السحابية بالفعل. 3. الحوسبة السحابية فقط للتقنيين ومطوري البرمجيات إنّ الحوسبة السحابيّة تغيّر طريقة بناء الشركات لأنظمة المعلومات لديها، وكيفية استخدامها لها، بما في ذلك كلّ برمجياتها، ويجب على المدراء، والمسوّقين، ومدراء الأنظمة، والمطورين تعلّمها؛ ولكن - بالطبع- بتوجّهات مختلفة، مركّزين على الجوانب المتعلّقة بأدوارهم ومسؤوليّاتهم. أنظمة التشغيل والأجهزة الافتراضيّة والشبكة بما أنّ الحوسبة السحابية مجالها واسع، لكي تتعلّم الحوسبة السحابية تحتاج لبعض المهارات تتعلق بالمفاهيم الأساسيّة لأنظمة التشغيل وكيف تعمل (دون الخوض في تفاصيلها الدقيقة)، مثل Windows ولينُكس ومفاهيم بسيطة تتعلّق بهما. إذا كانت معرفتك جيدة في هذه الأمور، فأنت تعرف أنّ التقنيات المتعلّقة باستخدام الأجهزة الافتراضيّة (أو الأجهزة الظاهريّة Virtualization) لها دورً مهمّ عندما نتحدّث عن الحوسبة السحابيّة. لا توجد تجربة تضاهي تشغيل جهاز افتراضيّ بنفسك (يمكنك فعل ذلك باستخدام VirtualBox) لتفهم كيف تعمل بيئة الأجهزة الافتراضيّة. تمكّنك هذه التقنيّات من إنشاء بيئة ظاهريّة تحدّد فيها عدد وسرعة المعالجات المركزية (CPU) والذاكرة الرئيسيّة (RAM) ومساحة التخزين، وكذلك نظام التشغيل الذي يعمل عليها مثل Windows أو Linux. تتشارك الأجهزة الافتراضيّة في العتاد الحقيقيّ وأجهزة الشبكة ولكنّها منفصلة عن بعضها. من أوائل الشركات الرائدة في هذا المجال شركة تُدعى VMWare. لقد كانت الحوسبة الظاهريّة (أو الأجهزة الافتراضيّة) معروفة جيّدًا قبل VMWare، ولكنّ هذه الشركة غيّرت السوق المتعلّق بها، حيث حوّلت هذه التقنيّة إلى حزمة برمجيّة جاهزة للاستخدام ممّا جعلها شائعة في الشركات صغيرة كانت أم كبيرة. لقد قدّمت هذه التقنيّة مفهومًا اقتصاديًّا واستراتيجيًّا جديدًا، وهو Consolidation، ويعني حرفيًّا الدمج أو الجَمع، ويشير إلى جمع أكثر من خدمة وأكثر من جهاز افتراضيّ على جهاز حقيقيّ واحد. ويعني هذا أن الشركات حول العالم لم يعد واجبًا عليها توفير خادم حقيقيّ لكل نوع من التطبيقات أو الأحمال التي يشغّلونها، بل صار بإمكانهم مشاركة الموارد وتقسيمها بين عدد من الأجهزة الافتراضيّة. مفاهيم أساسيّة عليك معرفتها عن الأجهزة الافتراضيّة Hypervisor: هو قلب نظام الأجهزة الافتراضيّة والذي يشغّل كلّ الأجهزة الافتراضيّة. ومن الأمثلة عليه VMWare وKVM وXen و OpenVZ. تستخدم كلّ بيئات الحوسبة السحابيّة hypervisor معدّل. أمازون مثلًا تستخدم Xen. الجهاز الافتراضيّ (أو الجهاز الظاهريّ، وبالإنجليزيّة: Virtual Machine): وهو العنصر الأساسيّ في هذه التقنيّة. اعلَم أنّ للجهاز الافتراضيّ نظام تشغيل ومعالج وذاكرة وقرص تخزين والعديد من الإعدادات المتعلّقة بالشبكة. مزايا استخدام الأجهزة الافتراضيّة: الجَمع (جمع أكثر من جهاز على عتاد واحد)، وإمكانيّة نقل الأجهزة الافتراضيّة بين الخوادم الحقيقيّة (والتي تسمّى أيضًا بالعُقَد physical nodes)، والمرونة في إضافة موارد جديدة إلى جهاز افتراضيّ موجود. ما إن تصبِح ملمًّا بأساسيّات تقنيّات الحوسبة الظاهريّة (الأجهزة الافتراضيّة) وأنظمة التشغيل، فعليك بأخذ مساق مقدمة في الشبكات، ومن ثمّ ستتعلّم الحوسبة السحابية بسهولة. يمكن أن يكون مجال الشبكات صعبًا، وسيحتاج حتّى ذوو المهارات العالية بعض الوقت لفهمه بالكامل. راجع القسم المتعلّق بالشبكات في هذا المقال لفهم المتطلبات اللازمة للخوض في هذا المجال. وفي النهاية، نريد تكوين فكرة واضحة عن معنى كلّ من الحوسبة السحابيّة العامّة والخاصّة. السحابة العامّة: تشير إلى البنية التحتية التي من الممكن للعموم الوصول إليها وتخزين بيانات وأجهزة افتراضيّة وأيّ نوع من الموارد السحابيّة. يمكنك استخدامها بنفسك، ولست بحاجة إلى الاستثمار في العتاد والبنية التحتيّة من أجل ذلك. يمكنك استخدام السحابات العامّة والدفع حسب الاستخدام. وهذا يشبه استئجار السيّارة لمدّة معينة من الوقت بدلًا من شرائها وامتلاكها. السحابة الخاصّة: تحتاج الشركات إلى كلّ المرونة والمزايا التي تقدمها الحوسبة السحابيّة، ولكن قد تكون لديها بنيتها التحتيّة ومركز البيانات (data center) الخاصّ بها. في هذه الحالة، تكون الشركة مسؤولة عن إدارة كلّ شيء فيها. ما هي هندسة الحوسبة السحابيّة يشير مفهوم معمارية الحوسبة السحابيّة (أو هندسة الحوسبة السحابيّة) إلى المكوّنات الرئيسيّة والفرعيّة التي تحتاجها الحوسبة السحابيّة. وتتكون هذه المكوّنات عادة من منصّة الواجهة، والمنصّة الخلفيّة، ونظام التوصيل السحابيّ للمحتوى (cloud-based delivery) والشبكة. وتشكّل هذه المكوّنات مجتمعة معماريّة الحوسبة السحابيّة. ويعتمد تصميم حلول الحوسبة السحابيّة على أساليب وإجراءات هندسيّة تمّ تطويرها على مدى العقدين الماضيين. مهندس الحوسبة السحابية مسؤول عن تحويل المتطلبات التقنيّة للمشروع إلى معماريّة وتصميم يوجّهان سير العمل للوصول إلى المنتج النهائيّ. وغالبًا يكون مهندس الحوسبة السحابية مسؤولًا أيضًا عن رأبِ الصدعِ بين المشكلات المركّبة المتعلّقة بالأعمال وبين الحلول المعتمدة على الحوسبة السحابيّة. ويعمل الأعضاء الآخرون في الفريق التقنيّ - بما فيهم مهندس دعم المطورين DevOps والمطورون - مع مهندس الحوسبة السحابيّة للتأكد من بناء الحلّ أو الحلول التقنيّة المناسبة. ما المهارات المطلوبة في البداية؟ إذا كنت تفكر بأن تغدو مهندس حوسبة سحابية، فيفترض بأن لديك بالفعل معرفة مسبقة قويّة في الحوسبة السحابيّة أو مجال تقنيّ مشابه. إذا كنت ترى المفاهيم التالية مفهومة بالنسبة لك، أو على الأقل بعضها، فغالبًا أنت على الطريق الصحيح. أمّا إذا لم تكن كذلك، فأنصحك أوّلًا بدراسة أو العمل في مجال قريب قبل أن تسعى إلى أن تغدو مهندس حوسبة سحابيّة. معرفة جيّدة في واحد من أنظمة التشغيل على الأقل: لينُكس، يونكس، سولاريس، أو ويندوز. ما أنصحك به هو نظام التشغيل لينُكس بأيّ من توزيعاته (سواء بتوزيعة دبيانيّة أو ردهاتيّة أو غيرها). وجود خبرة مسبقة كمدير نظام أو مهندس نظم لأيّ من أنظمة التشغيل المعروفة قد يفيدك أيضًا. فهم جيّد في الشبكات: TCP/IP و HTTP و DNS. أقترح أن تتعرف على المفاهيم المتعلقة بها قبل السعي لأن تصبح مهندس حوسبة سحابية. لغة برمجة: ستحتاج على الأقل إلى فهم بسيط للغة برمجة مفسّرة (scripting language). غالبًا هذا ليس إلزاميًّا، ولكنه بكل تأكيد سيفيدك. الأمن: أمن المعلومات مهم في الحوسبة السحابيّة، ولهذا، يجب أن يكون لديك فهم جيّد للمفاهيم الأساسيّة في مجال أمن المعلومات، كجدران الحماية مثلًا. إن القائمة المذكورة أعلاه ليست كاملة أبدًا. إن العبرة من ذكرها هو ضرورة أن تكون لديك معرفة تقنيّة قويّة إذا كنت تفكّر بدخول مجال هندسة الحوسبة السحابيّة. يقدّم موقع Could Roster قائمة محدّثة بالمهارات التقنيّة الدارجة، ويشرح ما تقوم به هندسة الحوسبة السحابيّة، ويوضّح الخصائص والتوقّعات اليوميّة، ويعرض قائمة بالمهارات التي يحتاجها السوق. يتم تحديث القائمة شهريًّا، لذا تأكّد من مراجعتها قُبَيلَ بدئك في السعي نحو الحصول على شهادة في المجال. [001-Cloud-Roster-Features.gif] ما الخطوة التالية؟ لنفترض بأنّك تحقّق بعض المتطلّبات المذكورة أعلاه؛ ماذا تفعل الآن لتغدو مهندس حوسبة سحابيّة مؤهّلًا؟ يعتمد هذا على المنصّة التي تفضّلها: خدمات أمازون السحابيّة - AWS مهندس معتمد لحلول خدمات أمازون السحابيّة (AWS Certified Solutions Architect – Associate) - تحقِّق هذه الشهادة الخبرات التقنيّة في تصميم ونشر نظام قابل للتوسعة، ومتاح دائمًا، ومقاوم للأخطاء على منصّة AWS التابعة لأمازون. يوضّح هذا المقال كيفيّة التحضير للاختبار بالتفصيل، ويتعمّق أكثر فيما يتعلّق بالمصادر المتاحة على Cloud Academy التي من شأنها مساعدتك على النجاح في الاختبار. Microsoft Azure مهندس حلول حوسبة سحابية لمنصّة Microsoft Azure (بالإنجليزيّة Microsoft Azure Solutions Architect - إنّ منصّة Microsoft Azure رياديّةٌ في هذا السوق الصاعِد، وتتطلّب شهادتها خبرة في الحوسبة، والشبكات، والتخزين، والأمن، وذلك من أجل تصميم حلول تعمل على Azure. للحصول على شهادة مهندس حلول Azure، ستحتاج إلى النجاح في اختبارين، وهما: AZ-300 و AZ-301. لا تحتاج إلى اجتياز أيّ امتحانات أقلّ درجة من أجل التقدم إلى هذين الامتحانين. يركّز اختبار AZ-300 على تقنيات Azure، بينما يركّز اختبار AZ-301 على التصميم. خدمات Google السحابيّة - Google Cloud Platform مهندس مختصّ في الحوسبة السحابيّ: يمكّن المهندسُ المختصّ في الحوسبة السحابيّة (Profestional Cloud Architect) المؤسساتِ من الاستفادة من التقنيات التي تتيحها خدمات Google السحابية. يمكن لهذا المهندس - بفهمه العميق لمعمارية الحوسبة السحابية ومنصّة Google للخدمات السحابيّة - أن يصمّم ويطوّر ويدير حلول تقنيّة متينة وآمنة وقابلة للتوسعة ومتاحة دائمًا ومرنة وذلك لتحقيق أهداف المؤسسة. لقد غدوتُ مهندس حوسبة سحابية مؤهَّلًا - ماذا أفعل الآن؟ ما إن تتخطى اختبار التأهيل، ستُفتَح أمامك العديد من فُرَص العمل التي ربما لم تفكِّر فيها حتّى. إنّ بعض الشركات الأكثر ابتكارًا في مجال البيانات الضخمة (big data) ليس بوسعها تحقيق أيّ شيء دون مهندس حوسبة سحابيّة مؤهّل لإحدى منصّات الحوسبة السحابية المذكورة. تُقدِّم AWS المرونة وإمكانيّة التوسعة والرزانة المطلوبة لأكثر من مليون زبون. من الشركات التي تستفيد من خدمات AWS في مجال البيانات الضخمة كلّ من General Motors، وIBM، وSplunk، وWeather Company. قد تجد نفسك يومًا ما تعمل لدى شركة طبيّة لبناء نظام لتحليل الحمض النووي (الجينات) لتوقع الأمراض من خلالها. إذا كنت تحب السّفر، فقد تعمل في يوم ما لدى شركة Expedia، التي تستخدم AWS لاستضافة خدمتها (Expedia Service)، وهي خدمة متخصّصة بتقديم الاقتراحات المتعلّقة بالسياحة. ولكي لا ننسى أحد أكبر زبائن AWS، وهي Netflix، تستخدم منصة AWS في نظام توصيل محتوى متاح دائمًا ومقاوم للأخطاء لخدمة بثّ الأفلام والبرامج التلفازيّة التي تقدّمها. تعتمد Netflix على إمكانات البنية التحتيّة لأمازون في التوسّع السريع والخوادم وتخزين البيانات، وذلك بسبب الكمّ الهائل ونمط الاستخدام المتأرجح لزبائنها. لا يسعنا إلا أن نتخيّل أنّهم يوظّفون مئات إن لم يكن آلاف مهندسي حلول الحوسبة السحابيّة لمنصّة AWS. إنّ منصّة Microsoft Azure أسرع مزوّدي الخدمات السحابيّة نموًّا لبناء واختبار ونشر وإدارة التطبيقات والخدمات عبر مراكز بيانات تديرها Microsoft. من الشركات التي تستخدم Azure كلّ من Adobe، وApple، وiCloud، وEbay، وTravelocity، وSamsung، وXerox، وNFL، وNBC. ما إن تصبح مهندس حوسبة سحابيّة مؤهًلًا لمنصّة Microsoft Azure، فسيكون باستطاعتك التقدّم لأيّ من آلاف الشواغر المتاحة لـمهندسي الحوسبة السحابيّة لمنصّة Azure. إنّ منصّة Google للحوسبة السحابيّة هي حقيبة كاملة من خدمات الحوسبة السحابيّة التي تعمل على نفس البنية التحتيّة التي تستخدمها Google من أجل خدماتها التي تقدّمها للمستخدمين الأفراد، وتستخدمها كذلك كلّ من Target، وPayPal، و20th Century Fox، وTwitter. إذا صرت مؤهلًا في هندسة الحوسبة السحابية لمنصة Google، فبإمكانك التقدّم للوظائف ذات العلاقة. إنّ مهندس الحوسبة السحابيّة لَذو دور هامّ، وهناك حاجة ماسّة في السوق لهذا التخصّص، والإمكانات فيه غير محدودة. وتشير التوقعات أيضًا إلى نموّ هائل في هذا المجال في السنوات القليلة القادمة، ولهذا نعتقد بأنّ الحصول على مؤهّل في هندسة الحوسبة السحابية خطوة في الاتجاه الصحيح، سواء للعمل في المجال، أو للتعرف على أيّ تقنيات حديثة ومذهلة تنشأ في حلبة الحوسبة السحابيّة. ترجمة -وبتصرف- للمقالين: What Exactly Is a Cloud Architect and How Do You Become One?‎ لصاحبه Michael Sheehy Prerequisites to Learn Cloud Computing – Introduction لصاحبه Stefano Bellasio
    1 نقطة
×
×
  • أضف...