پیکربندی HAProxy


محمد در نظر دارد پیکربندی مربوط به HAProxy را برای وب‌سایتی که جدیدا در دست طراحی است انجام دهد. در معماری انجام شده، HAProxy به عنوان لودبالانسر/پراکسی، جلوی سرورهایی که برای وب سایت ایجاد شده‌اند قرار گرفته است در این پیاده‌سازی از چندین سرور (api application و nginx webserver) استفاده شده است و برای پاسخ به درخواست‌های وب‌سایت از این سرورها استفاده می‌شود.

در وب‌سایت مورد نظر یک اپلیکیشن با نام api که یک flask api است وظیفه جواب دادن به درخواست‌ها روی مسیر‌های /games ، /auth و /mobile را دارد.

همچنین دو وب سرور Nginx وجود دارد که وظیفه جواب دادن به درخواست‌ها روی مسیر روت یا / را دارند که به صورت Fail Over یکدیگر کار می‌کنند.

برای دانلود پروژه اولیه روی این لینک کلیک کنید.

حال از محمد خواسته شده تا کارهای زیر را انجام دهد:

  1. در HAProxy نیاز به پیکربندی داریم که بتوانیم با توجه به بالا بودن هر دو وب‌سرور nginx، برای مسیر روت (یا همان /) ابتدا فقط ترافیک به وب‌سرور با نام app_primary ارسال شود و در صورت از دسترس خارج شدن سرور اول ترافیک، به سمت وب‌سرور دوم با نام app_secondary ارسال گردد و زمانی‌که مشکل وب‌سرور اول حل شد ترافیک مجدد فقط به وب سرور app_primary ارسال شود.

توجه داشته باشید:

  • تنظیمات HAProxy باید به گونه‌ای باشد که همزمان ترافیک به هر دو وب‌سرور nginx ارسال نگردد.
  • وب‌سرورهای Nginx روی پورت 80 کار می‌کنند.
  • در تنظیمات HAProxy برای وب‌سرورهای Nginx یک backend با نام app تعریف شده‌است که در باکس زیر جزئیات آن را می‌بینید:
extensionFromNamehaproxy.cfg
backend app
    http-response add-header x-Server %b/%s
    default-server check inter 1s fall 1 rise 3
Config
  1. در پیکربندی HAProxy مسیرهای زیر باید توسط اپلیکیشن مورد نظر(یعنی api یا nginx) جواب داده شود:
  • درخواست‌های به /games ، /mobile و /auth باید حتما توسط اپلیکیشن api جواب داده شود.

  • درخواست‌ها به مسیر روت باید توسط وب‌سرور Nginx جواب داده شود.

  1. تمامی درخواست‌هایی که توسط پلتفرم‌های همراه (یعنی موبایل، تبلت و ...) حتما بایستی به مسیر /mobile هدایت شوند. و در صورتی‌که درخواست مورد نظر از این پلتفرم‌ها نباشد بایستی به مسیر درخواستی خود هدایت شود.

توجه داشته باشید:

  • در صورتی‌که درخواست مورد نظر از پلتفرم‌های همراه (موبایل، تبلت و ...) نباشد و مسیر مورد نظر در هیچ یک از backend‌ها وجود *نداشته باشد** بایستی توسط *Nginx پاسخ داده شود و به مسیر روت هدایت شود.
  • اپلیکیشن api روی پورت 5000 کار می‌کند.
  1. در صورتی‌که درخواستی دارای کوئری باشد (به عنوان مثال /digikala?test=foo) بایستی به مسیر روت (یا همان nginx) هدایت شود.

  2. پیکربندی HAproxy باید به گونه‌ای باشد وقتی درخواستی با هدر X-Secret: key BASE64DECODED base64 به HAProxy رسید قسمت BASE64DECODED از هدر درخواستی به صورت base64 در هدری با نام auth-hash به اپلیکیشن api داده شود.

توجه داشته باشید:

  • اپلیکیشن api به این صورت کار می‌کند که اگر درخواستی با هدر auth-hash روی مسیر /auth برسد هدر مورد نظر را در خروجی چاپ می‌کند. در نظر داشته باشید که خروجی چاپ شده حتما بایستی مقدار base64 کلید مورد نظر در هدر X-Secret باشد.
  • درخواست‌های روی مسیر auth به صورت زیر ارسال می‌شود و دارای هدر X-Secret می‌باشند:
extensionFromNameterminal
curl -H "X-Secret: key BASE64DECODED RANDOM_STRING" 127.0.0.1:8080/auth
Bash

به عنوان مثال برای کلید BASE64DECODED باید مقدار زیر چاپ شود:

QkFTRTY0REVDT0RFRAo=
Plain text
  • هیچ تغییری روی کد اپلیکیشن api نباید داده شود.

  • عبارت بعد از BASE64DECODED یک رشته تصادفی می‌باشد.

  • سرویس HAProxy در هیچ حالتی نباید خطای 5XX بدهد و برای هر مسیری (موجود و یا ناموجود) باید ریسپانس کد 200 داشته باشد.

  • در تنظیمات HAProxy برای اپلیکیشن api که یک Flask api می‌باشد backend با نام api تعریف شده است. در ادامه جزئیات api را مشاهده می‌کنید.

extensionFromNamehaproxy.cfg
backend api
    http-response add-header x-Server %b/%s
    default-server check inter 1s fall 1 rise 3
Config
  • تعداد بکندهای تعریف شده در تنظیمات HAProxy نباید بیشتر از دو مورد موجود (api و app) باشد.

  • برای ایجاد پروژه اولیه از یک فایل docker-compose استفاده شده است که پورت 8080 برای HAProxy پابلیش شده است که درخواست های به پورت 8080 هاست (یا همان سیستم شما)، به HAProxy frontend روی پورت 80 ارسال می‌شوند. در ادامه جزئیات frontend را مشاهده می‌کنید:

extensionFromNamehaproxy.cfg
frontend http
    bind *:80
Config

تنظیمات HAProxy به شرح زیر می‌باشد: ‍‍‍‍‍

extensionFromNamehaproxy.cfg
# haproxy.cfg
global
    user root
    group root
    daemon
    stats timeout 30s

defaults
    log    global
    mode    http
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend http
    bind *:80

backend api
    http-response add-header x-Server %b/%s
    default-server check inter 1s fall 1 rise 3

backend app
    http-response add-header x-Server %b/%s
    default-server check inter 1s fall 1 rise 3
Config

نکته: در تعریف backend‌ها در HAProxy در نظر داشته باشید که اپلیکیشن api روی پورت 5000 کار می‌کند و وب‌سرورهای nginx روی پورت 80 کار می‌کنند.

اجرای پروژه اولیه🔗

برای اجرای از دستور زیر استفاده کنید:

extensionFromNameterminal
docker-compose up -d
Bash

برای از دسترس خارج کردن app وب‌سرور nginx می‌توانید از دستور زیر استفاده نمایید:

extensionFromNameterminal
docker-compose stop app_primary
Bash

برای انجام تست دسترسی به مسیرهای مورد نظر از مرورگر خود آدرس 127.0.0.1:8080 را باز نمایید به عنوان مثال:

http://127.0.0.1:8080/
http://127.0.0.1:8080/mobile
http://127.0.0.1:8080/games
http://127.0.0.1:8080/auth
Plain text

برای تست مسیر /auth میتوانید از دستور زیر استفاده کنید:

extensionFromNameterminal
curl -H "X-Secret: key BASE64DECODED RANDOM_STRING" 127.0.0.1:8080/auth
Bash

نحوه‌ی ارسال جواب🔗

شما فقط می‌توانید محتوای فایل haproxy.cfg را تغییر دهید. تغییرات خودتان را بر روی haproxy.cfg اعمال کنید و این فایل را Zip کرده و ارسال کنید. توجه کنید که پس از extract نمودن فایل زیپ، باید فایل haproxy.cfg مشاهده شود.

ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.