HAProxy ?

隨著網頁服務的流量提升,網頁伺服器所有乘載的連線數也會遽增。這個時候就需要使用負載平衡( Load Balance )的技術,將外部發送來的請求,平均分配到其中的不同伺服器上,而負責接收到請求的伺服器,獨立的回應給客戶端。負載平衡除了分流能力之外,有另一個很大的好處就是可以提供 High Availability,避免其中一台機器掛了而使得整個服務也掛掉。

如果是使用 Nginx 作為網頁伺服器,可以搭配開源的 HAProxy 使用。HAProxy 設定有幾台機器, 若其中某台掛掉則服務中抽離,當機器復活之後在加回服務中,達到 High Availability 的目的。

The Reliable, High Performance TCP/HTTP Load Balancer - HAProxy

開始設定

可以接續著前一篇介紹的 Nginx 安裝說明服用!

Step 1. OpenSSL 與 HAProxy 安裝

這個部分我們需要編譯 OpenSSL 1.0.2 的 Source Code 來安裝(因為目前 yum 還沒有可以使用的資源)。

Terminal
1
2
3
4
5
6
7
# Compile and install OpenSSL - via https://github.com/haproxy/haproxy/blob/master/README
wget -O /tmp/openssl.tgz https://www.openssl.org/source/openssl-1.0.2-latest.tar.gz
tar -zxf /tmp/openssl.tgz -C /tmp
cd /tmp/openssl-*
./config --prefix=/usr --openssldir=/etc/ssl --libdir=lib no-shared zlib-dynamic
make
make install_sw

接著,重新編譯 HAProxy 1.6.3 使用 OpenSSL。

Terminal
1
2
3
4
5
6
7
8
9
# Compile and install HAProxy
wget -O /tmp/haproxy.tgz https://www.haproxy.org/download/1.6/src/haproxy-1.6.3.tar.gz
tar -zxvf /tmp/haproxy.tgz -C /tmp
cd /tmp/haproxy-*
make \
TARGET=linux2628 USE_LINUX_TPROXY=1 USE_ZLIB=1 USE_REGPARM=1 USE_PCRE=1 USE_PCRE_JIT=1 \
USE_OPENSSL=1 SSL_INC=/usr/include SSL_LIB=/usr/lib ADDLIB=-ldl \
CFLAGS="-O2 -g -fno-strict-aliasing -DTCP_USER_TIMEOUT=18"
make install

然後, HAProxy 就可以通過靜態的方式連接到 OpenSSL ,可以利用這個指令測試:

Terminal
1
haproxy -vv

Step 2. HAProxy 設定

haproxy.cfg 的設定文件如下:

'/etc/haproxy/haproxy.cfg'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
global
#debug
chroot /var/lib/haproxy
user haproxy
group haproxy
pidfile /var/run/haproxy.pid

# Default SSL material locations
ca-base /etc/ssl/certs
crt-base /etc/ssl/private

# Default ciphers to use on SSL-enabled listening sockets.
ssl-default-bind-options no-sslv3 no-tls-tickets force-tlsv12
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS

spread-checks 4
tune.maxrewrite 1024
tune.ssl.default-dh-param 2048

defaults
mode http
balance roundrobin

option dontlognull
option dontlog-normal
option redispatch

maxconn 5000
timeout connect 5s
timeout client 20s
timeout server 20s
timeout queue 30s
timeout http-request 5s
timeout http-keep-alive 15s

frontend http-in
bind *:80

stats enable
stats refresh 30s
#stats hide-version
stats realm Strictly\ Private
stats auth admin:admin
stats uri /admin?stats

default_backend nodes-http

frontend https-in
mode tcp
bind *:443 ssl crt /etc/ssl/dummy.pem alpn h2,http/1.1
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
use_backend nodes-http2 if { ssl_fc_alpn -i h2 }
default_backend nodes-http

backend nodes-http
server node1 web.server:80 check

backend nodes-http2
mode tcp
http-request add-header X-Forwarded-Proto https
server node1 web.server:81 check send-proxy
view raw
  • 這裡我們定義 HAProxy 監聽 Port 443 去偵測 HTTP 連線
  • 後端設定 nodes-http2, nodes-http 兩種方式來確保 HTTP/1.1 跟 HTTP/2 都能支援
  • use_backend nodes-http2 if { ssl_fc_alpn -i h2 } 會根據使用者端的連線自動分辨不同的 HTTP 版本

Step 3. 虛擬主機設定

建立 Nginx vhost.conf(虛擬主機設定文件)確保在使用 HTTP/2 的情況下正常工作。下面是一個簡單的 vhost 配置:

vhost.conf
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80 default_server;
listen 81 default_server http2 proxy_protocol;
## Needed when behind HAProxy with SSL termination + HTTP/2 support
listen 443 default_server ssl http2;

ssl_certificate /etc/ssl/dummy.crt;
ssl_certificate_key /etc/ssl/dummy.key;

root /data/www/default;
index index.html;
}

我們無法在 Port 443 上使用 SSL ,因為必須要由 HAProxy 解密。因此,我們使用 Port 81 作為 HTTP/2 溝通的窗口。

接著,可以透過以下指令啟動 HAProxy:

terminal
1
$ haproxy -f /etc/haproxy/haproxy.cfg

結論

隨著 HTTP/2 在 Nginx 上升級,再搭配上 HAProxy 的設定,使得網頁伺服器的效能除了能有效能上的提昇之外,更能增加彈性。 HAProxy 是達到 Load Balance 不可或缺的工具。

Reference

[1] The complete guide to HTTP/2 with HAProxy and Nginx
[2] 使用 HAProxy 完成 網站分流, 平衡負載


License

本文主要參考 The complete guide to HTTP/2 with HAProxy and Nginx,如果侵犯到你的權益,請及時聯繫我們。


本著作由 Chang, Wei-Yaun (v123582) 製作,
創用CC 姓名標示-相同方式分享 3.0 Unported授權條款釋出。