Как да: Разпределим натоварването на сайт с HAProxy

Как да: Разпределим натоварването на сайт с HAProxy

След като дадохме отговор на Nick Mirev и въпроса му за намаляване на процесорното време, нашите специалисти от Friendly Geeks се заеха с нелеката задача да дадат по-голяма яснота за това как да оптимизираме работата на един сайт, работещ на няколко сървъра и да разпределим натовaрването към тях. Въпросът “Как да конфигурираме HAProxy load balancing and hardware failover” бе зададен като коментар на нашето #Предизвикателство във Facebook от Svetozar Kolew. Отново ни задавате интересни въпроси, на които с радост ще отговорим.

Какво е HAProxy? Това е един безплатен, бърз и надежден софтуер, използван за разпределяне на натоварването на един сайт или апликация между два или повече сървъра. Осигурява високо ниво на сигурност и резервираност при хардуерен проблем на някой от node-овете. Сайтове, които използват това решение с висока достъпност, са GitHub, Reddit, Tumblr, Twitter и много други. За да дадем повече информация за работата на софтуера, ще Ви покажем нагледно как той се инсталира и настройва.

Ето още какъв софтуер ще използваме в нашия урок:

httpd: Уеб сървър.

php: Софтуер, обработващ php скриптове.

mysql: Сървър за бази данни.

memcached: Софтуер за кеширане на обекти в RAM паметта. В случая целта му е да съхранява php сесиите.

NFS: Мрежова файлова система, удобна за монтиране. Спестява: често синхронизиране, голям брой IOPS, трафик между сървърите, дублирането на данни.

Топология:

HAProxy1

IP адреси на сървърите:

NODE1:

172.18.10.22 (private)

NODE2:

172.18.10.23 (private)

HAproxy:

77.77.151.25 (public)

172.18.10.21 (private)

Създаване на виртуалните машини: 3 на брой, със следните параметри:

РАМ: 1024

CPU ядра: 2

Приоритет: 25%

Дискове:

/ - 10GB SSD

swap - 1GB

Операционна система: CentOS 6.5 x64

.

.

.

И така следваме стъпките:

1. Логваме се в сървър NODE1 и започваме неговата конфигурация:

2. Генерираме публичен ключ, който ще ни е нужен за бекъп синхронизацията на файловете от NODE1 на NODE2 безпаролно. Това е необходимо, защото често се налага cron задачи да извършват синхронизация и е по-безопасно да използваме ключ, отколкото да напишем паролата в крона или в някой файл.

[code]

ssh-keygen -t rsa

[/code]

По подразбиране ключът се записва в /root/.ssh/idrsa. Неговото съдържание трябва да бъде копирано на NODE2 във файла /root/.ssh/authorizedkeys.

3. Създаваме потребител wordpress и му задаваме парола. Обърнете внимание, че потребителите и на двата сървъра трябва да са еднакви! Това е така, защото httpd сървърът ще бъде настроен с именно този потребител, а файловете, тъй като са “споделени” от единия сървър на другия, ще бъдат с негови права.

[code]

adduser wordpress

passwd wordpress

<въвеждаме паролата>

[/code]

4. Инсталираме unzip, сваляме и разархивираме wordpress:

[code]

yum install unzip

wget wordpress.org/latest.zip

unzip latest.zip

[/code]

5. Създаваме phpinfo.php файл със съдържание <?php phpinfo(); ?>, с който можем да следим заредените php модули и който ще бъде използван от Haproxy за проверка дали NODE1 e онлайн:

[code]

nano /home/wordpress/public_html/phpinfo.php

Поставяме - <?php phpinfo(); ?> и записваме

chown wordpress:wordpress /home/wordpress/public_html/phpinfo.php

[/code]

6. Инсталираме PHP и основни extension-и към него (заедно с допълнителни модули), HTTPD, NFS, mySQL, MEMCACHED и RSYNC:

[code]

yum install php php-cli php-common php-mysql php-pdo php-xml php-xmlrpc httpd

yum install nfs-utils nfs-utils-lib

yum install mysql mysql-server

yum install memcached php-pecl-memcache

yum install rsync

[/code]

7. Конфигурираме NFS, HTTPD, mySQL server и memcached да се стартират при стартиране на системата:

[code]

chkconfig nfs on

chkconfig httpd on

chkconfig mysqld on

chkconfig memcached on

[/code]

8. Създаваме виртуален хост и променяме потребителя на httpd, сменяйки и формата на access_log да логва IP-то на клиента, а не на сървъра с HAProxy-то, редактирайки /etc/httpd/conf/httpd.conf. Това се променя, защото потребителят няма да отваря директно NODE-овете, а IP-то на HAProxy. То ще пренасочва трафика и ако не сменим вида на лога, httpd-то ще вижда IP-то на HAProxy, а не клиентското. Важно е потребителят и групата (User и Group), под които се стартира httpd и на двата NODE-а, да е един и същ, защото в противен случай ще има конфликт с правата на единия от двата сървъра.

[code]

...

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

...

User wordpress

Group wordpress

...

<VirtualHost 172.18.10.22:80>

ServerName pgrucov.com

ServerAlias www.pgrucov.com

ServerAdmin admin@icn.bg

DocumentRoot /home/wordpress/public_html

ErrorLog logs/icn-cluster-error_log

CustomLog logs/icn-cluster-access_log combined

</VirtualHost>

...

[/code]

9. Експортираме/home/wordpress/public_html/wp-content, за да може да се ползва от NODE2, редактирайки /etc/exports. Важно е да се дава достъп на локалното IP на NODE2 с цел по-висока сигурност. Експортираме само wp-content, където се съдържат снимките към публикациите, темплейта и плъгините.

[code]

*/home/wordpress/publichtml/wp-content 172.18.10.23(rw,fsid=0,sync,crossmnt,nosubtreecheck,noroot_squash)*

[/code]

10. Задаваме на PHP да използва memcached за сесиите, редактирайки /etc/php.ini. Отново е важно е да зададе локалното IP. Символът “;” коментира (забранява) дадена директива. В случая сме коментирали запазването на кукита(cookies) като файл локално.

[code]

;session.save_handler = files

;session.save_path = "/var/lib/php/session"

session.save_handler = memcached

session.save_path = "172.18.10.22:11211"

[/code]

11. Необходимо е да променим mysql да "слуша" само на локалния IP адрес и да няма достъп отвън. Редактираме /etc/my.cnf и добавяме (променяме) bind-address-а.

[code]

bind-address = 172.18.10.22

[/code]

12. Добавяме паролата за mySQL в /root/.my.cnf, за да можем да управляваме базата и да правим дъмпове без да въвеждаме парола.

[code]

[mysql]

user=root

password=parola

[mysqldump]

user=root

password=parola

[/code]

13. Създаваме база данни, потребител и даваме права на двата NODE-а в mySQL. Тъй като mysql "слуша" само локално, добавяме wildcard "%", за да може да се достъпва от всеки един локален хост:

[code]

mysql -p

<parola>

CREATE DATABASE wordpress;

GRANT ALL PRIVILEGES ON wordpress. TO wordpress@'%' IDENTIFIED BY 'parola';*

[/code]

SERVER: NODE2:

14. Добавяме публичния ключ на NODE1 във файла /root/.ssh/authorized_keys

15. Създаваме директория, на която ще бъде запазван бекъп всяка сутрин:

[code]

mkdir /BACKUP

[/code]

16. Инсталираме PHP (заедно с допълнителни модули), HTTPD, NFS и RSYNC.

[code]

yum install php php-cli php-common php-mysql php-pdo php-xml php-xmlrpc httpd

yum install nfs-utils nfs-utils-lib

yum install rsync

[/code]

17. Създаваме потребител wordpress и му задаваме парола. Отново Ви припомняме, че е важно потребителите и на двата сървъра да са еднакви!

[code]

adduser wordpress

passwd wordpress

<parola>

[/code]

18. Създаваме директория за сайта.

[code]

mkdir /home/wordpress/public_html

[/code]

19. Синхронизираме файловете на Wordpress

[code]

*rsync -avzh root@172.18.10.22:/home/wordpress/publichtml/ /home/wordpress/publichtml/*

[code]

20. Създаваме phpinfo.php файл със съдържание <?php phpinfo(); ?>, с който можем да следим заредените php модули и който ще бъде използван от Haproxy за проверка дали NODE2 e онлайн:

[code]

nano /home/wordpress/public_html/phpinfo.php

Поставяме - <?php phpinfo(); ?> и записваме

chown wordpress:wordpress /home/wordpress/public_html/phpinfo.php

[/code]

21. Конфигурираме NFS и HTTPD да се стартират при стартиране на системата:

[code]

chkconfig nfs on

chkconfig httpd on

[/code]

22. Описваме NFS дяла редактирайки /etc/fstab и mount-ваме:

[code]

*172.18.10.22:/home/wordpress/publichtml/wp-content /home/wordpress/publichtml/wp-content nfs defaults*

[/code]

[code]

mount -a

[/code]

23. Създаваме виртуален хост и променяме потребителя на httpd. Преправяме и формата на access_log-а, за да логва IP-то на клиента, а не на HAProxy-то, редактирайки /etc/httpd/conf/httpd.conf.

[code]

...

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

...

User wordpress

Group wordpress

...

<VirtualHost 172.18.10.23:80>

ServerName pgrucov.com

ServerAlias www.pgrucov.com

ServerAdmin admin@icn.bg

DocumentRoot /home/wordpress/public_html

ErrorLog logs/icn-cluster-error_log

CustomLog logs/icn-cluster-access_log combined

</VirtualHost>

...

[/code]

24. Задаваме на PHP да използва memcached за сесиите, редактирайки /etc/php.ini:

[code]

;session.save_handler = files

;session.save_path = "/var/lib/php/session"

session.save_handler = memcached

session.save_path = "172.18.10.22:11211"

[/code]

25. Създаваме директории за бекъп и bash скрипт, който да извършва достъп до NODE1 и да прави бекъп на базата данни и файловете:

[code]

mkdir -p /BACKUP/mysqldumps

nano /home/wordpress/backup.sh

ПОСТАВЯМЕ:

#!/bin/sh

mysqldump -h 172.18.10.22 -u root -pparola wordpress > /BACKUP/mysqldumps/wordpress.sql

rsync -az root@172.18.10.22:/home/wordptress/public_html /BACKUP/

ЗАПИСВАМЕ ФАЙЛА

[/code]

26. Правим файла executable и създаваме крон, който да го изпълнява всеки ден в 00:00 часа:

[code]

chmod +X /home/wordpress/backup.sh

crontab -e

ПОСТАВЯМЕ:

0 0 sh /home/wordpress/backup.sh > /dev/null 2>&1*

ЗАПИСВАМЕ:

[/code]

SERVER: LOAD BALACNER

27. Инсталираме HAproxy:

[code]

yum install haproxy

[/code]

28. Конфигурираме HAProxy да се стартира при стартиране на системата.

[code]

chkconfig haproxy on

[/code]

29. Настройваме HAProxy, редактирайки /etc/haproxy/haproxy.cfg. Комуникацията Node-LB се осъществява през локалните IP адреси.

Опцията "option httpchk" проверява дали скриптът phpinfo.php е наличен на нодовете и ако липсва, приема, че node-а е офлайн и го изключва от списъка. Удобно е при голям брой нодове.

[code]

frontend main :80*

*# acl urlstatic pathbeg -i /static /images /javascript /stylesheets*

*# acl urlstatic pathend -i .jpg .gif .png .css .js*

*# usebackend static if urlstatic*

default_backend app

#backend static

# balance roundrobin

# server static 127.0.0.1:4331 check

backend app

balance roundrobin

option httpchk HEAD /phpinfo.php HTTP/1.0

server node1 172.18.10.22:80 check

server node2 172.18.10.23:80 check

[/code]

30. Отваряме: http://pgrucov.com (IP-то на LoadBalancer-а) и инсталираме Wordpress.

Недостатъци на така организираната инфраструктура:

Не се разпределя натоварването, генерирано от mySQL сървъра.

Ниско ниво на Redundancy (при падане на NODE1 всичко спира да работи).

Round robin принцип на разпределяне на натоварването, което не дава възможност за избор на приоритетен сървър.

Екипът от Friendly Geeks и ICN.Bg остават насреща, за да даде окспертен отговор на всички Ваши технически въпроси.

Етикети: #tcp #optimizirane-na-sajt #proxy #http #zayavki #haproxy #load-balancing