دانشجوی پزشکیِ عاشقِ تکنولوژی
معماری وب: آشنایی با مفاهیم پایه
تصویر بالا، معماری مدرن اپلیکیشنهای تحت وب را به خوبی به نمایش میگذارد. توسعهدهندگانی که در حوزه وب تجربه کمتری دارند، ممکن است این معماری کمی پیچیده به نظرشان برسد. اما نگران نباشید، حقیقت این است که اصول اولیه حاکم بر این نمودار را میتوان بسیار سریع آموخت! در ادامه مروری کوتاه اما بسیار ساده بر هر یک از اجزاء این تصویر میاندازیم تا ببینیم اپلیکیشنهای مدرن تحت وب چگونه کار میکنند و وقتی یک وبسایت را فرامیخوانیم، در پشت صحنه دقیقاً چه اتفاقی میافتد.
۱. سامانه نام دامنه (DNS)
سامانه نام دامنه (Domain Name System) یا مخفف رایجتر آن DNS یک فناوری پایه و حیاتی برای وجود شبکهی جهانی اینترنت است. در سطوح اولیه، DNS یک کلید/مقدار (مثلاً google.com) را به یک IP (مثلاً: 85.129.83.120) ربط میدهد که باعث میشود کامپیوتر شما یک درخواست به سرور مناسب بفرستد. اگر این سیستم را به برقراری تماس تلفنی تشبیه کنیم، فرآیند کار DNS مانند تبدیل «با علی تماس بگیر» به این است که: «با شمارهی 22112233 تماس بگیر». همانطور که در گذشته برای پیدا کردن شماره تلفن علی باید در دفترچه تلفن دنبال آن میگشتید، امروزه نیز برای پیدا کردن IP یک دامنه به DNS نیاز دارید. میتوان گفت DNS دفترچه تلفن اینترنت است.
جزئیات بسیار زیادی هستند که میتوان به آنها پرداخت، اما برای مراحل ابتدایی تا همینجا کافی است.
۲. متوازنکننده بار (Load Balancer)
قبل از پرداختن به جزئیات توازن بار، باید راجع به مقیاسدهی افقی و عمودی اپلیکیشن توضیح بدهیم. به طور ساده، تغییر مقیاس افقی یعنی افزایش «تعداد» منابع مثلاً از طریق افزایش تعداد کامپیوترها؛ در حالی که تغییر مقیاس عمودی یعنی افزایش «قدرت» منابعی که در اختیار داریم مثلاً با ارتقای CPU یا RAM کامپیوتر.
در توسعهی وب، شما تقریباً همیشه باید به صورت افقی مقیاس کنید، دلیل آن هم این است که هر چیزی خراب میشود! سرورها ناخواسته به مشکل میخورند، شبکهها تحلیل میروند، حتی گاهی یک مرکز داده (Data Center) به طور کلی آفلاین میشود. داشتن چند سرور باعث میشود بتوانید از قطعیها فرار کنید و برنامهی شما همچنان کار کند. در واقع برنامهی شما "مقاوم به مشکل" (Fault Tolerant) میشود. مزیت دوم تغییر مقیاس افقی این است که اجزای مختلف Back-end برنامه ی شما (مانند سرور شبکه، دیتابیس و...) اگر روی سرورهای جدا قرار داشته باشند، کمترین وابستگی را به هم خواهند داشت. مورد آخر هم این که در نهایت برای مقیاس عمودی محدودیت وجود دارد و به جایی میرسید که دیگر نمیتوانید مقیاس عمودی بیشتری انجام دهید. هیچ کامپیوتری آنقدر قوی نیست که بتواند از عهدهی تمام محاسبات مورد نیاز شما بر بیاید!
خب، برگردیم به متوازن کننده های بار، همان چاشنی جادویی که مقیاس افقی را امکانپذیر میکند! کار آنها این است که درخواست را به یکی از چندین سرور اپلیکیشن که معمولاً دقیقاً شبیه هم (یا Mirror Image هم هستند) بفرستند و پاسخ آن را به کاربر (Client) برگردانند. همهی این سرورها درخواست را مشابه یکدیگر مدیریت میکنند، پس مسئله صرفا توزیع درخواستها است به طوری که هیچ کدام از سرورها بار اضافی نگیرند.
همین. ایدهی کلی متوازنکننده بار بسیار است. مشخص است که اگر بخواهیم دقیقتر شویم، پیچیدگیهای خاص خود را دارند اما فعلاً نیازی نیست آنها را بدانیم.
۳. سرور برنامههای مبتنی بر وب (Web Application Servers)
در بیان کلی، سرورهای برنامههای مبتنی بر وب را میتوان به سادگی معرفی کرد. آنها منطق مورد نیاز برای مدیریت کردن درخواستهای کاربر را اجرا میکنند و پاسخ را در قالب HTML به مرورگر کاربر میفرستند. سرورها برای کار خود، با زیرساختهای بکاند مختلف مثل دیتابیسها، لایههای Cache، صفهای انجام کار (Job Queues) و... در ارتباط هستند. همان طور که بالاتر گفته شد، به صورت معمول حداقل دو سرور وجود دارد (و خیلی مواقع بیشتر) که به یک متوازنکننده بار متصل شدهاند تا درخواست کاربر بتواند پردازش شود.
برای پیادهسازی سرورهای برنامه، به یک زبان برنامهنویسی (مثلاً Node.js ،Ruby ،PHP، جاوا، اسکالا، سیشارپ و...) و در کنار آن یک فریمورک Web MVC برای آن زبان (Express برای Node.js، لاراول برای پیاچپی، Play برای Scala و...) نیاز است. البته جزئیات این موارد فراتر از موضوع این مقاله است.
۴. سرورهای دیتابیس
امروزه هر برنامهی شبکه از یک یا تعدادی بیشتر دیتابیس برای ذخیرهسازی اطلاعات استفاده میکند. دیتابیس به شما امکان تعریف دادهساختارهای خود، اضافه کردن دادهی جدید، پیدا کردن داده، بهروز کردن یا پاک کردن داده، و خیلی کارهای دیگر را میدهد. سرورهای برنامههای تحت وب معمولاً مستقیم به یک دیتابیس متصل میشوند، علاوه بر این هر سرویس Back-end ممکن است دیتابیس خاص خود را داشته باشد که از بقیهی برنامه جدا است.
درست است که از پرداختن به خیلی از جزئیات پرهیز میکنیم اما دانستن جزئیات دو مورد بهتر از ندانستن آنهاست: SQL و NoSQL.
زبان SQL (که مخفف Structured Query Language یا به عبارتی زبان ساختارمند پرسشها) است در دهه ۷۰ میلادی ایجاد شد. هدف از ساخت این زبان، ایجاد راهکاری ساده برای کوئری زدن بر روی مجموعه دادههای رابطهای (Relational Data Sets) بود. دیتابیسهای SQL دادهها را در جدولهایی نگه میدارند که به وسیلهی IDهای مشترک با یکدیگر مرتبط هستند. بگذارید مثال سادهای در مورد ذخیرهی اطلاعات آدرس کاربران بزنیم:
میتوانیم دادهها را در دو جدول ذخیره کنیم: یکی جدول users و دیگری جدول user_addresses. هر دو این جدولها یک ستون id دارند که به ترتیب، شناسهی کاربرها و شناسهی آدرسها را با یک عدد یکتا مشخص میکند. در جدول user_addresses یک ستون به نام user_id نیز قرار دارد که یک کلید خارجی (Foreign Key) محسوب میشود و این دو جدول را به یکدیگر متصل میکند. با user_id میتوانیم بفهمیم آدرسی که ذخیره شده است برای کدام کاربر است. تصویر زیر یک طرح ساده از این مثال است:
اگر با SQL آشنایی ندارید، بهتر است کمی در مورد آن مطالعه کنید؛ زیرا در بخشهای زیادی از توسعهی وب به کار میرود و آشنایی با مبانی آن بسیار کاربردی است.
در طرف مقابل NoSQL، که به معنای غیر SQL (یا Non-SQL) است، مجموعهای جدیدتر از فناوریهای دیتابیس است. هدف ایجاد NoSQL مدیریت حجم عظیم دادههایی است که برخی برنامههای تحت وب در مقیاس بزرگ تولید میکنند. بیشتر انواع SQL معمولاً به خوبی نمیتوانند به صورت افقی مقیاس کنند و تنها توانایی مقیاس شدن عمودی (آن هم به شکل محدود) را دارند. اگر در مورد NoSQL به کسب اطلاعات تکمیلی نیاز دارید، میتوانید نگاهی به منابع زیر بیندازید:
در نظر داشته باشید که به طور کلی دنیای وب، حتی برای دیتابیسهای NoSQL، از SQL استفاده میکند. پس حتماً باید SQL یاد بگیرید و هیچ راه فراری از آن ندارید.
۵. سرویسهای Caching
یک سرویس Caching، پایگاه داده سادهای به صورت کلید/مقدار (یا به عبارتی Key/Value) در اختیار ما میگذارد که امکان ذخیره و پیدا کردن اطلاعات را تقریباً با O(1) فراهم میکند. برنامهها از سرویسهای Caching استفاده میکنند تا نتایج محاسبات پرخرج و پرزحمت را نگه دارند و به این ترتیب دفعهی بعد نیازی نباشد که دوباره این محاسبات از اول انجام شوند و صرفا نتایج از Cache بازیابی میشوند. یک برنامه میتواند نتایج یک کوئری دیتابیس، نتایج ارتباط با سرویسهای خارجی، HTML یک URL خاص و خیلی چیزهای دیگر از این دست را Cache کند. مثالهایی از دنیای واقعی ببینید:
- گوگل نتایج جستجوهای پرطرفدار مثل “آب” یا “سریال جدید” را Cache میکند تا هر دفعه نیازی به محاسبه کردن آنها نباشد.
- فیسبوک خیلی از چیزهایی که بعد از ورود میبینید، مثلاً دادههای پستها، فهرست دوستان و... را Cache میکند. درباره سیستم Caching فیسبوک در این مطلب میتوانید بیشتر بخوانید.
فراگیرترین فناوریهای کاربردی برای Caching عبارتند از Redis و Memcached.
۶. صف کار (Job Queue & Servers)
بیشتر برنامههای تحت وب نیاز دارند که یک سری کار را به صورت ناهمگام (Asynchronously) در پشت پرده انجام دهند که بعضاً ربط مستقیمی هم به درخواست کاربر ندارند. مثلاً گوگل باید کل اینترنت را Crawl کند (خزش در صفحات وب) و نتایج را نمایه کند تا بتواند پاسخ جستجوها را بدهد. گوگل این کارها را صرفاً زمان جستجوی کاربر انجام نمیدهد، بلکه به صورت ناهمگامی شبکه را Crawl میکند و نمایههای جستجو را به طور مداوم به روز میکند. یا مثال روزمره دیگری که همگی که با آن سروکار داشتهایم، زمانی است که کاربر در سایت عضو میشود و قرار است برای او ایمیل تایید عضویت ارسال شود. پیامی مبنی بر ارسال ایمیل سریعاً به کاربر نمایش داده میشود اما در واقع ایمیل هنوز ارسال نشده و به صورت ناهمگام و کمی بعدتر ارسال میشود.
ساختارهای زیادی برای کار کردن به صورت ناهمگام وجود دارد، فراگیرترین آن چیزی است که آن را ساختار «صف کار» مینامیم. دو جزء اینجا ایفای نقش میکنند: یک صف «کار» که باید اجرا شود و یک یا چند سرور کار (معمولا به آنها "کارگر" میگویند) که باید کارهای صف را انجام دهند.
صفهای کار لیستی از کارها که باید به صورت ناهمگام انجام شوند نگه میدارند. ساده ترین نوع آنها صفهای «خروج به ترتیب ورود» (یا FIFO) هستند که اولین درخواستی که وارد صف میشود، قبل از سایر درخواستها پردازش میشود. هرچند FIFO در بسیاری از مواقع هم جوابگو نیست و بیشتر برنامهها در نهایت به صفهایی نیاز پیدا میکنند که اولویتبندی بهتری از اهمیت کارها در آنها صورت میگیرد. هروقت یک کار باید انجام شود، چه طبق یک برنامهی منظم و چه طبق عملیاتهای کاربر، برنامه این کار را به صف اضافه میکند.
سرورهای کار، کارها را پردازش میکنند. آنها هر از گاهی به صف کار سر میزنند (Polling) تا ببیند آیا کاری برای انجام دادن هست یا نه و اگر بود، آن کار را از صف خارج، و اجرا میکنند. زبانها و فریمورکهای این سرورها نیز همانند سرورهای شبکه بسیار گسترده میباشند و برای این مقاله از ورود دقیقتر به آنها خودداری ميکنیم.
۷. سرویس جستجوی تمام متن
اکثر برنامههای تحت وب، نوعی از جستجو را درون خود دارند؛ به این صورت که کاربر یک متن ورودی میدهد (Query) و برنامه مرتبطترین نتایج را برمیگرداند. فناوری پشت این عملیات، «جستجوی تمام متن» (یا Full-text Search) نام دارد که از یک ایندکس معکوس (Inverted Index) استفاده میکند تا به سرعت پستهایی را پیدا کند که کلیدواژههای موجود در Query را دارا هستند.
با اینکه امکان انجام جستجوی تمام متن به طور مستقیم در یک سری دیتابیسها (مثلاً MySQL) وجود دارد اما راهاندازی یک «سرویس جستجوی» جداگانه که ایندکس معکوس بسازد و رابط Query داشته باشد هم بسیار معمول است. برای این منظور امروزه Elasticsearch پرطرفدارترین پلتفرم جستجوی تمام متن را ارائه میکند؛ البته موارد دیگری مثل Sphinx و Apache Solr نیز وجود دارند
۸. سرویسها (Services)
با پیشرفت و بزرگتر شدن برنامه، طی زمان یک سری «سرویسها» از برنامه جدا میشوند و به صورت برنامههای مستقل به کار خود ادامه میدهند. البته آنها با دنیای خارج ارتباطی برقرار نمیکنند، و برنامهی اصلی و دیگر سرویسها همچنان با آنها تعامل دارند. به عنوان مثال بر حسب نیاز میتوان برای چیزهایی از قبیل «مدیریت حسابهای کاربری»، «مدیریت پرداختها» یا «ایجاد فایلهای PDF از متون» سرویسهای جداگانهای راهاندازی کرد.
۹. داده (Data)
امروزه بقای شرکتها به طرز استفادهی آنها از دادهها بستگی دارد. تقریباً همهی برنامهها بعد از بزرگ شدن به حد کافی، یک پایپلاین داده راه میاندازند که بتوانند دادهها را جمعآوری، ذخیره و آنالیز کنند. یک پایپلاین عادی سه مرحله دارد:
۱. برنامه، دادههایی که معمولاً دربارهی رفتار کاربران است را به محیطی برای پردازش دادهها ارسال میکند. AWS Kinesis و Kafka دو فناوری رایج این کار هستند.
۲. هم دادهی خام و هم دادهی نهایی تغییریافته در سرویس ذخیرهی ابری ذخیره میشوند. AWS Kinesis محیطی به نام Firehose دارد که امکان ذخیرهی دادهی خام در سرویس ابری خودش (S3) را بسیار ساده کرده است.
۳. معمولا دادهی تغییریافته برای آنالیز به یک انبار داده (Data Warehouse) بارگذاری میشود. [در خارج از ایران] بسیاری از استارتاپها برای این منظور از AWS Redshift استفاده میکنند، هرچند شرکتهای بزرگتر معمولاً از Oracle یا انباردادههای انحصاری دیگر استفاده میکنند. اگر دادهها به اندازهی کافی بزرگ باشند، باید از فناوریهای ویژه دادههای بزرگ مانند هدوپ (Hadoop) و NoSQL استفاده کرد.
۱۰. ذخیره ابری (Cloud Storage)
ذخیره ی ابری راهی ساده و مقیاسپذیر برای ذخیره داده، دسترسی به آن و به اشتراک گذاشتن دادهها در اینترنت است. شما میتوانید هر چیزی که روی فایلسیستم محلی ذخیره میکنید را در آن ذخیره کنید، و مزیت آن این است که با استفاده از یک RESTful API میشود تحت HTTP به آن دسترسی داشت. سرویس S3 آمازون امروزه با اختلاف محبوبترین سرویس ذخیرهی ابری جهان است.
۱۱. شبکه توزیع محتوا (CDN)
شبکه توزیع محتوا (Content Delivery Network) یا مخفف آن CDN راهی در اختیار ما میگذارد تا داراییهایی مثل HTML ایستا، CSS، جاوا اسکریپت و عکسها را سریعتر در وب به کاربران ارائه دهیم، بسیار سریعتر از زمانی که آنها را از یک سرور تکمبدا ارائه میدهیم. روش کار CDN به این صورت است که محتوا را بین تعداد زیادی سرور حاشیهای در سرتاسر جهان پخش میکند تا کاربر آن محتوا را به جای دریافت از سرور مبدا اصلی، از سرورهای حاشیهای دریافت کند. برای مثال در شکل زیر، کاربری در اسپانیا یک صفحه را از سایتی درخواست کرده که سرورهای مبدا آن در نیویورک هستند؛ اما داراییهای ایستا میتوانند از یک سرور CDN حاشیهای در انگلیس دریافت شوند تا فاصلهی طولانی بین اسپانیا و نیویورک طی نشود.
برخی مطلبهای قبلی کوئرامگ برای توسعهدهندگان وب:
ترجمه و تلخیص از:
"Web Architecture 101", by Jonathan Fulton at Storyblocks
کوئرامگ مجلهای تخصصی برای توسعهدهندگان است که هر هفته با مطلبهایی در زمینه تکنولوژی، رشد فردی و آینده برنامهنویسی بهروزرسانی میشود. برای اطلاع از آخرین مطلبهای ما، میتوانید توئیتر یا کانال تلگرام کوئرا را دنبال کنید.
مطلبی دیگر از این انتشارات
۱۰ ابزار که توسعهدهندگان جاوا باید در سال ۲۰۱۹ یاد بگیرند
مطلبی دیگر از این انتشارات
بهترین ویرایشگرهای متن حال حاضر برای برنامهنویسها
مطلبی دیگر از این انتشارات
انقلاب پنج به هفت؛ داستان PHP (قسمت اول)