An Introduction to HAProxy and Load Balancing Concepts

آشنایی با مفاهیم تقسیم بار Load Balancing و HAProxy

An Introduction to HAProxy and Load Balancing Concepts

معرفی

HAProxy یک نرم افزار متن باز Open Source برای تقسیم بار Load Balancing می باشد و مخفف High Availability Proxy است ، که محبوب ترین تقسیم کننده بار Load Balancer بر روی پروتکل TCP/HTTP می باشد و یکی از بهترین راه حل های پراکسی بر روی سیستم عامل های Linux ، Solaris و FreeBSD می باشد. از این برنامه برای افزایش کارایی و پایداری بیشتر زیرساخت سرور ها بوسیله توزیع بار بر روی چندین سرور استفاده می شود. این برنامه بر روی بسیاری از محیط های پرکاربرد مانند GitHub , Imgur , Instagram  و Twitter استفاده می شود.

در این مطلب ، مطالب عمومی درباره HAProxy مانند مفاهیم پایه تقسیم بار Load Balancing و مثال هایی از این که این برنامه چطور به باعث افزایش کارایی و پایداری سرور ها و زیر ساخت سرورهای شما می شود ، فراهم کردیم.

اصطلاح HAProxy

اصطلاح ها و مفاهیم زیادی درباره تقسیم بار Load Balancing وجود دارند که در قسمت های بعدی این مقاله به توضیحات اصطلاحات عمومی در این زمینه می پردازیم.

لیست کنترل دسترسی ( Access Control List )ACL

همانطور که میدانید از ACL ها در قسمت های مختلف IT استفاده می شود که در همه موارد هم کاربرد مشابه دارند و برای بررسی درخواست ها با یک لیست که از قبل تعریف شده است می باشد. در اینجا از ACL ها برای بررسی برخی شرط ها ( مانند سرور ها و قسمتی از درخواست ها ) استفاده می شود و نتیجه آن بهتر شدن برخی عملکردهای پایه ای می باشد. استفاده از ACL ها باعث می شود که در اجاع درخواست های شبکه انعطاف پذیری بیشتری در حالت های مختلف داشته باشیم ، مانند تطبیق الگو ها و تعداد اتصالات به یک backend.

مثالی از یک ACL :

acl url_blog path_beg /blog

این ACL برای مشخص کردن درخواست هایی است که با blog/ شروع می شوند. مثلا این درخواست http://yourdomain.com/blog/blog-entry-1 با این الگو مطابقت دارد.

برای آشنایی با جزئیات بیشتر در این باره راهنمای پیکربندی HAProxy را مطالعه کنید.

Backend

درخواست ها بعد از این که توسط تقسیم کننده بار HAProxy مدیریت و دسته بندی شدند به سرور های تعیین شده برای پردازش و پاسخ ارسال می شوند که به این مجموعه از سرورها Backend می گوییم. سرور های Backend در یک قسمت جداگانه در پیکربند HAProxy تعریف می شوند. تعریف backend ساده است و به صورت انجام می شود :

  • همراه با الگوریتم تقسیم بار مورد استفاده
  • لیستی از سرور ها و پورت ها

یک Backend شامل یک یا چندین سرور است و واضح است که با اضافه کردن سرور های Backend تقسیم بار بین سرور های بیشتری انجام می شود و تحمل بار در شبکه و زیرساخت افزایش پیدا کرده و در نتیجه پایداری سیستم نیز افزایش پیدا می کند. همچنین وقتی تعداد سرور ها بیشتر باشند در صورت خرابی و از دسترسی خارج شدن سرور ، درخواست بین سرور های دیگر تقسیم شده که باعث پایداری بیشتر سیستم شما شده و در نتیجه باعث افزایش اعتماد به شبکه و زیرساخت شما خواهد شد.

در ادامه نمونه ای از پیکربندی دو سرور Backend با نام های web-backend و blog-backend آورده شده است که هر کدام بر روی سرور های جداگانه هستند که بر روی پورت ۸۰ کار می کنند :

خط balance roundrobin مشخص کننده نوع الگوریتم تقسیم کننده بار هست که در قسمت های بعدی الگوریتم های تقسیم کننده بار را با جزئیات بیشتری معرفی می کنیم.

قسمت mode http مشخص می کند که پراکسی بر روی کدام یک از لایه های شبکه کار می کند ، که در قسمت بعدی این مطلب انواع حالت های پراکسی را برای HAProxy شرح می دهیم.

گزینه check در انتهای خطوط server تعیین می کند که سلامت و در دسترسی بودن سرور های backend باید بررسی شوند.

Frontend

در قسمت Frontend مشخص می شود که چه درخواستی به سرور های backend ارسال شوند. تنظیمات مربوط به این قسمت در فایل پیکربندی HAProxy در قسمت جداگانه به نام frontend انجام می شود. تعریف frontend شامل اجزای زیر است :

  • تنظیم آدرس IP و پورت
  • ACL ها
  • رول های backend ، که مشخص می کنند درخواست هایی که با شرط های ACL ها منطبق هستند به کدام سرور های backend ارسال شوند ، و رول های پیش فرض default_backend که همه درخواست ها را بررسی می کنند.

یک frontend را به روش های مختلفی می توان پیکربندی کرد که در ادامه به توضیح این روش ها می پردازیم.

انواع تقسیم بار Load Balancing

تا الان با اصطلاحات پایه تقسیم بار Load Balancing آشنا شدیم ، اکنون با روش ها و انواع تقسیم آشنا می شویم.

حالت بدون تقسیم بار No Load Balancing

طراحی زیرساخت یک برنامه تحت وب ساده به صورت زیر است :

web_server

در این مثال کاربر بوسیله نام دامنه yourdomain.com به صورت مستقیم به برنامه تحت وب متصل می شود و هیچ تقسیم بار و Load Balancing ای وجود ندارد. در این حالت اگر تنها یک سرور شما از دسترس خارج شود کاربر دیگر به برنامه شما دسترسی ندارد. به علاوه اگر کاربران زیادی به صورت همزمان به سرور متصل شوند و سرور نتواند بار اضافه را مدیریت کند ، سرور شما یا به شدت کند شده و یا اینکه سرور دیگر نمی تواند سرویس دهی کند و هیچ کسی نمی تواند به سرور متصل شود.

تقسیم بار در لایه ۴ – Layer 4 Load Balancing

ساده ترین راه برای تقسیم ترافیک شبکه بین چند سرور استفاده از تقسیم بار لایه ۴ ( لایه انتقال – Transport Layer ) است. در این حالت از تقسیم بار ترافیک کاربر بر اساس آدرس IP و پورت port شبکه انجام می شود ، برای مثال اگر درخواستی برای آدرس  http://yourdomain.com/anything دریافت شود ترافیک آن به سرور backend ای ارسال می شود که همه درخواست های برای yourdomain.com و پورت ۸۰ ارسال می شوند.

این یک طرح ساده برای تقسیم بار در لایه ۴ می باشد :

layer_4_load_balancing

در اینجا کاربر دیگر مستقیما به سرور برنامه تحت وب متصل نمی شود بلکه در ابتدا به سرور تقسیم کننده بار متصل شده سپس درخواست های کاربر به گروهی از سرور های web-backend ارسال می شوند. هر سروری که انتخاب شود به درخواست های کاربر پاسخ می دهد. به طور کلی تمامی سرور های web-backend باید محتوا و پاسخ دهی یکسانی داشته باشند ، در غیر اینصورت ممکن است کاربر پاسخ های متناقض و متفاوتی را دریافت کند. دقت کنید که در این طرح سرور های web-backend به یک سرور پایگاه داده متصل هستند و اگر برای سرور پایگاه داده مشکلی پیش بیاید سرویس دهی دیگر انجام نخواهد شد. البته این طرح یک مثال ساده برای درک مطلب است.

تقسیم بار لایه ۷ – Layer 7 Load Balancing

یک روش دیگر برای تقسیم بار ترافیک شبکه استفاده از تقسیم بار در لایه ۷ ( Application Layer ) می باشد. با استفاده از تقسیم بار در لایه ۷ ، تقسیم کننده بار ترافیک ها را بر اساس محتوای درخواست ها به سرور های backend ارجاع می دهد. در این حالت می توانید چندین برنامه تحت وب را با یک نام دامنه و یک پورت راه اندازی کنید.

این نیز یک طرح ساده از تقسیم بار در لایه ۷ می باشد :

layer_7_load_balancing

در این مثال اگر درخواست کاربر yourdomain.com/blog باشد به سرورهایی backend که در قسمت blog-backend تعریف شده اند ارسال می شوند و بقیه درخواست ها به سرورهای web-backend ارسال می شوند که ممکن است برنامه ای متفاوت به این درخواست ها پاسخ دهند. در این مثال نیز هر دو برنامه از یک پایگاه داده مشترک استفاده می کنند.

نمونه ای از یک قسمت از این تنظیمات به صورت زیر است :

frontend http : تنظیمات frontend با نام http تمامی درخواست های پورت ۸۰ را مدیریت می کند.

acl url_blog path_beg /blog : درخواست کاربران که با blog/ شروع می شود را مشخص می کند.

use_backend blog-backend if url_blog سرور blog-backend : در صورت برقراری شرط ACL را تعیین می کند ، که در اینجا از ACL به عنوان یک پراکسی استفاده می شود.

default_backend web-backend : در اینجا مشخص می شود که تمام درخواست های دیگر که شامل شرط ACL نیستند به سرور web-backend ارسال شوند.

الگوریتم های تقسیم بار – Load Balancing Algorithms

از الگوریتم های تقسیم بار برای انتخاب سرور backend هنگام تقسیم بار استفاده می شود. در HAProxy چند الگوریتم وجود دارد که آنها را توضیح می دهیم. علاوه بر الگوریتم متعادل کننده بار، سرورها می توانند یک پارامتر وزن weight را برای دستکاری در انتخاب سرور، در مقایسه با سرور های دیگر، تعیین کنند.

الگوریتم های زیادی برای HAProxy وجود دارد که در اینجا فقط تعدادی از مشهور ترین این الگوریتم ها توضیح می دهیم. برای مطالعه بیشتر و کامل الگوریتم ها راهنمای پیکربندی HAProxy  را مطالعه کنید.

پرکاربرد ترین الگوریتم ها :

Roundrobin

این الگوریتم پیش فرض HAProxy می باشد که به صورت چرخشی عمل می کند ، یعنی هر تعداد سرور که وجود داشته باشد به صورت نوبتی و چرخشی درخواست را برای آنها ارسال می کند.

Leastconn

در این حالت سرور هایی که کمترین اتصال و نشست های فعال را داشته باشند انتخاب می شود. این الگوریتم برای نشست های طولانی مدت در برنامه تحت وب برقرار است پیشنهاد می شود. سرور هایی که اتصال و نشست های یکسان داشته باشند بر اساس مدل چرخشی round-robin انتخاب می شوند.

Source

در این الگوریتم سرور ها بر اساس منبع تعیین شده مانند آدرس IP کاربران انتخاب می شوند. برای مثال درخواست کاربران با یک آدرس خاص که در پیکربندی آن را تعیین می کنیم به یک سرور مشخص ارسال می شوند. این روش برای زمانی مناسب است که می خواهید در کاربران مشخص یا یک شبکه مشخص از سرور ای که میخواهید سرویس بگیرند.

علامت گذاری نشست ها – Sticky Sessions

در اتصال به برنامه تحت وب و ایجاد نشست این نکته مهم است که در ارتباط های بین سرور و کاربر دقیقا همان سرور که درخواست کاربر را به آن واگذار شده است به کاربر به صورت مداوم و تا انتهای نشست پاسخ دهد. این کار بوسیله sticky sessions انجام می شود ، به این صورت که نشست ها بین کاربر و سرور بر اساس مقدار appsession که در قسمت backend تعیین می شود بر روی ترافیک نشست ها علامت گذاری می شوند ( اصطلاحا stick می شوند ) تا درخواست مجدد ارسالی از کاربر در یک نشست به همان سرور پاسخ دهنده مشخص شده ارسال و دریافت شوند.

بررسی سلامت اتصال – Health Check

نکته بسیار مهم در سیستم تقسیم بار و Load Balancing این است که برنامه تقسیم کننده بار باید از وضعیت سرور های backend و این که این سرور ها می توانند به درخواست ها پاسخ بدهند یا نه ، مطلع باشد. برای این کار برنامه تقسیم کننده بار HAProxy به صورت دوره ای و مرتبا وضعیت برقرار بودن اتصال TCP را بر روی آدرس IP و پورت port تعیین شده در فایل پیکربندی برنامه تعیین شده است را بررسی می کند. دقت کنید که اگر سروری از سرور های backend از دسترس خارج شد ، مشخصات آن سرور را به صورت دستی از تنظیمات برنامه حذف نکنید.

اگر سروری از سرور های backend از دسترس خارج شود ، برنامه تقسیم کننده بار HAProxy دیگر درخواستی را به آن سرور ارسال نمی کند و درخواست ها به سرور های دیگر ارسال می شوند. در این زمان مرتبا وضعیت اتصال و ارتباط با سروری که از دسترس خارج شده بررسی می شود و همین که اتصال برقرار شود مجددا برای آن سرور درخواست ها ارسال می شوند.

همچنین اگر تمامی سرور های backend از دسترس خارج شوند ، برنامه تحت وب دیگر در دسترسی کاربران نخواهد بود تا زمانی که حداقل یکی از سرور های backend به چرخه بازگردند.

البته برای سرور های خاص مانند سرور های پایگاه داده بررسی وضعیت اتصال به سرور ها راه حل کافی نیست و باید راه حل های دیگری نیز در همراه آن داشته باشید.

راه حل های دیگر

اگر احساس می کنید HAProxy ممکن است برای نیازهای شما بسیار پیچیده باشد، راه حل های زیر ممکن است بهتر باشد:

  • Linux Virtual Servers (LVS) – یک تقسیم کننده بار ساده و سریع لایه ۴ که در بسیاری از توزیع های لینوکس وجود دارد.
  • Nginx – یک وب سرور سریع و پایدار که به منظور پراکسی و تقسیم بار نیز از آن استفاده می شود. Nginx اغلب در ارتباط با HAProxy برای قابلیت ذخیره و فشرده سازی آن استفاده می شود.

پایداری بالا – High Availability

تا اینجا تقسیم بار لایه های ۴ و ۷ را برای مدیریت و تقسیم بار ترافیک های مستقیم شبکه و ارسال آنها به سرور های backend صحبت کردیم ، ولی نقطه ضعف آنها در خود سرور تقسیم کننده بار می باشد. به این دلیل که سروری که کار تقسیم بار را انجام می دهد یکی است و پشتیبانی ندارد. این سرور ممکن است در درخواست های زیاد غرق شده و پایین بیاید تاخیر زیادی در کار شما بوجود آورد و مدت زمان زیاد سرویس شما را از دسترس خارج کند.

استفاده از High Availability ( HA  ) در زیر ساخت شبکه سرور های می تواند از این نقطه ضعف جلوگیری کند. این سیستم با اضافه کردن افزونگی ( Redundancy ) به صورت یک لایه اضافه برای تحمل خطا به لایه های معماری ، یک سرور جایگزین در زمان وقوع خطا جایگزین می کند. تقسیم کننده بار تحمل بار شبکه و درخواست های شبکه را برای سرور های backend آسان می کند و باعث پایداری آنها می شود ، ولی برای اینکه پایداری واقعی را داشته باشیم باید سرور جایگزین برای تحمل خطا سرور تقسیم کننده بار داشته باشیم.

در شکل زیر یک طرح ساده و پایه ای از پایداری بالا نمایش داده شده :

ha-diagram-animated

در این مثال چندین تقسیم کننده بار وجود دارد ( یکی فعال و بقیع غیر فعال هستند ) که همگی در پشت یک آدرس IP استایتک قابل انتقال به یکدیگر هستند. وقتی کاربر می خواهد به سایت دسترسی داشته باشد ، درخواست آن از طریق آدرس IP به سرور تقسیم کننده بار فعال می رسد. اگر سرور تقسیم کننده بار در دسترس نباشد ، سیستم تحمل خطا این رو تشخیص می دهد و آدرس IP را مجددا به یکی از سرور های غیر فعال واگذار می کند. راه های زیادی برای پیاده سازی HA وجود دارد.

Leave a Reply