Archive for the ‘Load Balancing’ Category

Trong mô hình Load Balancing, HAProxy đứng giữa client và các backend servers, vì vậy kết nối mã hóa SSL giữa client và server sẽ có thể được thực hiện theo các cách thức sau:

  • Thực hiện yêu cầu kết nối mã hóa SSL giữa Client và HAProxy, còn từ HAProxy thực hiện các kết nối không mã hóa với backend servers. Phương thức này gọi là SSL Termination

  • Thực hiện yêu cầu kết nối trực tiếp giữa Client và các backend servers. Tuy nhiên, khi đó chúng ta lại không thể thực hiện Add/Set phần Header. Phương thức này gọi là SSL Passthrough

  • Một cách thức khác là kết hợp cả 02 cách thức trên mà vừa đảm bảo phân tải xử lý của CPU, cũng như cho phép thực hiện chỉnh sửa thông tin Header.

Bài viết đi vào mô hình thực hiện ở cách thức kết nối SSL theo cách thức SSL Termination.

haproxy-ssl

Trong bài viết này, tôi sẽ hướng dẫn cấu hình HAProxy sử dụng SSL với  self-signed certificate và LetsEncrypt

1. Tự tạo self-signed certificate

Đây là certificate mà ta sẽ tự tạo ra trên chính server. Certificate này không được xác thực bởi các nhà cung cấp chứng chỉ số (CA). Mục đích tạo self-signed certificate là để kiểm tra hoặc sử dụng trong môi trường mạng local.

Các bước tạo self-signed certificate và cấu hình HAProxy sử dụng SSL như sau:

Step1: Tạo private key

Thực hiện tạo key cho local domain “example.local”.

  • Tạo thư mục chứa certificate
mkdir -p /etc/ssl/example.local
cd /etc/ssl/example.local
  • Tạo key với mã hóa RSA
openssl genrsa -des3 -out example.key 2048

root@vnsys:/etc/ssl/example.local# openssl genrsa -des3 -out example.key 2048
Generating RSA private key, 2048 bit long modulus
…………………………………………………+++
……………………………..+++
e is 65537 (0x10001)
Enter pass phrase for example.key:
Verifying – Enter pass phrase for example.key:

Quá trình tạo key ở trên yêu cầu nhập pass phrase. Để remove passphrase (mục đích là bỏ qua quá trình hỏi pass phrase) thực hiện như sau:

openssl rsa -in example.key -out example.key

root@vnsys:/etc/ssl/example.local# openssl rsa -in example.key -out example.key
Enter pass phrase for example.key:
writing RSA key

Step2: Đăng ký certificate (Certificate Signing Request -CSR)

Dựa vào key đã tạo ở Step1, chúng ta thực hiện đăng ký certificate

openssl req -new -key example.key -out example.csr

root@vnsys:/etc/ssl/example.local# openssl req -new -key example.key -out example.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
Country Name (2 letter code) [AU]:VN
State or Province Name (full name) [Some-State]:HN
Locality Name (eg, city) []:CG
Organization Name (eg, company) [Internet Widgits Pty Ltd]:IT
Organizational Unit Name (eg, section) []:Example Inc
Common Name (e.g. server FQDN or YOUR name) []:example.local
Email Address []:

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Step3: Tạo certificate – CRT

Dựa vào CSR ở trên, chúng ta tạo một self-signed certificate, với hiệu lực 365 ngày

openssl x509 -req -days 365 -in example.csr -signkey example.key -out example.crt

root@vnsys:/etc/ssl/example.local# openssl x509 -req -days 365 -in example.csr -signkey example.key -out example.crt
Signature ok
subject=/C=VN/ST=HN/L=CG/O=IT/OU=Example Inc/CN=example.local
Getting Private key

Step4: Mở rộng key và cert thành tệp pem

Tệp pem là tệp tin chứa định dạng có thể chỉ public certificate hoặc có thể gồm tập public key, private key và root certificate kết hợp với nhau.

Chúng ta thực hiện nối private key và certificate ở trên để tạo thành tệp pem

cat example.key example.crt >>example.pem

Step5: Cấu hình HAProxy với SSL cho website

Sau khi đã có tệp pem, chúng ta cấu hình HAProxy để cho phép xử lý luồng kết nối với SSL.

Phần frontend

Chúng ta gán listen port cho https với port default là 443, không sử dụng giao thức sslv3, và chỉ định vị trí tệp pem “example.pem”.

  • Sử dụng đồng thời cả 02 giao thức HTTP và HTTPS
#Frontend Section
frontend http-in
        bind *:80
    bind *:443 ssl no-sslv3 crt /etc/ssl/example.local/example.pem 
        acl example-acl hdr(host) -i example.local
        use_backend example if example-acl

Ở đây chúng ta sử dụng tham số “crt” (certificate) trong bind. Thiết lập này được sử dụng khi cấu hình SSL, chỉ định đường dẫn tệp pem. Chúng ta có thể khai báo nhiều “crt” với nhiều tệp pem được chỉ định cho nhiều site mà sử dụng SSL.

  • Chỉ sử dụng HTTPS

Khi đó chúng ta cần thêm tùy chọn redirect khi truy cập http đến https

Redirect toàn bộ các site trong cấu hình HAProxy, thì sử dụng:

redirect scheme https code 301 if !{ ssl_fc }

Redirect với site chỉ định

redirect scheme https if { hdr(Host) -i example.local } !{ ssl_fc }

Khi đó, cấu hình frontend như sau:

## Frontend section
frontend http-in
        bind *:80
        bind *:443 ssl no-sslv3 crt /etc/ssl/example.local/example.pem
        redirect scheme https if { hdr(Host) -i example.local } !{ ssl_fc } 
        acl example-acl hdr(host) -i example.local
        use_backend example if example-acl

Note: Thay vì sử dụng default port cho https là 443, chúng ta muốn redirect đến https với một cổng tùy chọn, chẳng hạn 8443. Khi đó cấu hình tùy chọn như sau:

## Frontend section
frontend http-in
        bind *:80
        bind *:8443 ssl no-sslv3 crt /etc/ssl/example.local/example.pem
        http-request replace-value Host (.*):80 \1
        http-request redirect location https://%[req.hdr(Host)]:8443%[capture.req.uri] if !{ ssl_fc }
        acl example-acl hdr(host) -i   example.local
        use_backend example if example-acl

Phần Backend

Phần này, chúng ta sẽ khai báo thông tin thuật toán load balancing sẽ sử dụng, các thông tin web server , các tùy chọn về log và thiết lập tùy chọn header.

backend example
        balance roundrobin
        server server1 192.168.10.111:8080 weight 1 check
        server server2 192.168.10.112:8080 weight 1 check
        server server3 192.168.10.113:8080 weight 1 check
        option httplog
        option forwardfor
        http-request set-header X-Forwarded-Port %[dst_port]
        http-request add-header X-Forwarded-Proto https if { ssl_fc }

Ở đây, chúng ta có một số tùy chọn:

option forwardfor : Được sử dụng để thêm header “X-Forwarded-For”, vì vậy backend có thể nhận được địa chỉ IP thực của client truy cập. Nếu không có tùy chọn này thì backend sẽ chỉ nhận được thông tin IP của HAProxy.

http-request set-header X-Forwarded-Port %[dst_port] : thiết lập một header “X-Forwarded-Port” vì vậy mà backend biết được port nào để sử dụng khi redirect URLs.

http-request add-header X-Forwarded-Proto https if { ssl_fc } : Thêm header X-Forwarded-Proto với thiết lập scheme là https nếu yêu cầu truy cập https. Cái này, cho phép backend xác định được scheme để sử dụng khi gửi URL lúc redirect

Khi đó, nội dung tệp cấu hình HAProxy đầy đủ cho site example.local sử dụng SSL như sau:

# Global settings
global
        log 127.0.0.1   local0
        pidfile     /var/run/haproxy.pid
        stats socket /var/lib/haproxy/stats
        maxconn 100000
        user haproxy
        group haproxy
        daemon
        quiet
# Proxies settings
## Defaults section
defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option      redispatch
        maxconn     100000
        retries                 3
        timeout http-request    5s
        timeout queue           30s
        timeout connect         30s
        timeout client          30s
        timeout server          30s
        timeout http-keep-alive 30s
        timeout check           30s
## Frontend section
frontend http-in
        bind *:80
        bind *:443 ssl no-sslv3 crt /etc/ssl/example.local/example.pem
        redirect scheme https if { hdr(Host) -i example.local } !{ ssl_fc } 
        acl example-acl hdr(host) -i example.local
        use_backend example if example-acl
backend example
        balance roundrobin
        server server1 192.168.10.111:8080 weight 1 check
        server server2 192.168.10.112:8080 weight 1 chec
        server server3 192.168.10.113:8080 weight 1 check
        option httplog
        option forwardfor
        http-request set-header X-Forwarded-Port %[dst_port]
        http-request add-header X-Forwarded-Proto https if { ssl_fc }
## Statistics settings
listen statistics
        bind *:1986
        stats enable
        stats admin if TRUE
        stats hide-version
        stats realm Haproxy\ Statistics
        stats uri /stats
        stats refresh 30s
        stats auth keepwalking86:ILoveVietnam$

2. Sử SSL sử dụng LetsEncrypt

Trong phần này, chúng ta sẽ sử dụng certificate được cung cấp bởi một nhà cung cấp certificate (certificate authority – CA). Sử dụng certificate này cho phép website được xác thực khi truy cập internet. Với điều kiện hạn chế, chúng ta có thể sử dụng certificate miễn phí của một số nhà cung cấp.

Trong phần cấu hình này, chúng ta sử dụng Let’s Encrypt để nhận certificate miễn phí với mỗi lần renew là 90 ngày.

Yêu cầu:

  • Website publish với tên miền internet.

Step1: Cài đặt Certbot

Để lấy certificate từ Let’s Encrypt chúng ta sử dụng công cụ Certbot

  • Cài đặt LetsEncrypt trên Ubuntu-16.04+
sudo add-apt-repository -y ppa:certbot/certbot
sudo apt-get update
sudo apt-get install -y certbot
  • Cài đặt LetsEncrypt trên CentOS 7
yum -y install epel-release
yum -y install certbot

Step2: Cấu hình HAProxy khi chưa https

Certbot có thể tự động lấy certificate, nhưng điều kiện cần là nó phải xác minh được domain hợp lệ. Tôi cấu hình haproxy cho website với tên miền mymusic.vn (thay mymusic.vn với thông tin website thực cần cấu hình) như sau:

# Global settings
global
        pidfile     /var/run/haproxy.pid
        maxconn 100000
        user haproxy
        group haproxy
        daemon
        quiet
        stats socket /var/lib/haproxy/stats
        log 127.0.0.1   local0

# Proxies settings
## Defaults section
defaults
        log     global
        mode    http
        option  httplog
        option  forwardfor
        option  dontlognull
        retries 3
        option      redispatch
        maxconn     100000
        retries                 3
        timeout http-request    5s
        timeout queue           10s
        timeout connect         10s
        timeout client          10s
        timeout server          10s
        timeout http-keep-alive 10s
        timeout check           10s

## Frontend section
frontend http-in
        bind *:80
        acl mymusic-acl hdr(host) -i mymusic.vn
        use_backend mymusic if mymusic-acl
## Backend section
backend mymusic
        balance roundrobin
        server server1 192.168.10.111:8080 weight 1 check
        server server2 192.168.10.112:8080 weight 1 check
        server server3 192.168.10.113:8080 weight 1 check
## Statistics settings
listen statistics
        bind *:1986
        stats enable
        stats admin if TRUE
        stats hide-version
        stats realm Haproxy\ Statistics
        stats uri /stats
        stats refresh 30s
        stats auth keepwalking86:ILoveVietnam$

Step3: Tạo New letsencrypt certificate bằng certbot

Nếu muốn tạo certificate và cấu hình haproxy, chúng ta cần cấp phép cho LetsEncrypt. Khi đó cần thiết lập một site stand-alone để listen khi ủy quyền cho LetsEncrypt.

Khi yêu cầu một certificate từ LetsEncrypt, nó sẽ yêu cầu được truy cập vào tệp tin được ủy quyền theo dạng đường dẫn “http://your-domain/well-known/acme-challenge/” và đường dẫn này bind đến cổng 80 cho yêu cầu http và 443 cho https. Khi đó chúng ta thực hiện yêu cầu certificate với một trong hai cách sau:

Cách 1: Stop HAProxy

Chẳng hạn haproxy đang listen ở port 80, khi đó stop haproxy và thực hiện chạy dòng lệnh sau để yêu cầu certificate từ LetsEncrypt

systemctl stop haproxy
certbot certonly --standalone -d mymusic.vn --non-interactive --agree-tos --email keepwalking86@mymusic.vn

root@vnsys:/home/keepwalking# certbot certonly –standalone -d mymusic.vn –non-interactive –agree-tos –email keepwalking86@mymusic.vn
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mymusic.vn
Waiting for verification…
Cleaning up challenges

IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/mymusic.vn/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/mymusic.vn/privkey.pem
Your cert will expire on 2019-04-29. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew all of your certificates, run
“certbot renew”
– Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
– If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let’s Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

Sau khi kết thúc quá trình nhận certificate cho site mymusic.vn từ LetsEncrypt thành công, khi đó thư mục chứa các tệp certificate, key nằm ở /etc/letsencrypt/live/mymusic.vn/

Cách 2: Haproxy vẫn hoạt động trên port 80

Để tránh xung đột port 80 với HAProxy, chúng ta sẽ cấu hình haproxy để bảo cho LetsEncrypt listen với một port khác, chẳng hạn 8080. Thực hiện cấu hình haproxy như sau:

  • Thêm tùy chọn acl trong phần frontend

Sử dụng cổng 80 cùng với site mymusic.vn nhưng khi đó, cần tạo acl để truy cập URL mà chứa chuỗi “/.well-known/acme-challenge/”

acl letsencrypt-acl path_beg /.well-known/acme-challenge/
use_backend letsencrypt if letsencrypt-acl
  • Cấu hình phần backend

Khai báo cổng listen sẽ sử dụng

backend letsencrypt
    server letsencrypt 127.0.0.1:8080

Khi đó reload haproxy và thực hiện tạo certificate như sau:

certbot certonly --standalone -d mymusic.vn --non-interactive --agree-tos --email keepwalking86@mymusic.vn --http-01-port=8080

root@vnsys:/home/keepwalking# certbot certonly –standalone -d mymusic.vn –non-interactive –agree-tos –email keepwalking86@mymusic.vn –http-01-port=8080
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mymusic.vn
Waiting for verification…
Cleaning up challenges

IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/mymusic.vn/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/mymusic.vn/privkey.pem
Your cert will expire on 2019-04-29. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew all of your certificates, run
“certbot renew”
– If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let’s Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le

Trong đó, thuộc tính các tham số truyền vào như sau:

–standalone: Sử dụng chế độ standalone để đạt một certificate khi chúng ta không muốn sử dụng hoặc không có web server đang tồn tại. Sử dụng standalone, chúng ta kết hợp gồm lệnh “certonly”

-d mymusic.vn: chỉ định public domain hợp lệ “mymusic.vn” mà trỏ bản ghi “A” vào địa chỉ IP Public của haproxy. Tùy chọn “-d” có thể được sử dụng cho nhiều domain và yêu cầu cùng một certificate.

–non-interactive –agree-tos –email keepwalking86@mymusic.vn: Cho phép xác nhận các điều khoản, cũng như vào thông tin email tự động khi LetsEncrypt yêu cầu

–http-01-port=8080: Cái này bảo cho stand-alone server sẽ listen trên port 8080 của một request HTTP.

Step4: Mở rộng key và cert thành tệp pem

Tệp pem là tệp tin chứa định dạng có thể chỉ public certificate hoặc có thể gồm tập public key, private key và root certificate kết hợp với nhau.

Chúng ta thực hiện nối private key và certificate ở trên để tạo thành tệp pem.

cd /etc/letsencrypt/live/mymusic.vn/
cat fullchain.pem privkey.pem | tee mymusic.vn.pem

Step5: Cấu hình HAProxy sử dụng LetsEncrypt SSL

Sau khi đã có tệp pem, chúng ta cấu hình HAProxy để cho phép xử lý luồng kết nối với SSL.

Phần frontend

Chúng ta gán listen port cho https với port default là 443, không sử dụng giao thức sslv3, và chỉ định vị trí tệp pem “mymusic.vn.pem”.

  • Nếu HAProxy sử dụng đồng thời cả HTTP và HTTPS, khi đó cấu hình như sau:
## Frontend section
frontend http-in
        bind *:80
          bind *:443 ssl no-sslv3 crt /etc/letsencrypt/live/mymusic.vn/mymusic.vn.pem
        acl mymusic-acl hdr(host) -i mymusic.vn
        use_backend mymusic if mymusic-acl
  • HAProxy chỉ sử dụng HTTPS

Khi đó chúng ta cần thêm tùy chọn redirect khi truy cập http đến https

Redirect với site mymusic.vn

redirect scheme https if { hdr(Host) -i mymusic.vn } !{ ssl_fc }

Khi đó, cấu hình frontend như sau:

## Frontend section
frontend http-in
        bind *:80
        bind *:443 ssl no-sslv3 crt /etc/letsencrypt/live/mymusic.vn/mymusic.vn.pem
        redirect scheme https if { hdr(Host) -i mymusic.vn } !{ ssl_fc } 
        acl mymusic-acl hdr(host) -i mymusic.vn
        use_backend mymusic if mymusic-acl

Phần Backend

Chúng ta sẽ khai báo thông tin thuật toán load balancing sẽ sử dụng, các thông tin web server , các tùy chọn về log và thiết lập tùy chọn header.

backend mymusic
        balance roundrobin
        server server1 192.168.10.111:8080 weight 1 check
        server server2 192.168.10.112:8080 weight 1 chec
        server server3 192.168.10.113:8080 weight 1 check
        option httplog
        option forwardfor
        http-request set-header X-Forwarded-Port %[dst_port]
        http-request add-header X-Forwarded-Proto https if { ssl_fc }

Ở đây, chúng ta có một số tùy chọn:

option forwardfor : Được sử dụng để thêm header “X-Forwarded-For”, vì vậy backend có thể nhận được địa chỉ IP thực của client truy cập. Nếu không có tùy chọn này thì backend sẽ chỉ nhận được thông tin IP của HAProxy.

http-request set-header X-Forwarded-Port %[dst_port] : thiết lập một header “X-Forwarded-Port” vì vậy mà backend biết được port nào để sử dụng khi redirect URLs.

http-request add-header X-Forwarded-Proto https if { ssl_fc } : Thêm header X-Forwarded-Proto với thiết lập scheme là https nếu yêu cầu truy cập https. Cái này, cho phép backend xác định được scheme để sử dụng khi gửi URL lúc redirect

Khi đó, nội dung tệp cấu hình HAProxy đầy đủ cho site mymusic.vn sử dụng SSL như sau:

# Global settings
global
        log 127.0.0.1   local0
        pidfile     /var/run/haproxy.pid
        stats socket /var/lib/haproxy/stats
        maxconn 100000
        user haproxy
        group haproxy
        daemon
        quiet
# Proxies settings
## Defaults section
defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        option      redispatch
        maxconn     100000
        retries                 3
        timeout http-request    5s
        timeout queue           30s
        timeout connect         30s
        timeout client          30s
        timeout server          30s
        timeout http-keep-alive 30s
        timeout check           30s
## Frontend section
frontend http-in
        bind *:80
        bind *:443 ssl no-sslv3 crt /etc/letsencrypt/live/mymusic.vn/mymusic.vn.pem
        redirect scheme https if { hdr(Host) -i mymusic.vn } !{ ssl_fc } 
        acl mymusic-acl hdr(host) -i mymusic.vn
        use_backend mymusic if mymusic-acl
backend mymusic
        balance roundrobin
        server server1 192.168.10.111:8080 weight 1 check
        server server2 192.168.10.112:8080 weight 1 chec
        server server3 192.168.10.113:8080 weight 1 check
        option httplog
        option forwardfor
        http-request set-header X-Forwarded-Port %[dst_port]
        http-request add-header X-Forwarded-Proto https if { ssl_fc }
## Statistics settings
listen statistics
        bind *:1986
        stats enable
        stats admin if TRUE
        stats hide-version
        stats realm Haproxy\ Statistics
        stats uri /stats
        stats refresh 30s
        stats auth keepwalking86:ILoveVietnam$

Tham khảo thêm về LetsEncrypt

 

Cân bằng tải trong HAProxy

Posted: Tháng Một 11, 2019 in HAProxy, Load Balancing
Thẻ:,

Trong bài viết này, chúng ta sẽ giới thiệu về một số thuật toán cân bằng tải phổ biến trong HAProxy, và cách thức cố định session với sticky session

1. Các thuật toán cân bằng tải

HAProxy hỗ trợ các thuật toán sau: roundrobin, static-rr, leastconn, first, source, uri, url_parm, hdr, rdp-cookie. Ở đây, chúng ta sẽ giới thiệu một số thuật toán thường được sử dụng.

1.1 Roundrobin

Là thuật toán luân chuẩn theo vòng. Các server sẽ được sử dụng lần lượt theo vòng, phụ thuộc vào giá trị trọng số của nó. roundrobin là thuật toán được sử dụng mặc định load balancing khi không có thuật toán nào được chỉ định.

backend web-backend
    option httplog
    option forwardfor
    server web1 192.168.1.110:8080 check
    server web2 192.168.1.111:8080 check
    server web3 192.168.1.112:8080 check

Dựa vào khả năng xử lý của từng server, chúng ta sẽ thay đổi giá trị trọng số của từng server để phân phối tải đến các server khác nhau. Sử dụng tham số “weight” để thay đổi trọng số. Tỷ lệ tải của các server sẽ tỷ lệ thuận trọng số của chúng so với tổng trọng số của tất cả server. Vì vậy mà server nào có trọng số càng cao, thì yêu cầu tải lên nó cũng sẽ cao. Ví dụ cân bằng tải khi thiết lập weight

backend web-backend
    balance  roundrobin
    option httplog
    option forwardfor
    server web1 192.168.1.110:8080 check weight 2
    server web2 192.168.1.111:8080 check weight 2
    server web3 192.168.1.112:8080 check weight 1

Khi đó mỗi 05 request, 2 request đầu tiên sẽ được chuyển tiếp lần lượt đến server web1 và web2, 3 request sau sẽ thực hiện chuyển tiếp lần lượt đến server web1, web2 và web3.

Mặc định weight có giá trị là 1, giá trị tối đa của weight là 256. Nếu server giá trị weight là 0, khi đó nó sẽ không tham gia vào cụm server trong load balancing.

1.2 leastconn

Đây là thuật toán dựa trên tính toán số lượng kết nối để thực hiện cân bằng tải cho server, nó sẽ tự động lựa chọn server với số lượng kết nối đang hoạt động là nhỏ nhất, để lượng connection giữa các server là tương đương nhau.

Thuật toán này khắc phục được tình trạng một số server có lượng connection rất lớn (do duy trì trạng thái connection), trong khi một số server khác thì lượng tải hay connection thấp.

backend web-backend
      leastconn
    option httplog
    option forwardfor
    server web1 192.168.1.110:8080 check
    server web2 192.168.1.111:8080 check
    server web3 192.168.1.112:8080 check

Thuật toán này hoạt động tốt khi mà hiệu suất và khả năng tải của các server là tương đương nhau.

2. Sticky session

Trong môi trường web, nhiều khi chúng ta cần cố định session của user, như để duy trì trạng thái login. Khi đó, chúng ta cần cố định session trên một server. HAProxy hỗ trợ một số thuật toán Load Balancing duy trì trạng thái kết nối mà cho phép cố định session như hdr, rdp-cookie, source, uri hoặc url_param. Chẳng hạn như:

backend cms
    balance source
    hash-type consistent
    server web1 192.168.10.110:8080 check
    server web2 192.168.10.111:8080 check
    server web3 192.168.10.112:8080 check

Nếu chúng ta muốn cố định session mà vẫn sử dụng các thuật toán load balancing như roundrobin, leastconn, hoặc static-rr, khi đó chúng ta sử dụng “Sticky Session”. Sticky session cho phép cố định session của users mà sử dụng cookie, và HAProxy sẽ điều phối để luôn request từ một user đến cùng một server.

Để sử dụng sticky session trong HAProxy, chúng ta thêm tùy chọn “cookie cookie_name insert/prefix” vào trong phần backend.

2.1 Session cookie được thiết lập bởi HAProxy

Khi đó sử dụng ‘cookie cookie_name insert <options>’. “cookie_name” là giá trị mà HAProxy sẽ chèn vào (insert). Khi client quay lại (tức là cũng là client này và request tiếp theo), HAProxy sẽ biết được server nào để chọn cho client này. Ví dụ:

    cookie  WEB insert
    server web1 192.168.1.110:8080 cookie web1 check
    server web2 192.168.1.111:8080 cookie web2 check
    server web3 192.168.1.112:8080 cookie web3 check

Chúng ta check thử xem HAProxy sẽ response giá trị cookie như thế nào khi sử dụng insert

session cookie setup by haproxy

Khi đó chúng ta thấy giá trị cookie mà HAProxy phản hồi cho client là “WEB=web1”

2.2 Sử dụng session cookie của ứng dụng

Khi đó sử dụng “cookie SESSION_ID prefix <option>”. “SESSION_ID” là tên cookie của application như PHPSESSID, JSESSID, laravel_session, … Khi đó, HAProxy sẽ sử dụng session id cookie mà được tạo bởi application để duy trì kết nối giữa một client và một server backend. Cách thức hoạt động, đó là HAProxy sẽ mở rộng cookie với một SESSION ID cookie hoặc cookie đang tồn tại, mà có đặt trước nó là giá trị cookie của server và dấu ~.

    cookie laravel_session prefix
    server web1 192.168.1.110:8080 cookie web1 check
    server web2 192.168.1.111:8080 cookie web2 check
    server web2 192.168.1.112:8080 cookie web3 check

Chúng ta check thử xem header của haproxy server và response của nó. Sử dụng: curl -I http://haproxy-ip-address:80/

session cookie setup by app

Khi đó chúng ta thấy HAProxy server phản hồi với header như hình, với giá trị cookie được thay đổi là: “laravel_session=web1~eyJpdiI6InJuOUN…1Lc0E9PSIsInZhbH” với giá trị prefix là web1~ trước giá trị cookie của application mà HAProxy đã thêm vào.

Hạn chế của sticky session: Với sticky session, việc các request từ một user sẽ chỉ cố định vào một server. Vì vậy mà sẽ không đảm bảo được tính điều phối nhiều request từ một users đến nhiều server. Để khắc phục điểm hạn chế này, thì hiện nay có một số phần mềm như redis, memcached, … cho phép lưu session của user, còn việc điều phối các request của user thì vẫn thực hiện bình thường đến các server.

Vì vậy, trong bài viết tiếp theo chúng ta đi vào phần cấu hình và sử dụng redis.

Tham khảo thêm các bài viết về HAProxy tại: https://www.haproxy.com/blog/

Chúng ta vẫn thường sử dụng tiện ích rsync cho đồng bộ cây thư mục trong cùng máy hoặc giữa 2 máy.

Rsync nhẹ, cho tốc độ đồng bộ nhanh, nhưng nó chưa tích hợp tính năng đồng bộ Live, tức là mọi thay đổi chưa được đồng bộ ngay tức thì như một số ứng dụng lưu trữ đám mây phổ biển hiện nay như: Dropbox, Owncloud, …). Rsync cũng chưa cấu hình được để đồng bộ 2 chiều trong trường hợp cần Load Balancing. Một điểm nữa là để đồng bộ tự động thì cần đặt lịch cho Rsync. Trên Linux, cronjob chỉ đặt lịch đồng bộ tối thiểu 1 phút (có thể hack để đặt lịch ở mức thấp hơn :D)

Để giải quyết cho bài toán đồng bộ Live và 2 chiều cho Load Balancing, chúng ta có thể sử dụng đến Lsyncd.

Lsyncd là một daemon, sử dụng tiện ích rsync, kết hợp với SSH để giải quyết những hạn chế nêu trên của rsync. Lsyncd nhẹ, cài đặt và cấu hình đơn giản.

Trong phạm vi bài viết tôi sẽ sử dụng Lsyncd để đồng bộ dữ liệu giữa 2 CentOS 7 servers

sync data with lsyncd

Yêu cầu: Cài đặt SSH Keys 2 chiều cho Server01 và Server02, tham khảo bài viết:  https://vnsys.wordpress.com/2016/12/10/ssh-keys-2-chieu-tren-servers/

1. Install lsyncd and required packages

Cài đặt lsyncd trên cả 2 servers

rpm -ivh http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install lsyncd rsync

2. Config lsync on both servers

2.1 Cấu hình Lsyncd trên server01

Sửa đổi nội dung tệp tin cấu hình “/etc/lsyncd.conf” với nội dung sau:

 ----
 -- User configuration file for lsyncd.
 --
 -- Simple example for default rsync, but executing moves through on the target.
 --
 -- For more examples, see /usr/share/doc/lsyncd*/examples/
 --
 -- sync{default.rsyncssh, source="/var/www/html", host="localhost", targetdir="/tmp/htmlcopy/"}

settings {
 logfile = "/var/log/lsyncd.log", -- Sets the log file
 statusFile = "/var/log/lsyncd-status.log" -- Sets the status log file
 }
 sync{
 default.rsyncssh, -- uses the rsyncssh defaults Take a look here: https://github.com/axkibe/lsyncd/blob/master/default-rsyncssh.lua
 delete = true, -- Doesn't delete files on the remote host eventho they're deleted at the source. This might be beneficial for some not for others
 source="/var/www/example/", -- Your source directory to watch
 host="192.168.1.51", -- The remote host (use hostname or IP)
 exclude={"/storage"}, -- To exclude file & folder (not sync)
 targetdir="/var/www/example/", -- the target dir on remote host, keep in mind this is absolute path
 rsync = {
 archive = true, -- use the archive flag in rsync
 perms = true, -- Keep the permissions
 owner = true, -- Keep the owner
 _extra = {"-a"}, -- Sometimes permissions and owners isn't copied correctly so the _extra can be used for any flag in rsync
 },
 delay = 5, -- We want to delay the syncing for 5 seconds so we queue up the events
 maxProcesses = 1, -- We only want to use a maximum of 4 rsync processes at same time
 ssh = {
 port = 1122 -- This section allows configuration for ssh specific stuff such as a different port
 }
 }

2.2 Cấu hình Lsyncd trên server02

Sửa đổi nội dung tệp tin cấu hình “/etc/lsyncd.conf” với nội dung sau:

----
 -- User configuration file for lsyncd.
 --
 -- Simple example for default rsync, but executing moves through on the target.
 --
 -- For more examples, see /usr/share/doc/lsyncd*/examples/
 --
 -- sync{default.rsyncssh, source="/var/www/html", host="localhost", targetdir="/tmp/htmlcopy/"}

settings {
 logfile = "/var/log/lsyncd.log", -- Sets the log file
 statusFile = "/var/log/lsyncd-status.log" -- Sets the status log file
 }
 sync{
 default.rsyncssh, -- uses the rsyncssh defaults Take a look here: https://github.com/axkibe/lsyncd/blob/master/default-rsyncssh.lua
 delete = true, -- Doesn't delete files on the remote host eventho they're deleted at the source. This might be beneficial for some not for others
 source="/var/www/example/", -- Your source directory to watch
 host="192.168.1.50", -- The remote host (use hostname or IP)
 exclude={"/storage"},
 targetdir="/var/www/example/", -- the target dir on remote host, keep in mind this is absolute path
 rsync = {
 archive = true, -- use the archive flag in rsync
 perms = true, -- Keep the permissions
 owner = true, -- Keep the owner
 _extra = {"-a"}, -- Sometimes permissions and owners isn't copied correctly so the _extra can be used for any flag in rsync
 },
 delay = 5, -- We want to delay the syncing for 5 seconds so we queue up the events
 maxProcesses = 1, -- We only want to use a maximum of 4 rsync processes at same time
 ssh = {
 port = 1122 -- This section allows configuration for ssh specific stuff such as a different port
 }
 }

3. Restart and check log lsyncd on both servers

Start lsyncd trên 2 servers và tạo hoặc xóa tệp tin, thư mục trong đường dẫn đồng bộ /var/www/example để kiểm tra

systemctl start lsyncd
tail -f /var/log/lsyncd.log

lsyncd for syncing data

Load balancing Haproxy + KeepAlived for Nginx web server

Trong mô hình này

  • Phần Frontend, chúng ta sẽ sử dụng 02 server HAProxy + KeepAlived làm cân bằng tải (LB) cho các web server phần backend. Tại sao lại 02 server? 01 server HAProxy có thể được sử dụng làm LB cho các server Backend. Nhưng bản thân 01 server HAProxy không đảm bảo tính High availability (HA) của hệ thống, nếu nó down thì cả hệ thống down. Vì vậy, chúng ta sẽ sử dụng ít nhất 02 server HAProxy. Trên 02 server này, chúng ta cài KeepAlived để tạo ra một địa chỉ IP ảo – Virtual IP (VIP), mà client sẽ truy cập web qua địa chỉ IP này.
  • Phần Backend, chúng sẽ có thể sử dụng các web server như Apache, Nginx, … Trong trường hợp này, tôi sử dụng Nginx – một phần mềm web server rất phổ biến hiện nay.

I. Cài đặt và cấu hình KeepAlived để tạo VIP

Chúng ta sẽ cài đặt và cấu hình KeepAlived để tạo địa chỉ IP ảo (VIP) là 192.168.10.153

Step1: Installing KeepAlived trên cả 2 server

yum -y install keepalived

Step2: Cấu hình trên server 01 (Master server) – 192.168.10.151/24

Tạo tệp /etc/keepalived/keepalived.conf với nội dung sau:

! Configuration File for keepalived
global_defs {
   notification_email {
     dungnv@example.local
   }
   smtp_server mail.example.local
   notification_email_from info@example.local
   smtp_connect_timeout 30
   ! router_id LVS_MASTER
}
vrrp_script chk_haproxy {
        script "/usr/bin/killall -0 haproxy"    # verify the pid is exist or not
        interval 2                              # check every 2 seconds
        weight 2                                # add 2 points of prio if OK
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0  #Setting network interface for configuration
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass KeepWalking  #same for all machines
    }
    virtual_ipaddress {
        192.168.10.153
    }
    track_script {
        chk_haproxy
    }
}

Trong phần cấu hình global, thay đổi thông tin email mà cho phép gửi thông báo về sự kiện về thay đổi master server. Trong phần cấu hình mail này, không có phần thiết lập xác thực để gửi mail. Vì vậy, chúng ta cần tạo email trên mail server mà bỏ qua bước xác thực để có thể gửi mail.

Phần vrrp_script, chúng ta định nghĩa  một vrrp_script với tên chk_haproxy để track quá trình định tuyến để tạo VIP. Ở đây, chúng ta sẽ check dựa trên pid của daemon haproxy, nó sẽ check mỗi 2 giây (interval 2), và tăng trọng số lên 2 (weight 2) nếu pid haproxy tồn tại (chú ý ta chỉ tăng 1 lần)

Phần vrrp_instance, chúng ta định nghĩa và cấu hình cho phần giao diện mạng. Tùy thuộc cấu hình server mà chọn giao diện mạng phù hợp để cho phép giao tiếp với bên ngoài và tương tác với backup server. Ở đây, tôi sử dụng giao diện eth0, thiết lập trọng số có priority là 100, nó sẽ tăng thêm 2 khi kiểm tra ở phần vrrp_script tồn tại pid cho haproxy. Dựa vào giá trị priority này để xác định state là MASTER hay BACKUP. Server nào có priority cao hơn, server đó là MASTER và ngược lại. Cuối cùng thông tin VIP là 192.168.10.153

Step3: Cấu hình trên server 02 (Backup server)-192.168.10.152/24

Soạn thảo tệp tin /etc/keepalived/keepalived.conf với nội dung sau

! Configuration File for keepalived
global_defs {
   notification_email {
     dungnv@example.local
   }
   smtp_server mail.example.local
   notification_email_from info@example.local
   smtp_connect_timeout 30
   ! router_id LVS_MASTER
}
vrrp_script chk_haproxy {
        script "/usr/bin/killall -0 haproxy"    # verify the pid is exist or not
        interval 2                              # check every 2 seconds
        weight 2                                # add 2 points of prio if OK
}
vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 99
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass KeepWalking  #same for all machines
    }
    virtual_ipaddress {
        192.168.10.153
    }
    track_script {
        chk_haproxy
    }
}

Thông tin cấu hình keepalived.conf giống ở master server, chỉ khác ở thiết lập giá trị priority là 99 và tùy thuộc vào phần giao diện mạng lựa chọn.

Step4: Kiểm tra hoạt động của VIP

Sau khi đã cấu hình xong haproxy, chúng ta start haproxy và kiểm tra thông tin VIP

systemctl start keepalived

Chúng ta thực hiện lệnh sau để kiểm tra hoạt động của địa chỉ VIP trên các server.

ip address
link/ether 08:00:27:72:5b:b6 brd ff:ff:ff:ff:ff:ff inet 192.168.10.151/24 brd 192.168.1.255 scope global eth0 valid_lft forever preferred_lft forever inet 192.168.10.153/32 scope global eth0 valid_lft forever preferred_lft forever

Khi đó, chúng ta thấy địa chỉ IP 192.168.10.153/32 được sinh ra trên server01.

Hoặc sử dụng một trong các lệnh dưới đây để show ip

nmcli
ip addr show eth0 #ip address list

Note:

  • Trên CentOS 7 mặc định chưa có lệnh killall hoặc sử dụng lệnh **pkill**. Cài đặt psmisc
yum install psmisc
  • Add firewall rules để cho phép truyền thông VRRP
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 \
--in-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --direct --permanent --add-rule ipv4 filter OUTPUT 0 \
--out-interface eth0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
firewall-cmd --reload

II. Cài đặt và cấu hình HAProxy làm Load Balancing

Trong phần này, chúng ta sẽ cấu hình cân bằng tải cho site “example.local”, listen với port 80, cho các web server có địa chỉ 192.168.10.155 và 192.168.10.156 với cổng là 80.

Step1: Cài đặt HAProxy trên cả 2 máy HAproxy (master + backup)

yum install haproxy

Step2: Cấu hình HAProxy trên Master

Thực hiện chỉnh sửa hoặc tạo tệp tin /etc/haproxy/haproxy.cfg trên Master HAProxy với nội dung sau:

# Global settings
global
        pidfile     /var/run/haproxy.pid
        maxconn 100000
        user haproxy
        group haproxy
        daemon
        quite
        stats socket /var/lib/haproxy/stats
        log 127.0.0.1   local0

# Proxies settings
## Defaults section
defaults
        log     global
        mode    http
        option  tcplog
        option  dontlognull
        retries 3
        option      redispatch
        maxconn     100000
        retries                 3
        timeout http-request    5s
        timeout queue           10s
        timeout connect         10s
        timeout client          10s
        timeout server          10s
        timeout http-keep-alive 10s
        timeout check           10s

## Frontend section
frontend http-in
        bind *:80
        acl example-acl hdr(host) -i example.local
        use_backend example if example-acl
## Backend section
backend example
        balance roundrobin
        server server1 192.168.10.155:80 weight 1 check
        server server2 192.168.10.156:80 weight 1 check
## Statistics settings
listen statistics
        bind *:1986
        stats enable
        stats hide-version
        stats realm Haproxy\ Statistics
        stats uri /stats
        stats refresh 30s
        stats auth keepwalking86:ILoveVietnam$

Ở tệp cấu hình trên haproxy.cfg, chúng ta chia thành 02 phần: global và proxies

Phần global: thiết lập các tham số chung của HAProxy như: pidfile, user, group, daemon, … Các tham số này được áp dụng đến toàn bộ hệ thống.

Phần proxies: dùng thiết lập proxy. Trong tệp tin haproxy.cfg ở trên, nó được chia làm các phần con sau:

  • defaults: thiết lập các tham số mặc định cho các phần sau của nó. Các thiết lập trong phần này sẽ được reset nếu có tùy chọn ở các phần tiếp theo như frontend, backend, listen
  • frontend: Các thông tin thiết lập trong phần này mà HAProxy chấp nhận yêu cầu kết nối từ client. Ở đây, chúng ta tạo một frontend với tên http-in (chúng ta có thể tạo ra nhiều frontend với các tên khác nhau, tùy thuộc vào nhu cầu), gán cổng sẽ listen là 80, chỉ định tên backend là example, kết hợp nếu đúng ACL là example-acl
  • backend: thiết lập nhóm server mà HAProxy sẽ kết nối để chuyển tiếp kết nối incoming. Ở đây, chúng ta tạo ra backend với tên example (tùy thuộc vào hệ thống chúng ta cần dựng bao nhiêu site). Sử dụng thuật toán cân bằng tải là “roundrobin” – là thuật toán mặc định được sử dụng nếu không chỉ định thuật toán khác. Khai báo các web server có địa chỉ là 192.168.10.155 và 192.168.10.156, cổng listen trên web server là 80 và trọng số weight=1. Ta có thể thay đổi giá trị weight để yêu cầu tải trên mỗi server khác.
  • listen: định nghĩa một proxy hoàn chỉnh, mà kết hợp được cả frontend và backend. Ở đấy, tôi tạo một listen cho phần thống kê HAProxy. Khi đó chúng ta truy cập http://ip-address-haproxy:1986/stats với thông tin chứng thực keepwalking86/IloveVietnam$

Mặc định SELinux chưa cho phép sử dụng port 1986, chúng ta enable nó như sau:

setsebool -P haproxy_connect_any=1

Hoặc disable SELinux và restart servers

sed -i '/^SELINUX=/c\SELINUX=disabled' /etc/selinux/config

Step3: Copy tệp cấu hình haproxy.conf sang máy HAProxy backup

rsync -avzhP /etc/haproxy/haproxy.cfg root@192.168.10.152:/etc/haproxy/haproxy.cfg

Step4: Cấu hình haproxy log

Sửa nội dung tệp cấu hình rsyslog như sau:

cat >> /etc/rsyslog.conf <<EOF
\$ModLoad imudp
\$UDPServerRun 514
\$UDPServerAddress 127.0.0.1 #allow only rsyslog on 127.0.0.1 UDP port 514
EOF

Tạo tệp tin /etc/rsyslog.d/haproxy.conf

cat >> /etc/rsyslog.d/haproxy.conf <<EOF
local0.* /var/log/haproxy.log
EOF

III.  Cấu hình Nginx web server

Step1: Cài đặt Nginx web server

Có thể tham khảo cách Cài đặt Nginx web server 

Trong phạm vi bài viết này, chúng ta có thể cài đặt Nginx web server trên 02 server đơn giản  như sau:

yum -y install nginx
systemctl start nginx.service
systemctl enable nginx.service

Step2: Tạo tệp index.html

Cho mục đích kiểm tra, chúng ta sẽ tạo tệp index.htm đơn giản. Trong môi trường ứng dụng thực tế, chúng ta thực hiện cài đặt đầy đủ stack như LEMP.

Tạo tệp /usr/share/nginx/html/index.html đơn giản sau:

Trên server01:

echo “This is web server01” >/usr/share/nginx/html/index.html

Trên server02:

echo “This is web server02” >/usr/share/nginx/html/index.html

IV. Kiểm tra hoạt động HAProxy

Sau khi cấu hình xong KeepAlived, HAProxy, Nginx, chúng ta thực hiện kiểm tra hoạt động cân bằng tải.

Trên máy kiểm tra, thêm nội dung sau vào tệp /etc/hosts để truy cập site example.local ở LAN

echo "192.168.10.153 example.local" >>/etc/hosts

Step1: Kiểm tra hoạt động cân bằng tải HAProxy

Thực hiện tạo vòng lặp cho kiểm tra

check haproxy with while

Ta thấy HAProxy phân bổ tải lần lượt đến từng web server, với giá trị trọng số weight=1.

Step2: Thống kê hoạt động của HAProxy

Mở trình duyệt web, và truy cập http://example.local:1986/stats với thông tin chứng thực keepwalking86/IloveVietnam$

haproxy statistics

Load balancing across multiple application instances is a commonly used technique for optimizing resource utilization, maximizing throughput, reducing latency, and ensuring fault-tolerant configurations.
Nginx is a very efficient HTTP load balancer to distribute traffic to several application servers and to improve performance, scalability and reliability of web applications.
Nginx Load balancing methods
The following load balancing mechanisms (or methods) are supported in nginx:
  • round-robin
  • least-connected
  • ip-hash
nginx load balancing

nginx load balancing

srv-lb01 (10.11.218.250) (Nginx load balancer)
srv-web01 (10.11.218.251) ( Web server)
srv-web02 (10.11.218.252) ( Web server)
srv-web03 (10.11.218.253) ( Web server)

Note: pointing nginx.vn to 10.11.218.250 (Replace nginx.vn with your real site name)


1.
Default load balancing configuration (round-robin)

When load balancing method is not specifically configured, it defaults to round-robin. All requests are proxied to the server group, and nginx applies HTTP load balancing to distribute the requests.

Install Nginx on srv-lb01, see at http://vietsystem.blogspot.com

Create a new configuration file called /etc/nginx/sites-available/nginx.vn with the following contents:

vim /etc/nginx/sites-available/nginx.vn

# Defines a group of servers and Load balancing methods

upstream nginx.vn {          
          server 10.11.218.251; 
          server 10.11.218.252;
          server 10.11.218.253;
}
server {
          listen 80;
          error_log /var/log/nginx/nginx.vn-error.log;
          location / {
               proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
               proxy_pass http://nginx.vn;
          }
}

Enable the site and restart Nginx

# cd /etc/nginx/sites-enabled
# ln -s ../sites-available/nginx.vn .
#systemctl restart nginx.service

Open web browser and go to http://nginx.vn

2. Least connected load balancing

Least-connected load balancing is activated when the least_conn directive is used as part of the server group configuration:
# Defines a group of servers and Load balancing methods
upstream nginx.vn {
           least_conn;
           server 10.11.218.251;
           server 10.11.218.252;
           server 10.11.218.253;
}

3. ip hash load balancing

 To configure ip-hash load balancing, just add the ip_hash directive to the server (upstream) group configuration
# Defines a group of servers and Load balancing methods
upstream nginx.vn {
          ip_hash;
          server 10.11.218.251;
          server 10.11.218.252;
          server 10.11.218.253;
}
4. Weighted load balancing
When the weight parameter is specified for a server, the weight is accounted as part of the load balancing decision.
# Defines a group of servers and Load balancing methods
upstream nginx.vn {
          server 10.11.218.251 weight=2;
          server 10.11.218.252;
          server 10.11.218.253;
}
With this configuration, every 4 new requests will be distributed across the application instances as the following: 3 requests will be directed to srv-web01, one request will go to srv-web02, and another one to srv-web03.