Cách sử dụng HAProxy để thiết lập cân bằng tải HTTP trên VPS Ubuntu
Giới thiệu về HAProxy
HAProxy (Proxy khả dụng cao) là một trình cân bằng tải open-souce có thể cân bằng tải bất kỳ dịch vụ TCP nào. Nó đặc biệt thích hợp cho cân bằng tải HTTP vì nó hỗ trợ tính bền bỉ của phiên và xử lý lớp 7.
Với Mạng riêng DigitalOcean, HAProxy có thể được cấu hình như một giao diện user để cân bằng tải hai VPS thông qua kết nối mạng riêng.
Khúc dạo đầu
Ta sẽ sử dụng ba VPS ( server ) ở đây:
Server 1 - Cân bằng tải
Tên server : haproxy
Hệ điều hành: Ubuntu
IP công cộng: 1.1.1.1
IP riêng: 10.0.0.100
Server 2 - Nút 1
Tên server : lamp1
OS: LAMP trên Ubuntu
IP riêng: 10.0.0.1
Server 2 - Nút 2
Tên server : lamp2
OS: LAMP trên Ubuntu
IP riêng: 10.0.0.2
Cài đặt HAProxy
Sử dụng apt-get
để cài đặt HAProxy.
apt-get install haproxy
Ta cần kích hoạt HAProxy được khởi động bởi init script.
nano /etc/default/haproxy
Đặt tùy chọn ENABLED
thành 1
ENABLED=1
Để kiểm tra xem thay đổi này có được thực hiện đúng hay không, hãy thực hiện đúng tập lệnh init của HAProxy mà không có bất kỳ tham số nào. Bạn sẽ thấy những điều sau đây.
root@haproxy:~# service haproxy
Usage: /etc/init.d/haproxy {start|stop|reload|restart|status}
Cấu hình HAProxy
Ta sẽ di chuyển file cấu hình mặc định và tạo file của riêng ta .
mv /etc/haproxy/haproxy.cfg{,.original}
Tạo và chỉnh sửa file cấu hình mới:
nano /etc/haproxy/haproxy.cfg
Hãy để ta bắt đầu bằng cách thêm từng đoạn cấu hình vào file này:
global
log 127.0.0.1 local0 notice
maxconn 2000
user haproxy
group haproxy
Chỉ thị log
đề cập đến một server log hệ thống mà thông báo log sẽ được gửi đến. Trên Ubuntu rsyslog đã được cài đặt và chạy nhưng nó không nghe trên bất kỳ địa chỉ IP nào. Ta sẽ sửa đổi các file cấu hình của rsyslog sau.
Chỉ thị maxconn
chỉ định số lượng kết nối đồng thời trên giao diện user . Giá trị mặc định là 2000
và phải được điều chỉnh theo cấu hình VPS của bạn.
Chỉ thị user
và group
thay đổi quy trình HAProxy thành user / group được chỉ định. Những thứ này không nên thay đổi.
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 10000
timeout server 10000
Ta đang chỉ định các giá trị mặc định trong phần này. Các giá trị được sửa đổi là các chỉ thị timeout
khác nhau. Tùy chọn connect
chỉ định thời gian tối đa để đợi nỗ lực kết nối đến VPS thành công.
Thời gian chờ của server
client
và server
áp dụng khi client hoặc server được mong đợi xác nhận hoặc gửi dữ liệu trong quá trình TCP. HAProxy khuyên bạn nên đặt thời gian chờ của server
client
và server
thành cùng một giá trị.
Lệnh retries
đặt số lần thử lại sẽ thực hiện trên VPS sau khi kết nối không thành công.
option redispatch
cho phép phân phối lại phiên trong trường hợp kết nối bị lỗi. Vì vậy, độ bám của phiên sẽ bị overrides nếu VPS gặp sự cố.
listen appname 0.0.0.0:80
mode http
stats enable
stats uri /haproxy?stats
stats realm Strictly\ Private
stats auth A_Username:YourPassword
stats auth Another_User:passwd
balance roundrobin
option httpclose
option forwardfor
server lamp1 10.0.0.1:80 check
server lamp2 10.0.0.2:80 check
Điều này chứa cấu hình cho cả giao diện user và backend . Ta đang cấu hình HAProxy để lắng nghe trên cổng 80 cho appname
mà chỉ là một tên để xác định một ứng dụng. Các stats
thị stats
cho phép trang thống kê kết nối và bảo vệ nó bằng xác thực HTTP Cơ bản sử dụng thông tin đăng nhập được chỉ định bởi chỉ thị stats auth
.
Trang này có thể được xem bằng URL được đề cập trong stats uri
vì vậy trong trường hợp này, nó là http://1.1.1.1/haproxy?stats
; một bản demo của trang này có thể được xem ở đây .
Chỉ thị balance
chỉ định thuật toán cân bằng tải để sử dụng. Tùy chọn có sẵn là Round Robin ( roundrobin
), tĩnh Round Robin ( static-rr
), Connections Least ( leastconn
), Source ( source
), URI ( uri
) và URL tham số ( url_param
).
Thông tin về mỗi thuật toán có thể được lấy từ tài liệu chính thức .
Chỉ thị server
khai báo một server backend , cú pháp là:
server <name> <address>[:port] [param*]
Tên ta đề cập ở đây sẽ xuất hiện trong log và cảnh báo. Có nhiều tham số được hỗ trợ bởi chỉ thị này và ta sẽ sử dụng tham số check
và cookie
trong bài viết này. Tùy chọn check
cho phép kiểm tra tình trạng trên VPS, nếu không, VPS là
luôn được coi là có sẵn.
Khi bạn đã hoàn tất việc cấu hình , hãy bắt đầu dịch vụ HAProxy:
service haproxy start
Kiểm tra cân bằng tải và chuyển đổi dự phòng
Để kiểm tra cài đặt này, hãy tạo một tập lệnh PHP trên tất cả các web server của bạn ( server backend - LAMP1 và LAMP2 tại đây).
/var/www/file.php
<?php
header('Content-Type: text/plain');
echo "Server IP: ".$_SERVER['SERVER_ADDR'];
echo "\nClient IP: ".$_SERVER['REMOTE_ADDR'];
echo "\nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR'];
?>
Bây giờ ta sẽ sử dụng curl và yêu cầu file này nhiều lần.
> curl http://1.1.1.1/file.php
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
> curl http://1.1.1.1/file.php
Server IP: 10.0.0.2
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
> curl http://1.1.1.1/file.php
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Lưu ý ở đây cách HAProxy bật tắt kết nối giữa LAMP1 và LAMP2, đây là cách Round Robin hoạt động. IP client mà ta thấy ở đây là địa chỉ IP Riêng của bộ cân bằng tải và tiêu đề X-Forwarded-For
là IP của bạn.
Để xem chuyển đổi dự phòng hoạt động như thế nào, hãy truy cập web server và dừng dịch vụ:
lamp1@haproxy:~#service apache2 stop
Gửi lại các yêu cầu bằng curl
để xem mọi thứ hoạt động như thế nào.
Mức độ dính của phiên
Nếu ứng dụng web của bạn cung cấp nội dung động dựa trên các phiên đăng nhập của user (ứng dụng nào thì không), khách truy cập sẽ gặp phải những điều kỳ lạ do chuyển đổi liên tục giữa các VPS. Độ bám của phiên đảm bảo khách truy cập sẽ sử dụng VPS đã phục vụ yêu cầu đầu tiên của họ. Điều này có thể thực hiện được bằng cách gắn thẻ từng server backend với một cookie.
Ta sẽ sử dụng đoạn mã PHP sau để chứng minh cách hoạt động của độ dính phiên.
/var/www/session.php
<?php
header('Content-Type: text/plain');
session_start();
if(!isset($_SESSION['visit']))
{
echo "This is the first time you're visiting this server";
$_SESSION['visit'] = 0;
}
else
echo "Your number of visits: ".$_SESSION['visit'];
$_SESSION['visit']++;
echo "\nServer IP: ".$_SERVER['SERVER_ADDR'];
echo "\nClient IP: ".$_SERVER['REMOTE_ADDR'];
echo "\nX-Forwarded-for: ".$_SERVER['HTTP_X_FORWARDED_FOR']."\n";
print_r($_COOKIE);
?>
Mã này tạo một phiên PHP và hiển thị số lần xem trang trong một phiên duy nhất.
Phương pháp chèn cookie
Trong phương pháp này, tất cả các phản hồi từ HAProxy tới client sẽ chứa tiêu đề Set-Cookie:
với tên của server backend làm giá trị cookie của nó. Vì vậy, về sau client (trình duyệt web) sẽ bao gồm cookie này với tất cả các yêu cầu của nó và HAProxy sẽ chuyển tiếp yêu cầu đến server backend phù hợp dựa trên giá trị cookie.
Đối với phương pháp này, bạn cần thêm chỉ thị cookie
và sửa đổi chỉ thị server
trong phần listen
cookie SRVNAME insert
server lamp1 10.0.0.1:80 cookie S1 check
server lamp2 10.0.0.2:80 cookie S2 check
Điều này khiến HAProxy thêm tiêu đề Set-Cookie:
với cookie có tên SRVNAME
có giá trị là S1
hoặc S2
dựa vào đó chương trình backend trả lời yêu cầu. Sau khi điều này được thêm vào, hãy khởi động lại dịch vụ:
service haproxy restart
và sử dụng curl
để kiểm tra cách thức hoạt động.
> curl -i http://1.1.1.1/session.php
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:11:22 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Set-Cookie: PHPSESSID=l9haakejnvnat7jtju64hmuab5; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 143
Connection: close
Content-Type: text/plain
Set-Cookie: SRVNAME=S1; path=/
This is the first time you're visiting this server
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
)
Đây là yêu cầu đầu tiên ta đưa ra và nó đã được LAMP1 trả lời như ta có thể thấy từ Set-Cookie: SRVNAME=S1; path=/
. Bây giờ, để mô phỏng những gì một trình duyệt web sẽ làm cho yêu cầu tiếp theo, ta thêm các cookie này vào yêu cầu bằng cách sử dụng tham số --cookie
của curl.
> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=l9haakejnvnat7jtju64hmuab5;SRVNAME=S1;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:11:45 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 183
Connection: close
Content-Type: text/plain
Your number of visits: 1
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.87.127
Array
(
[PHPSESSID] => l9haakejnvnat7jtju64hmuab5
[SRVNAME] => S1
)
> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=l9haakejnvnat7jtju64hmuab5;SRVNAME=S1;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:11:45 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 183
Connection: close
Content-Type: text/plain
Your number of visits: 2
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.87.127
Array
(
[PHPSESSID] => l9haakejnvnat7jtju64hmuab5
[SRVNAME] => S1
)
Cả hai yêu cầu này đều được LAMP1 phục vụ và phiên được duy trì đúng cách. Phương pháp này rất hữu ích nếu bạn muốn có tất cả các file trên web server .
Phương pháp tiền tố cookie
Mặt khác, nếu bạn chỉ muốn có độ dính cho các cookie cụ thể hoặc không muốn có một cookie riêng cho độ dính phiên, tùy chọn prefix
là dành cho bạn.
Để sử dụng phương pháp này, hãy sử dụng lệnh cookie
sau:
cookie PHPSESSID prefix
PHPSESSID
có thể được thay thế bằng tên cookie của bạn . Chỉ thị server
vẫn giống như cấu hình trước đó.
Bây giờ ta hãy xem cách này hoạt động.
> curl -i http://1.1.1.1/session.php
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:36:27 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Set-Cookie: PHPSESSID=S1~6l2pou1iqea4mnhenhkm787o56; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 143
Content-Type: text/plain
This is the first time you're visiting this server
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
)
Lưu ý cách cookie server
S1
được đặt trước cookie phiên. Bây giờ, hãy gửi thêm hai yêu cầu với cookie này.
> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=S1~6l2pou1iqea4mnhenhkm787o56;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:36:45 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 163
Content-Type: text/plain
Your number of visits: 1
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
[PHPSESSID] => 6l2pou1iqea4mnhenhkm787o56
)
> curl -i http://1.1.1.1/session.php --cookie "PHPSESSID=S1~6l2pou1iqea4mnhenhkm787o56;"
HTTP/1.1 200 OK
Date: Tue, 24 Sep 2013 13:36:54 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.8
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Length: 163
Content-Type: text/plain
Your number of visits: 2
Server IP: 10.0.0.1
Client IP: 10.0.0.100
X-Forwarded-for: 117.213.X.X
Array
(
[PHPSESSID] => 6l2pou1iqea4mnhenhkm787o56
)
Ta có thể thấy rõ rằng cả hai yêu cầu đều được LAMP1 phục vụ và phiên đang hoạt động hoàn hảo.
Cấu hình ghi log cho HAProxy
Khi ta bắt đầu cấu hình HAProxy, ta đã thêm một dòng: log 127.0.0.1 local0 notice
log hệ thống đến địa chỉ IP localhost. Nhưng theo mặc định, rsyslog trên Ubuntu không lắng nghe trên bất kỳ địa chỉ nào. Vì vậy, ta phải làm cho nó làm như vậy.
Chỉnh sửa file cấu hình của rsyslog.
nano /etc/rsyslog.conf
Thêm / Chỉnh sửa / Bỏ ghi chú các dòng sau:
$ModLoad imudp
$UDPServerAddress 127.0.0.1
$UDPServerRun 514
Bây giờ rsyslog sẽ hoạt động trên cổng UDP 514 trên địa chỉ 127.0.0.1 nhưng tất cả các thông báo HAProxy sẽ chuyển đến /var/log/syslog
nên ta phải tách chúng ra.
Tạo luật cho log HAProxy.
nano /etc/rsyslog.d/haproxy.conf
Thêm dòng sau vào nó.
if ($programname == 'haproxy') then -/var/log/haproxy.log
Bây giờ khởi động lại dịch vụ rsyslog:
service rsyslog restart
Điều này ghi tất cả các thông báo HAProxy và truy cập log vào /var/log/haproxy.log
.
Keepalives trong HAProxy
Theo chỉ thị listen
, ta đã sử dụng option httpclose
để thêm tiêu đề Connection: close
. Thao tác này cho client (trình duyệt web) đóng kết nối sau khi nhận được phản hồi.
Nếu bạn muốn bật keep-alives trên HAProxy, hãy thay thế dòng option httpclose
bằng:
option http-server-close
timeout http-keep-alive 3000
Đặt thời gian chờ duy trì một cách khôn ngoan để một vài kết nối không tiêu hao hết tài nguyên của bộ cân bằng tải.
Thử nghiệm Keepalives
Keepalives có thể được kiểm tra bằng cách sử dụng curl
bằng cách gửi nhiều yêu cầu cùng một lúc. Đầu ra không cần thiết sẽ được bỏ qua trong ví dụ sau:
> curl -v http://1.1.1.1/index.html http://1.1.1.1/index.html
* About to connect() to 1.1.1.1 port 80 (#0)
* Trying 1.1.1.1... connected
> GET /index.html HTTP/1.1
> User-Agent: curl/7.23.1 (x86_64-pc-win32) libcurl/7.23.1 OpenSSL/0.9.8r zlib/1.2.5
> Host: 1.1.1.1
> Accept: */*
>
......[Output omitted].........
* Connection #0 to host 1.1.1.1 left intact
* Re-using existing connection! (#0) with host 1.1.1.1
* Connected to 1.1.1.1 (1.1.1.1) port 80 (#0)
> GET /index.html HTTP/1.1
> User-Agent: curl/7.23.1 (x86_64-pc-win32) libcurl/7.23.1 OpenSSL/0.9.8r zlib/1.2.5
> Host: 1.1.1.1
> Accept: */*
>
.......[Output Omitted].........
* Connection #0 to host 1.1.1.1 left intact
* Closing connection #0
Trong kết quả này, ta phải tìm dòng: Re-using existing connection! (#0) with host 1.1.1.1
, cho biết rằng curl đã sử dụng cùng một kết nối để thực hiện các yêu cầu tiếp theo.
Các tin liên quan
Cách tạo Omega 4 Drupal Subtheme trên Ubuntu VPS2013-09-26
Cách sử dụng tính năng trùng lặp với GPG để tự động hóa an toàn các bản backup trên Ubuntu
2013-09-19
Cách cấu hình một cụm đa node với Cassandra trên VPS Ubuntu
2013-09-11
Cách theo dõi log xác thực hệ thống trên Ubuntu
2013-09-05
Cách bắt đầu với Jekyll trên VPS Ubuntu
2013-08-28
Cách sử dụng Dig, Whois và Ping trên Ubuntu VPS để truy vấn dữ liệu DNS
2013-08-23
Cách thiết lập Sass trên VPS của bạn đang chạy trên Ubuntu
2013-08-14
Cách cài đặt Cassandra và chạy một cụm node đơn trên VPS Ubuntu
2013-08-08
Cách cài đặt CouchDB từ nguồn trên VPS Ubuntu 13.04 x64
2013-08-06
Cách quản lý gói trong Ubuntu và Debian với Apt-Get & Apt-Cache
2013-08-06