• 使用 HAProxy 完成 網站分流, 平衡負載
    时间:2009-04-10   作者:佚名   出处:互联网

    一台 Server 能夠承受的連線數量是有一定限制的, 特別是在同一時間的存取, 如果一台 Server 撐不住時, 該如何讓其它機器來分擔?
    網站分流、平衡負載解法

        * Poor 版: DNS Robin DNS Load Balancing - 詳可見: [筆記] FreeBSD 一張網卡多重 ip 實現 Round Robin DNS Load Balancing
        * Rich 版: 買 L4 / L7 Switch 解決.

    Poor / Rich 版 優缺點

        * 窮人版解法 有些小問題: 機器掛掉時, 沒辦法 立刻(by TTL 的時間) 自動切換.
        * Rich 版 就蠻好搞定的, 只是這一版目前不適用在我身上. XD

    HAProxy

    由上述原因, 取中間值的話, 可以考慮用 HAProxy 來達成, 詳可見: HAProxy 官網 (註: 此份文件使用的 HAProxy 是 1.3.15 版)

    HAProxy 可以設定後端有幾台機器, 多久要去 check 機器死活, 若死掉時就可以馬上將此機器從服務中抽離, 只要機器活起來, 將會自動回復服務, 基本架構可見: HAProxy - Description
    HAProxy 架設

    以下是於 Debian Linux 環境 步驟

       1. apt-get install haproxy
       2. vim /etc/default/haproxy # 將 ENABLED=0 改為 1

              #ENABLED=0
              ENABLED=1

       3. /etc/init.d/haproxy start # 啟動

    HAProxy 錯誤排除

    在上述啟動時, 若有出現下述錯誤:

        Starting haproxy: [ALERT] 015/191034 (15631) : Starting proxy webfarm: cannot bind socket...on both load balancers

        或

        [ALERT] 056/103843 (1358) : Starting proxy www-balancer: cannot bind socket

    解法

        * 暫時解法, 直接先修改設定, 讓它先跑起來:

              sysctl -e net.ipv4.ip_nonlocal_bind=1

        * 永久解法, 讓開機時自動設此參數.
             1. sysctl -a | grep nonlocal # 看是否已經有設定此參數
             2. vim /etc/sysctl.conf # 最下面加入
                net.ipv4.ip_nonlocal_bind=1

    不過, 就直接啟動, 沒有做什麼任何的事情, 再來就來看看設定檔, 來把想做的事情設一設~ :)
    HAProxy 設定檔 Debug 模式

    HAProxy 的設定檔預設是放在 /etc/haproxy/haproxy.cfg (Debian), 要看是否設定正確, 來源資料是否走對路等等, 要先知道如何 Debug.

        * Debug mode 啟動: "/usr/sbin/haproxy -d -f /etc/haproxy/haproxy.cfg"

    HAProxy 設定檔(haproxy.cfg)

    HAProxy 設定檔, 詳細文件可見: HAProxy Documentation

    想要直接取用設定(下述是我的設定), 可以直接修改取用(haproxy.cfg 下載), haproxy.cfg 內容如下:

        global
            maxconn 32768
            #chroot /usr/share/haproxy
            user haproxy
            group haproxy
            daemon
            nbproc 8
            #debug
            #quiet

        defaults
            log    global
            mode    http
            option    httplog
            option    dontlognull
            retries    3
            option redispatch
            option httpclose
            maxconn    32768
            contimeout    5000
            clitimeout    50000
            srvtimeout    50000

        #listen    www-balancer 0.0.0.0:80
        listen    www-balancer
                bind 0.0.0.0:80
                balance         roundrobin
                server          w1 11.11.11.11:80 weight 3 check
                server          w2 22.22.22.22:80 weight 3 check
                option          httpchk GET /robots.txt
                option          forwardfor

    HAProxy 常用參數說明


    HAProxy 上述 cfg 檔內容, 詳細可見: HAProxy Reference Manual (簡體版: HAProxy 配置手冊)

    下述內容主要來自上述文件:
    haproxy.cfg 三大項目

    haproxy.cfg 有分下列三種: (haproxy.cfg 的三個主項目)

        * global
        * listen
        * defaults

    註:

        * 下述所有 <name> 都必須由 大/小 寫字母, 數字, -, . : 組成. (大小寫會視為不同名稱)
        * defaults <name>: 下面所有參數的預設設定值, 下面的設定值會蓋掉上面的.
        * listen   <name>: 完整的 Proxy 代理, frontend / backend 都在這個設定裡 (用於 TCP)

    global 分類

    global 部分有下述幾類:

        * 行程管理和安全
             1. chroot <jail dir>
             2. daemon: 執行 -D 也是同樣
             3. gid
             4. group
             5. log
             6. nbproc: deamon 才能使用, 也是最推薦的模式, 如果小檔案很多, 建議要多開幾個, 但是 debug 時不建議開此參數. (arg: nbproc <number>)
             7. pidfile
             8. uid
             9. ulimit-n: 設定每個行程最大文件數, 此值會自動計算, 不建議設定此參數 (arg: ulimit-n <number>)
            10. user
            11. stats
        * 性能調校
             1. maxconn: 最大連接數, 同 -n (arg: maxconn <number>)
             2. noepoll: 在 Linux 系統不使用 epoll, 等同 -de
             3. nokqueue: 在 BSD 不使用 kqueue polling, 同 -dk
             4. nopoll: 此 poll 在任何機器都可以跑, 不建議關閉, 同 -dp
             5. nosepoll: 在 Linux 系統不使用 speculative epoll, 等同 -ds
             6. spread-checks: 多久去 check 一次, 預設值 0 (arg: spread-checks <0..50, in percent>)
             7. tune.maxaccept
             8. tune.maxpollevents
        * 測試
             1. debug: 將所有訊息都顯示到畫面上, 同 -d
             2. quiet: 不顯示任何訊息, 同 -v

    listen 分類

        * listen <instance_name> [ <IP_address>:<port_range>[,...] ]

    listen 部分有下述幾類:

        * bind
        * mode: TCP / HTTP / health
        * balance: roundrobin / source / url / url_param
        * server
        * option
        * # defaults 的參數都可於此寫入, 於此 listen 的設定中, 會以此寫入的為主.

    defaults 參數

    defaults 的參數說明: (註: 下述非完整參數, 只把可能會用到的簡單做個筆記.)

        * acl <aclname> <criterion> [flags] [operator] <value> ...
        * balance <algorithm> [ <arguments> ] (設定 load balancing algorithm, ex: balance roundrobin)
        * balance url_param <param> [check_post [<max_wait>]] (ex: balance url_param userid 或 balance url_param session_id check_post 64)
        * bind [<address>]:<port> [, ...] (ex: bind :80,:443 或 bind 10.0.0.1:10080,10.0.0.1:10443)
        * contimeout <timeout>: 設定連結到 server 的最大等待時間.
        * clitimeout <timeout>: 設定 Client 最大等待時間
        * errorfile <code> <file> (ex: errorfile 400 /etc/haproxy/errors/400.http, <code> 支援的 HTTP status code 有:  400, 403, 408, 500, 502, 503, and 504.)
        * log global
        * log <address> <facility> [<level>] (ex: log 127.0.0.1:514 local0 notice)
        * maxconn <conns>: 同時最大連線數量
        * mode { tcp|http|health } (defaults 為 http)
        * monitor fail [if | unless] <condition>: 如果發現掛掉時, 要做什麼事.
        * monitor-net <source> (ex: monitor-net 192.168.0.252/31 # addresses .252 and .253 are just probing us.)
        * monitor-uri <uri> (ex: monitor-uri /haproxy_test # Use /haproxy_test to report haproxy's status)
        * option dontlognull: Enable or disable logging of null connections.
        * option forwardfor [ except <network> ]: 如果有 X-Forwarded-For header 都送到 server 去.
        * option httpchk: 於下面範例解釋
        * option httpclose: Enable or disable passive HTTP connection closing
        * option httplog: Enable logging of HTTP request, session state and timers
        * option logasap: Enable or disable early logging of HTTP requests
        * option persist: 當 client 連到死的機器時, 持續繼續連線, 搭配 redispatch 會再幫他導到其它機器.
        * option redispatch: 當 client 連到死的機器時, 重新再分配.
        * option smtpchk
        * option smtpchk <hello> <domain> (ex: option smtpchk HELO mydomain.org)
        * option srvtcpka: Enable or disable the sending of TCP keepalive packets on the server side
        * option ssl-hello-chk: Use SSLv3 client hello health checks for server testing
        * option tcpka: Enable or disable the sending of TCP keepalive packets on both sides
        * option tcplog: Enable advanced logging of TCP connections with session state and timers
        * option transparent: Enable client-side transparent proxying
        * reqadd <string>: Add a header at the end of the HTTP request
        * reqallow  <search> (ex: reqiallow ^Host:\ www\.)
        * reqiallow <search>  (ignore case) (ex: reqiallow ^Host:\ www\.)
        * reqdel  <search> (ex: reqdel ^X-Forwarded-For:.*)
        * reqidel <search>  (ignore case) (ex: reqidel ^Cookie:.*SERVER=)
        * reqdeny  <search>
        * reqideny <search>  (ignore case) (ex: reqideny  ^Host:\ .*\.local)
        * reqpass  <search>
        * reqipass <search>  (ignore case) (ex: reqipass  ^Host:\ www.private\.local)
        * reqrep  <search> <string> (ex: reqrep ^([^\ ]*)\ /static/(.*)  \1\ /\2)
        * reqirep <search> <string>   (ignore case) (ex: reqirep ^Host:\ www.mydomain.com   Host:\ www)
        * rspadd <string>: Add a header at the end of the HTTP response
        * rspdel  <search>
        * rspidel <search>  (ignore case)
        * server <name> <address>[:port] [param*]: Declare a server in a backend (ex: server first  10.1.1.1:1080 cookie first  check inter 1000 或 server second 10.1.1.2:1080 cookie second check inter 1000)
        * stats auth <user>:<passwd> (ex: stats auth admin1:AdMiN123)
        * srvtimeout <timeout>: 設定在 server side 的 最大等待時間
        * retries <number>: 重試次數

    httpchk 範例

    httpchk (啟用 HTTP 的 server health check.) 特別重要, 範例多記錄一點.

        option httpchk
        option httpchk <uri>
        option httpchk <method> <uri>
        option httpchk <method> <uri> <version>
        ex:
            # Relay HTTPS traffic to Apache instance and check service availability
            # using HTTP request "OPTIONS * HTTP/1.1" on port 80.
            backend https_relay
                mode tcp
                option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
                server apache1 192.168.1.1:443 check port 80
          
            option  httpchk GET /robots.txt
            option  httpchk GET /index.html
            option  httpchk *

        option  httpchk GET /robots.txt # 指的是 GET /robots.txt HTTP/1.0
        option  httpchk # 指的是 OPTIONS / HTTP/1.0
        option  httpchk * # 指的是 OPTIONS * HTTP/1.0

    网友留言/评论

    我要留言/评论