haproxy是個高性能的tcp和http的反向代理,它就是個代理,不像nginx還做web服務器
haproxy安裝
-
下載及安裝haproxy(安裝包下載需翻墻)
$ cd /opt/k8s/keepalive-haproxy $ wget https://www.haproxy.org/download/2.1/src/haproxy-2.1.3.tar.gz $ tar -xzvf haproxy-2.1.3.tar.gz $ cd haproxy-2.1.3/ $ make TARGET=linux53 CPU=x86_64 USE_OPENSSL=1 USE_SYSTEMD=1 $ mkdir -p /opt/k8s/haproxy $ make install PREFIX=/opt/k8s/haproxy/-
USE_OPENSSL=1 開啟https
-
USE_SYSTEMD=1 指定為systemd模式,否則不能通過systemd進行啟動,報錯資訊
master-worker mode with systemd support (-Ws) requested, but not compiled. Use master-worker mode (-W) if you are not using Type=notify in your unit file or
-
recompile with USE_SYSTEMD=1.
```
* TARGET=linux53 CPU=x86_64引數,通過uname -a 查看機器對應的系統內核資訊決定
```
$ uname -a
Linux master 5.3.0-40-generic #32~18.04.1-Ubuntu SMP Mon Feb 3 14:05:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
```
* PREFIX 指定安裝路徑
-
使用隨安裝包提供的配置示例啟動haproxy
$ cd /opt/k8s/keepalive-haproxy/haproxy-2.1.3 $ mkdir /opt/k8s/haproxy/conf # 復制示例組態檔 $ cp examples/option-http_proxy.cfg /opt/k8s/haproxy/conf/ # 啟動 $ /opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/option-http_proxy.cfg
配置 haproxy 日志
因為haproxy會使用rsyslog進行日志處理,所以需要配置rsyslog
-
查看rsyslog的配置,
$ cat /etc/rsyslog.conf # # Include all config files in /etc/rsyslog.d/ # $IncludeConfig /etc/rsyslog.d/*.conf- /etc/rsyslog.conf 這個是ubuntu系統下的路徑,其他系統要查看相對應的配置
- 意思rsyslog會讀取/etc/rsyslog.d/下面的 *.conf來進行日志配置
-
在/etc/rsyslog.d/下追加haproxy.conf
$ cat > haproxy.conf<< EOF $ModLoad imudp $UDPServerRun 514 local0.* /var/log/haproxy.log EOF- 將haproxy日志寫入到/var/log/haproxy.log
-
重啟rsyslog
$ systemctl restart rsyslog -
停掉演示例子
$ ps -elf | grep -e PID -e haproxy $ kill -9 ${上一步驟查出的PID}
下面通過具體例子來說明如何利用haproxy對我們的業務進行負載均衡
-
部署圖如下

- 客戶端呼叫haproxy:8089,haproxy利用指定負載均衡演算法,將請求代理到具體的后端服務
- haproxy在9188上啟動監聽,回應haproxy自身的狀態資訊
-
對應的haproxy組態檔
$ cd /opt/k8s/haproxy/conf cat >haproxy.cfg << EOF global maxconn 20000 log 127.0.0.1 local0 info uid 200 gid 200 chroot /opt/k8s/haproxy nbproc 1 daemon defaults mode http retries 3 timeout connect 10s timeout client 20s timeout server 30s frontend web bind *:8089 mode http log global option httplog option dontlognull option nolinger option http_proxy maxconn 8000 timeout client 30s default_backend web-srv backend web-srv mode http option redispatch option abortonclose balance roundrobin cookie SERVERID option httpchk GET /health server web1 192.168.0.114:8086 check cookie server1 inter 2000 fall 3 weight 30 server web2 192.168.0.107:8086 check cookie server1 inter 2000 fall 3 weight 30 listen admin_stats bind 0.0.0.0:9188 mode http stats uri /haproxy-status stats auth admin:admin123 EOF -
驗證組態檔
$ /opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/haproxy.cfg -c Configuration file is valid- 追加 -c 引數,只針對組態檔格式內容進行驗證,并不真正啟動服務
-
啟動后端服務
后端服務采用spring boot撰寫的一個web程式,里面提供了兩個restful API,一個用來做health檢查,另一個用來呼叫測驗,在application.yml中將埠設定成8086,
核心代碼如下:
@RequestMapping("/header/list") public String listHeader(HttpServletRequest request) { Enumeration<String> headers = request.getHeaderNames(); while (headers.hasMoreElements()) { String header = headers.nextElement(); log.info(header + " is " + request.getHeader(header)); } return "OK"; } @RequestMapping("/health") public String health(HttpServletRequest request) { return "OK"; }將服務打成可執行jar后,在192.168.0.107、和192.168.0.114上啟動
-
啟動haproxy
$ cd /opt/k8s/haproxy $ ./sbin/haproxy -f conf/haproxy.cfg -
查看統計頁面

- 可以看到對應的后端web1、web2都正常運行
-
訪問 http://192.168.0.107:8089/header/list,觀察啟動的兩個后端服務的日志,可以看到每次haproxy會選一個后端服務回應我們的請求
-
查看haproxy日志
$ tail -10 /var/log/haproxy.log Mar 13 10:24:14 localhost haproxy[19512]: 192.168.0.108:56975 [13/Mar/2020:10:24:14.523] web web-srv/web1 0/0/0/11/11 200 181 - - ---- 2/2/0/0/0 0/0 "GET /header/list HTTP/1.1" Mar 13 10:24:14 localhost haproxy[19512]: 192.168.0.108:56975 [13/Mar/2020:10:24:14.561] web web-srv/web2 1/0/0/4/5 200 1117 - - ---- 2/2/0/0/0 0/0 "GET /favicon.ico HTTP/1.1" Mar 13 10:28:50 localhost haproxy[19512]: 192.168.0.108:57713 [13/Mar/2020:10:28:50.103] web web-srv/web1 0/0/4/12/16 200 181 - - ---- 2/1/0/0/0 0/0 "GET /header/list HTTP/1.1"
模擬故障、故障恢復
-
停掉107服務器上的spring boot工程
-
再次觀察haproxy的統計頁面

- 其中107服務器上對應的后端服務web2被標記成了DOWN
- 此時繼續請求http://192.168.0.107:8089/header/list,會發現haproxy只把請求轉發給正常的服務器114
-
恢復107服務器上的spring boot服務
-
再次觀察haproxy的統計頁面,會發現web2狀態重新變成UP,107上的spring boot也能收到haproxy分發過來的請求,
這樣利用haproxy的負載技術,不僅僅實作了流量的分發,也在一定程度上提升了系統容錯性
將haproxy設定成系統服務
采用此模式,編譯階段必須指定USE_SYSTEMD=1
-
撰寫haproxy服務啟動腳本
$ cat > //etc/systemd/system/haproxy.service <<"EOF" [Unit] Description=HAProxy Load Balancer After=network.target [Service] ExecStartPre=/opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/haproxy.cfg -c -q ExecStart=/opt/k8s/haproxy/sbin/haproxy -Ws -f /opt/k8s/haproxy/conf/haproxy.cfg ExecReload=/bin/kill -USR2 $MAINPID [Install] WantedBy=multi-user.target EOF- 啟動引數-W 以master-worker模式作業,在此模式下可通過發送SIGUSR2信號重新加載haproxy
-
啟動haproxy
$ systemctl daemon-reload $ systemctl start haproxy $ systemctl status haproxy ● haproxy.service - HAProxy Load Balancer Loaded: loaded (/etc/systemd/system/haproxy.service; disabled; vendor preset: enabled) Active: active (running) since Fri 2020-03-13 11:48:25 CST; 13s ago Process: 14757 ExecStartPre=/opt/k8s/haproxy/sbin/haproxy -f /opt/k8s/haproxy/conf/haproxy.cfg -c -q (code=exited, status=0/SUCCESS) Main PID: 14758 (haproxy) Tasks: 2 (limit: 4915) CGroup: /system.slice/haproxy.service ├─14758 /opt/k8s/haproxy/sbin/haproxy -Ws -f /opt/k8s/haproxy/conf/haproxy.cfg └─14759 /opt/k8s/haproxy/sbin/haproxy -Ws -f /opt/k8s/haproxy/conf/haproxy.cfg- 狀態為running表示正常,否則 通過 journalctl -u haproxy查看具體原因
-
設定成開機啟動
$ systemctl enable haproxy.service
遇到問題
-
configure: error: no acceptable C compiler found in $PATH
$ apt install gcc -
Can not include OpenSSL headers files
$ apt-get install libssl-dev -
systemd/sd-daemon.h: 沒有那個檔案或目錄
$ apt install libsystemd-dev -
400 bad request
一開始不懂haproxy的配置語法,在backend中追加了option http_proxy去掉這個配置就可以了
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/36604.html
標籤:其他
