天天看點

Haproxy+Keepalived負載均衡

Haproxy介紹

HAProxy是一個特别适用于高可用性環境的TCP/HTTP開源的反向代理和負載均衡軟體。在7層負載均衡方面的功能很強大(支援cookie track, header rewrite等等),支援雙機熱備,支援虛拟主機,支援健康檢查,同時還提供直覺的監控頁面,可以清晰實時的監控服務叢集的運作狀況。同時支援Linux 2.6核心中System Epoll,通過簡化系統調用,大幅的提高了網絡I/O性能。

Haproxy包括以下一些特征:

  • 根據靜态配置設定的cookie 配置設定HTTP請求
  • 配置設定負載到各個伺服器,同時保證伺服器通過使用HTTP Cookie實作連接配接保持;
  • 當主伺服器當機時切換到備份伺服器;允許特殊端口的服務監控;
  • 做維護時通過熱配置可以保證業務的連續性,更加人性化;
  • 添加/修改/删除HTTP Request和Response 頭;
  • 通過特定表達式Block HTTP請求;
  • 根據應用的cookie做連接配接保持;
  • 帶有使用者驗證的詳細的HTML監控報告.

    Haproxy支援的平台

    HAProxy is known to reliably run on the following OS/Platforms :
    Linux 2.4 on x86, x86_64, Alpha, Sparc, MIPS, PARISC 
    Linux 2.6 / 3.x on x86, x86_64, ARM, Sparc, PPC64 
    Solaris 8/9 on UltraSPARC 2 and 3 
    Solaris 10 on Opteron and UltraSPARC 
    FreeBSD 4.10 - 10 on x86 
    OpenBSD 3.1 to -current on i386, amd64, macppc, alpha, sparc64 and VAX (check the ports) 
    AIX 5.1 - 5.3 on Power™ architecture 
               

HAProxy負載均衡算法

HAProxy的負載均衡算法現在具體有如下8種:

  • roundrobin

    ,表示簡單的輪詢,這個不多說,這個是負載均衡基本都具備的;
  • static-rr

    ,表示根據權重,建議關注;
  • leastconn

    ,表示最少連接配接者先處理,建議關注;
  • source

    ,表示根據請求源IP,這個跟

    Nginx

    IP_hash

    機制類似,我們用其作為解決

    session

    問題的一種方法,建議關注;
  • ri

    ,表示根據請求的URI;
  • rl_param

    ,表示根據請求的URl參數’balance url_param’ requires an URL parameter name;
  • hdr(name)

    ,表示根據HTTP請求頭來鎖定每一次HTTP請求;
  • rdp-cookie(name)

    ,表示根據據cookie(name)來鎖定并哈希每一次TCP請求。

Haproxy部署

Haproxy源碼編譯安裝

安裝依賴軟體包

[[email protected] ~]# yum install -y net-tools vim lrzsz tree screen lsof tcpdump nc mtr nmap gcc glib gcc-c++ make
[[email protected] ~]# cd /usr/local/src
[[email protected] src]# wget http://www.haproxy.org/download/1.6/src/haproxy-1.6.3.tar.gz
[[email protected] src]# tar zxf haproxy-1.6.3.tar.gz 
           

編譯安裝Haproxy

[[email protected] src]# cd haproxy-1.6.3
[[email protected] src]# make TARGET=linux2628 PREFIX=/usr/local/haproxy-1.6.3
[[email protected] src]# make install
[[email protected] ~]# cp /usr/local/sbin/haproxy /usr/sbin/
[[email protected] ~]# haproxy -v
HA-Proxy version 1.6.3 2015/12/25
Copyright 2000-2015 Willy Tarreau <[email protected]>
           

Haproxy啟動腳本

[[email protected] ~]# cd /usr/local/src/haproxy-1.6.3
[[email protected] haproxy-1.6.3]# cp examples/haproxy.init /etc/init.d/haproxy
[[email protected] haproxy-1.6.3]# chmod 755 /etc/init.d/haproxy 
           

Haproxy配置檔案

[[email protected] ~]# useradd -r haproxy
[[email protected] ~]# mkdir /etc/haproxy
[[email protected] ~]# mkdir /var/lib/haproxy
[[email protected] ~]# mkdir /var/run/haproxy
[[email protected] ~]# vim /etc/haproxy/haproxy.cfg
global
   log 127.0.0.1 local3 info
   chroot /var/lib/haproxy
   user haproxy
   group haproxy
   daemon

defaults
   log global
   mode http
   option httplog
   option dontlognull
   timeout connect 5000
   timeout client 50000
   timeout server 50000

frontend http_front
   bind *:80
   stats uri /haproxy?stats
   default_backend http_back

backend http_back
   balance roundrobin
   server linux-node1 192.168.56.11:8080 check
   server linux-node2 192.168.56.12:8080 check

#設定可以監聽非本地IP

net.ipv4.ip_nonlocal_bind:
  sysctl.present: 
- value: 1
           

haproxy日志設定

[[email protected] ~]# vim /etc/rsyslog.conf
#rsyslog 預設情況下,需要在514端口監聽UDP,是以可以把/etc/rsyslog.conf如下的注釋去掉
# Provides UDP syslog reception 
$ModLoad imudp 
$UDPServerRun 514
local3.*         /var/log/haproxy.log
           
[[email protected] ~]# vim /etc/sysconfig/rsyslog
[[email protected] ~]# systemctl restart rsyslog
           

Haproxy配置

配置案例

global
maxconn 100000
chroot /usr/local/haproxy
uid 99  
gid 99 
daemon
nbproc 1 
pidfile /usr/local/haproxy/logs/haproxy.pid 
log 127.0.0.1 local3 info

defaults
option http-keep-alive
maxconn 100000
mode http
timeout connect 5000ms
timeout client  50000ms
timeout server 50000ms

listen stats
mode http
bind 0.0.0.0:8888
stats enable
stats uri     /haproxy-status 
stats auth    haproxy:saltstack

frontend frontend_www_example_com
bind 192.168.56.21:80
mode http
option httplog
log global
default_backend backend_www_example_com

backend backend_www_example_com
option forwardfor header X-REAL-IP
option httpchk HEAD / HTTP/1.0
balance source
server web-node1  192.168.56.21:8080 check inter 2000 rise 30 fall 15
server web-node2 192.168.56.22:8080 check inter 2000 rise 30 fall 15
           

HAProxy的配置過程分為3個主要部分:

  • 指令行參數,這是最優先的
  • global(全局)段,設定程序級參數
  • 代理配置段,通常位于"default", "listen", "fronted", "backend"這樣的形式内。

配置檔案的文法是由關鍵字後跟可選的一個或者多個參數(參數之間有空格)組成。如果字元串中包含空格,必須使用''進行轉義。\本身需要使用\進行轉義。

一些參數值為時間,比如說timeout。時間值通常機關為毫秒(ms),但是也可以通過加字尾來使用其他的機關,支援的機關為:

- us : microseconds. 1 microsecond = 1/1000000 second
  - ms : milliseconds. 1 millisecond = 1/1000 second. This is the default.
  - s  : seconds. 1s = 1000ms
  - m  : minutes. 1m = 60s = 60000ms
  - h  : hours.   1h = 60m = 3600s = 3600000ms
  - d  : days.    1d = 24h = 1440m = 86400s = 86400000ms
           

HAProxy配置中分五大部分:

  • global:

    全局配置參數,程序級的,用來控制Haproxy啟動前的一些程序及系統設定。

  • defaults:

    配置一些預設的參數,可以被frontend,backend,listen段繼承使用。

  • frontend:

    用來比對接收客戶所請求的域名,uri等,并針對不同的比對,做不同的請求處理

  • backend:

    定義後端伺服器叢集,以及對後端伺服器的一些權重、隊列、連接配接數等選項的設定,我将其了解為Nginx中的upstream塊。

  • listen:

    了解為frontend和backend的組合體。

HAProxy配置檔案的配置方法主要用兩種:一種是由前端(frontend)和後端(backend)配置塊組成,前端和後端都可以有多個。第二種方法是隻有一個listen配置快塊來同時實作前端和後端。我們這裡主要介紹最常用的frontend和backend工作模式,這個也是推薦的配置方法。

同時前端(frontend)區域可以根據HTTP請求的header資訊來定義一些規則,然後将符合某規則的請求轉發到相應後端(backend)進行處理,這個我們後面會詳細講解。

Global配置
global   # 全局參數的設定
log 127.0.0.1 local0 info
     # log文法:log [max_level_1]
     # 全局的日志配置,使用log關鍵字,指定使用127.0.0.1上的syslog服務中的local0日志裝置,記錄日志等級為info的日志
maxconn 4096
     # 定義每個haproxy程序的最大連接配接數,由于每個連接配接包括一個用戶端和一個伺服器端,是以單個程序的TCP會話最大數目将是該值的兩倍。
user haproxy
group haproxy
     # 設定運作haproxy的使用者群組,也可使用uid,gid關鍵字替代之
daemon
     # 以守護程序的方式運作
nbproc 16
     # 設定haproxy啟動時的程序數,根據官方文檔的解釋,我将其了解為:該值的設定應該和伺服器的CPU核心數一緻,即常見的2顆8核心CPU的伺服器,即共有16核心,則可以将其值設定為:<=16 ,建立多個程序數,可以減少每個程序的任務隊列,但是過多的程序數也可能會導緻程序的崩潰。這裡我設定為16
maxconn 4096
     # 定義每個haproxy程序的最大連接配接數,由于每個連接配接包括一個用戶端和一個伺服器端,是以單個程序的TCP會話最大數目将是該值的兩倍。
     #ulimit -n 65536
     # 設定最大打開的檔案描述符數,在1.4的官方文檔中提示,該值會自動計算,是以不建議進行設定
     pidfile /var/run/haproxy.pid# 定義haproxy的pid
           
代理(Proxies)相關配置

使用Haproxy進行反向代理負載均衡,最常修改的部分就是代理相關的配置了,代理相關配置位于下列配置段中:

-   defaults <name>
-   frontend<name>
-   backend  <name>
-   listen   <name>
           
  • "defaults"

    段為其後的所有其他配置段設定預設參數。

    "defaults"

    段可以有多個,後設定的總是會覆寫之前的配置。檢視下面的清單可以知道"defaults"段可以使用哪些配置參數。"defaults"關鍵字是可選的,但是為了更好的可讀性,建議加上。
  • "frontend"

    段描述了一組監聽的套接字,它們接受用戶端連接配接。
  • "backend"

    段描述了一組伺服器,代理(Haproxy)會連接配接這些伺服器并轉發用戶端請求到這些服

    務器上。

  • "listen"

    段定義了一個完整的代理,它的前段(frontend)和後端(frontend)都在這個配置

    段裡。這種配置通常用于僅TCP的流量.代理名必須由大(小)寫字母、數字、'-'、'_'、'.'、':'組成。ACL名字是大小寫敏感的,

    也即www和WWW分别指不同的代理。由于曆史原因,所有的代理名字是可以重疊的,這種僅僅會導緻日志有些問題。後來内容交換

    (Content Switching)的加入使得兩個有重複功能的代理(frontend/backend)必須使用不

    同的名字。然而,仍然允許frontend和backend使用同一個名字,因為這種配置會經常遇到。

目前,HAProxy支援兩種主要的代理模式: "tcp"也即4層,和"http",即7層。在4層模式下,

HAproxy僅在用戶端和伺服器之間轉發雙向流量。7層模式下,HAProxy會分析協定,并且能通過

允許、拒絕、交換、增加、修改或者删除請求(request)或者回應(response)裡指定内容來控制

協定,這種操作要基于特定規則。

Defaults配置
defaults    # 預設部分的定義
mode http
     # mode文法:mode {http|tcp|health} 。http是七層模式,tcp是四層模式,health是健康檢測,傳回OK
log 127.0.0.1 local3 err
     # 使用127.0.0.1上的syslog服務的local3裝置記錄錯誤資訊
retries 3
     # 定義連接配接後端伺服器的失敗重連次數,連接配接失敗次數超過此值後将會将對應後端伺服器标記為不可用
option httplog
     # 啟用日志記錄HTTP請求,預設haproxy日志記錄是不記錄HTTP請求的,隻記錄“時間[Jan 5 13:23:46] 日志伺服器[127.0.0.1] 執行個體名已經pid[haproxy[25218]] 資訊[Proxy http_80_in stopped.]”,日志格式很簡單。
option redispatch
     # 當使用了cookie時,haproxy将會将其請求的後端伺服器的serverID插入到cookie中,以保證會話的SESSION持久性;而此時,如果後端的伺服器宕掉了,但是用戶端的cookie是不會重新整理的,如果設定此參數,将會将客戶的請求強制定向到另外一個後端server上,以保證服務的正常。
option abortonclose
     # 當伺服器負載很高的時候,自動結束掉目前隊列處理比較久的連結
option dontlognull
     # 啟用該項,日志中将不會記錄空連接配接。所謂空連接配接就是在上遊的負載均衡器或者監控系統為了探測該服務是否存活可用時,需要定期的連接配接或者擷取某一固定的元件或頁面,或者探測掃描端口是否在監聽或開放等動作被稱為空連接配接;官方文檔中标注,如果該服務上遊沒有其他的負載均衡器的話,建議不要使用該參數,因為網際網路上的惡意掃描或其他動作就不會被記錄下來
option httpclose
     # 這個參數我是這樣了解的:使用該參數,每處理完一個request時,haproxy都會去檢查http頭中的Connection的值,如果該值不是close,haproxy将會将其删除,如果該值為空将會添加為:Connection: close。使每個用戶端和伺服器端在完成一次傳輸後都會主動關閉TCP連接配接。與該參數類似的另外一個參數是“option forceclose”,該參數的作用是強制關閉對外的服務通道,因為有的伺服器端收到Connection: close時,也不會自動關閉TCP連接配接,如果用戶端也不關閉,連接配接就會一直處于打開,直到逾時。
contimeout 5000
     # 設定成功連接配接到一台伺服器的最長等待時間,預設機關是毫秒,新版本的haproxy使用timeout connect替代,該參數向後相容
clitimeout 3000
     # 設定連接配接用戶端發送資料時的成功連接配接最長等待時間,預設機關是毫秒,新版本haproxy使用timeout client替代。該參數向後相容
srvtimeout 3000
     # 設定伺服器端回應客戶度資料發送的最長等待時間,預設機關是毫秒,新版本haproxy使用timeout server替代。該參數向後相容
           
Listen配置
listen status   # 定義一個名為status的部分
bind 0.0.0.0:1080
     # 定義監聽的套接字
mode http
     # 定義為HTTP模式
log global
     # 繼承global中log的定義
stats refresh 30s
     # stats是haproxy的一個統計頁面的套接字,該參數設定統計頁面的重新整理間隔為30s
stats uri /admin?stats
     # 設定統計頁面的uri為/admin?stats
stats realm Private lands
     # 設定統計頁面認證時的提示内容
stats auth admin:password
     # 設定統計頁面認證的使用者和密碼,如果要設定多個,另起一行寫入即可
stats hide-version
     # 隐藏統計頁面上的haproxy版本資訊
           
Frontend配置
frontend http_80_in # 定義一個名為http_80_in的前端部分
bind 0.0.0.0:80
     # http_80_in定義前端部分監聽的套接字
mode http
     # 定義為HTTP模式
log global
     # 繼承global中log的定義
option forwardfor
     # 啟用X-Forwarded-For,在requests頭部插入用戶端IP發送給後端的server,使後端server擷取到用戶端的真實IP
acl static_down nbsrv(static_server) lt 1
     # 定義一個名叫static_down的acl,當backend static_sever中存活機器數小于1時會被比對到
     use_backend php_server if static_down
     # 如果滿足政策static_down時,就将請求交予backend php_server
           
Backend配置
backend php_server  #定義一個名為php_server的後端部分
mode http
     # 設定為http模式
balance source
     # 設定haproxy的排程算法為源位址hash
cookie SERVERID
     # 允許向cookie插入SERVERID,每台伺服器的SERVERID可在下面使用cookie關鍵字定義
option httpchk GET /test/index.php
     # 開啟對後端伺服器的健康檢測,通過GET /test/index.php來判斷後端伺服器的健康情況
server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
server php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup
     # server文法:server [:port] [param*]
     # 使用server關鍵字來設定後端伺服器;為後端伺服器所設定的内部名稱[php_server_1],該名稱将會呈現在日志或警報中、後端伺服器的IP位址,支援端口映射[10.12.25.68:80]、指定該伺服器的SERVERID為1[cookie 1]、接受健康監測[check]、監測的間隔時長,機關毫秒[inter 2000]、監測正常多少次後被認為後端伺服器是可用的[rise 3]、監測失敗多少次後被認為後端伺服器是不可用的[fall 3]、分發的權重[weight 2]、最為備份用的後端伺服器,當正常的伺服器全部都當機後,才會啟用備份伺服器[backup]

backend static_server
mode http
option httpchk GET /test/index.html
server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 3
           

調試相關配置

  • debug

    啟動debug模式,此模式會dump所有的互動資訊到stdout,并運作于前台(譯注:不進入deamon

    模式)。等效于指令行參數-d. 此參數絕不要用于生産環境,因為它會在系統啟動時被挂起.

  • quiet

    在啟動時不顯示任何資訊。等于指令行參數-v

Haproxy健康檢查

HAProxy作為Loadbalance,支援對backend的健康檢查,以保證在後端backend不能服務時,把從frotend進來的request配置設定至可以其它可服務的backend,進而保證整體服務的可用性。

通過監聽端口進行健康檢測

這種檢測方式,haproxy隻會去檢查後端server的端口,并不能保證服務的真正可用。
listen http_proxy 0.0.0.0:80 
        mode http 
        cookie SERVERID 
        balance roundrobin 
        option httpchk 
        server web1 192.168.1.1:80 cookie server01 check 
        server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2 
           

通過URI擷取進行健康檢測

這種檢測方式,是用過去GET後端server的的web頁面,基本上可以代表後端服務的可用性。
listen http_proxy 0.0.0.0:80 
        mode http 
        cookie SERVERID 
        balance roundrobin 
        option httpchk GET /index.html 
        server web1 192.168.1.1:80 cookie server01 check 
        server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2 
 相關配置
option httpchk <method><uri><version>
           

啟用七層健康檢測

http-check disable-on-404 
如果backend傳回404,則除了長連接配接之外的後續請求将不被配置設定至該backend 
http-check send-state 
增加一個header,同步HAProxy中看到的backend狀态。該header為server可見。 X-Haproxy-Server-State: UP 2/3; name=bck/srv2; node=lb1; weight=1/2; scur=13/22; qcur=0 
server option 
check:啟用健康檢測
inter:健康檢測間隔
rise:檢測服務可用的連續次數
fall:檢測服務不可用的連續次數
error-limit:往server寫資料連續失敗的次數上限,執行on-error的設定
observe <mode>:把正常服務過程作為健康檢測請求,即實時檢測
on-error <mode>:滿足error-limit後執行的操作(fastinter、fail-check、sudden-death、mark-down)。其中fastinter表示立即按照fastinter的檢測延時進行。fail-check表示改次error作為一次檢測;sudden-death表示模仿一次fatal,如果緊接着一次fail則置server為down;mark-down表示直接把server置為down狀态。
其它
retries:連接配接失敗重試的次數,如果重試該次數後還不能正常服務,則斷開連接配接。
           

通過request擷取的頭部資訊進行比對進行健康檢測

這種檢測方式,則是基于進階,精細的一些監測需求。通過對後端服務通路的頭部資訊進行比對檢測。
listen http_proxy 0.0.0.0:80 
        mode http 
        cookie SERVERID 
        balance roundrobin 
        option httpchk HEAD /index.jsp HTTP/1.1\r\nHost:\ www.xxx.com 
        server web1 192.168.1.1:80 cookie server01 check 
        server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2 
           

Haproxy負載均衡算法

HAProxy的算法有如下8種:

roundrobin,表示簡單的輪詢,
static-rr,表示根據權重,建議關注;
leastconn,表示最少連接配接者先處理,建議關注;
source,表示根據請求源IP,建議關注;
uri,表示根據請求的URI;
url_param,表示根據請求的URl參數'balance url_param' requires an URL parameter name
hdr(name),表示根據HTTP請求頭來鎖定每一次HTTP請求;
rdp-cookie(name),表示根據據cookie(name)來鎖定并哈希每一次TCP請求。
           
排程算法source

haroxy 将使用者IP經過hash計算後 指定到固定的真實伺服器上(類似于nginx 的IP hash 指令)

配置指令

balance source

cookie 識别

haproxy 将WEB服務端發送給用戶端的cookie中插入(或添加加字首)haproxy定義的後端的伺服器COOKIE ID。

配置指令例舉

cookie SESSION_COOKIE insert indirect nocache

session 識别

haproxy 将後端伺服器産生的session和後端伺服器辨別存在haproxy中的一張表裡。用戶端請求時先查詢這張表。然後根據session配置設定後端server。

配置指令:

appsession<cookie> len <length> timeout <holdtime>

Haproxy 七層負載均衡
reqirep ^Host:\\ www.abc.com Host:\\ abc.com
acl host_abc_com hdr(host)      -i abc.com
acl host_cn      hdr_end(host)  -i .cn
acl host_xyz     hdr_beg(host)  -i xzy.
acl url_xxx      url_reg        -i ^/xxx
use_backend host-abc-com if host_abc_com 
use_backend host-cn      if host_cn
use_backend host-xyz-url-xxx if host_xyz url_xxx
default_backend default-servers
           
根據URL字尾進行負載均衡
acl php_web url_reg /*.php$
#acl php_web path_end .php # 定義一個名叫php_web的acl,當請求的url末尾是以.php結尾的,将會被比對到,上面兩種寫法任選其一

acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
#acl static_web path_end .gif .png .jpg .css .js .jpeg

# 定義一個名叫static_web的acl,當請求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif結尾的,将會被比對到,上面兩種寫法任選其一

use_backend php_server if php_web
# 如果滿足政策php_web時,就将請求交予backend php_server
use_backend static_server if static_web
# 如果滿足政策static_web時,就将請求交予backend static_server
           
根據url進行負載均衡
acl invitec url_reg /invitec_pk.do
use_backend b_yxpopo_com_pk if invitec
           
根據User-Agent實作域名跳轉

需求如下:

  • 1:域名www.example.com PC端通路正常顯示
  • 2:手機端:Android iPhone 通路首頁跳轉到wap.example.com,
  • 3:static big_* small_* 這幾類檔案開頭的進行跳轉進行跳轉效果如下所示:

    通路:http://club.jesse.com/static/20130916/27635260.htm

    跳轉到:http://3g.club.jesse.com/static/20130916/27635260.htm

  • 4:手機端通路:除規則3以外的不跳轉:如http://club.xywy.com/top.htm通路URL 不變。

Haproxy主要配置如下:

acl static_d path_beg /static /small /big  #比對XX開始的
acl index_page path_reg ^/$  #比對首頁
acl ua hdr_reg(User-Agent) -i iphone android #比對User-Agent類型
acl club hdr_reg(host) -i   club.jesse.com #比對通路的域名
redirect prefix http://3g.club.jesse.com if ua static_d club #比對相關的ACL政策就進行跳轉
redirect prefix http://3g.club.jesse.com if index_page ua club
use_backend club_pool if club
           

Haproxy TCP端口耗盡解決方案

在實際使用過程中,有兩個問題比較容易發生:

  1. TCP端口耗盡
  2. 網卡帶寬跑滿

    本文重點講講如何優化問題1,問題2暫不讨論。

優化一:使用盡可能多的端口

Linux系統預設提供了65K個端口,每當Haproxy建立了一個到MySQL的連接配接,就會消耗一個端口;當Haproxy斷開和MySQL的連接配接時,該端口并不會立即釋放,而是會處于TIME_WAIT狀态(2*MSL),逾時後才會釋放此端口供新的連接配接使用。

我的環境中,

tcp_fin_timeout

為15秒,也就是說如果我環境中的haproxy可以承載的最大并發連接配接數為

64K/(15*2)=2.1K

,可實際上達不到這個上限,原因如下:

net.ipv4.ip_local_port_range = 15000 65000

linux會保留一段端口,實際能參與配置設定的端口數隻有50K,為了獲得盡可能多的可配置設定端口,做如下調整:

# sysctl net.ipv4.ip_local_port_range="1025 65000"
# sysctl net.ipv4.ip_local_port_range="1025 65000"

#記得修改/etc/sysctl.conf中對應的内容
           

優化二:複用處于TIME_WAIT的端口

調整兩個參數:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1 
           

第一個參數很安全,可以不用過多關注。需要注意的是第二個參數,某些情況下會導緻資料包被丢棄。

例如:client通過NAT連接配接haproxy,并且haproxy端打開了tcp_tw_recycle,同時saw_tstamp也沒有關閉,當第一個連接配接建立并關閉後,此端口(句柄)處于TIME_WAIT狀态,在2*MSL時間内又一個client(相同IP,如果打開了xfrm還要相同PORT)發一個syn包,此時linux核心就會認為這個資料包異常,進而丢掉這個包,并發送rst包.

不過通常情況下,client都是通過内網直接連接配接haproxy,是以可以認為tcp_tw_recycle是安全的,隻是需要記住此坑。

優化三:縮短TIME_WAIT時間

Linux系統預設MSL為60秒,也就是正常情況下,120秒後處于TIME_WAIT的端口(句柄)才會釋放,可以将MSL的時間縮小,縮短端口的釋放周期。

# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
# echo 15 > /proc/sys/net/ipv4/tcp_fin_timeout
#這是一個折中的數值,太小也會導緻其它問題
           

優化四:使用多IP

如優化一中所說,我們已經盡可能多的使用了系統提供的端口範圍。但最多依然不超過65K。

Haproxy提供了内建的端口管理方法,可以充分利用以擴大我們的端口範圍。

server mysql0     10.0.3.1:3306 check source 10.0.3.100:1025-65000
server mysql1     10.0.3.1:3306 check source 10.0.3.101:1025-65000
           

如果使用兩個ip,我們可用的端口數就接近130K。擴充多個IP,就可以不斷增加端口數。

優化五:使用長連接配接

服務最好使用長連接配接,一是避免頻繁的申請連接配接,導緻端口耗盡;二是避免建立連接配接帶來的時間消耗。

Haproxy 線上維護

Haproxy Sock

開啟Haproxy Unix Socket

在global添加:

stats socket /usr/local/haproxy/haproxy.sock mode 600 level admin
    stats timeout 2m
           

Socat 工具

socat是一個多功能的網絡工具,名字來由是“Socket CAT”,可以看作是netcat的N倍加強版,socat的官方網站:http://www.dest-unreach.org/socat/ 。

socat是一個兩個獨立資料通道之間的雙向資料傳輸的繼電器。這些資料通道包含檔案、管道、裝置(終端或數據機等)、插座(Unix,IP4,IP6 - raw,UDP,TCP)、SSL、SOCKS4用戶端或代理CONNECT。

socat支援廣播和多點傳播、抽象Unix sockets、Linux tun/tap、GNU readline和PTY。它提供了分叉、記錄和程序間通信的不同模式。多個選項可用于調整socat和其管道,Socat可以作為TCP中繼(一次性或守護程序),作為一個守護程序基于socksifier,作為一個shell Unix套接字接口,作為IP6的繼電器,或面向TCP的程式重定向到一個串行線。

socat的主要特點就是在兩個資料流之間建立通道;且支援衆多協定和連結方式:

ip, tcp, udp, ipv6, pipe,exec,system,open,proxy,openssl,socket

等。

使用socat可以檢視和設定HAProxy狀态,首先得讓HAProxy産生出一個sock出來(hatop ,socat都是基于這個的,沒這個什麼都做不了)。

[[email protected] ~]#yum install –y readline-devel openssl-devel tcp_wrappers
[[email protected] ~]# cd /usr/local/src
[[email protected] src]# wgethttp://www.dest-unreach.org/socat/download/socat-1.7.2.4.tar.gz
[[email protected] src]# tar zxf socat-1.7.2.4.tar.gz 
[[email protected] src]# cd socat-1.7.2.4
[[email protected] socat-1.7.2.4]# ./configure&& make && make install
           

常用功能

擷取幫助:

echo "help"| socat stdio /usr/local/haproxy/haproxy.sock
Unknown command. Please enter one of the following commands only :
clear counters : clear max statistics counters (add 'all' for all counters)
clear table    : remove an entry from a table
help           : this message
prompt         : toggle interactive mode with prompt
quit           : disconnect
show info      : report information about the running process
show pools     : report information about the memory pools usage
show stat      : report counters for each proxy and server
show errors    : report last request and response errors for each proxy
show sess [id] : report the list of current sessions or dump this session
show table [id]: report table usage stats or dump this table's contents
get weight     : report a server's current weight
set weight     : change a server's weight
set server     : change a server's state or weight
set table [id] : update or create a table entry's data
set timeout    : change a timeout setting
set maxconn    : change a maxconn setting
set rate-limit : change a rate limiting value
disable        : put a server or frontend in maintenance mode
enable         : re-enable a server or frontend which is in maintenance mode
shutdown       : kill a session or a frontend (eg:to release listening ports)
show acl [id]  : report avalaible acls or dump an acl's contents
get acl        : reports the patterns matching a sample for an ACL
add acl        : add acl entry
del acl        : delete acl entry
clear acl <id> : clear the content of this acl
show map [id]  : report avalaible maps or dump a map's contents
get map        : reports the keys and values matching a sample for a map
set map        : modify map entry
add map        : add map entry
del map        : delete map entry
clear map <id> : clear the content of this map
set ssl <stmt> : set statement for ssl
#檢視狀态:
echo "show info;show stat" | socat /usr/local/haproxy/haproxy.sock stdio
#關閉節點:
echo "disable server b_yxpopo_com/hongbao-node11" | socat /usr/local/haproxy/haproxy.sock stdio
#啟用節點:
echo "enable server b_yxpopo_com/hongbao-node11" | socat /usr/local/haproxy/haproxy.sock stdio
           

Haproxy+keepalived架構實踐

VRRP介紹

  • VRRP中的角色
  • VRRP路由器

    VRRP路由器就是一台路由器,隻不過上面運作了VRRP協定的程式,比如我們等下要安裝的Keepalived就是運作了VRRPD這樣的程式來實作VRRP協定,我們可以了解為一台實體路由器,需要注意的是一台VRRP路由器可以位于多個虛拟路由器。

    VRRP虛拟路由器

    VRRP虛拟路由器通常有多台實體的VRRP路由器組成,這多台實體路由器組成一個Pool,虛拟路由器在生産環境中可以有多個,通過VRID進行标示。

    MASTER和BACKUP

    在一個VRRP虛拟路由器中,有多台實體的VRRP路由器,但是這多台路由器并不同時工作,而是由一台稱之為MASTER的負責路由工作,其它的都是BACKUP。MASTER并不是一成不變的,VRRP協定讓每個VRRP路由器參與競選,競選成功的就可以成為MASTER。MASTER擁有虛拟路由器的IP位址,我們把這個IP位址稱之為VIP,MASTER負責轉發發送給網關位址的資料包和響應ARP請求。

    VRRP是如何工作的?

    VRRP通過競選協定來實作虛拟路由器的功能,協定封包通過IP多點傳播(多點傳播位址:224.0.0.18)方式進行發送。虛拟路由器有VRID(範圍0-255)和一組IP位址組成,對外表現為一個MAC位址:00-00-5E-00-01-{VRID}。是以,在一個虛拟路由器中,不管誰是Master,對外都是相同的MAC位址和IP位址。如果其中一台虛拟路由器Down機,角色發送切換,那麼用戶端并不需要因為Master的變化修改自己的路由設定,可以做到透明的切換。這樣就實作了如果一台機器當機,那麼備用的機器會擁有MASTER上的IP位址,實作高可用功能。

    VRRP是如何通信的?

    在一個虛拟路由器中,隻有作為MASTER的VRRP路由器會一直發送VRRP廣播包,BACKUP的路由器會被動接收資料庫,不會搶占MASTER。當MASTER不可用時,這個時候BACKUP就收不到廣播包,多台BACKUP中優先級最高的這台會搶占成為MASTER。這個搶占的速度非常快小于1s,幾乎不會影響生産應用。為了安全考慮VRRP的資料包使用了加密協定進行加密。

Keepalived部署

[[email protected] ~]# cd /usr/local/src
[[email protected] src]# wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz
[[email protected] src]# tar zxf keepalived-1.2.19.tar.gz 
[[email protected] src]# cd keepalived-1.2.19
[[email protected] keepalived-1.2.19]# ./configure --prefix=/usr/local/keepalived-1.2.19
[[email protected] keepalived-1.2.19]# make && make install
[[email protected] keepalived-1.2.19]# cp keepalived/etc/init.d/keepalived.init /etc/init.d/keepalived
[[email protected] keepalived-1.2.19]# chmod +x /etc/init.d/keepalived
[[email protected] keepalived-1.2.19]# cp keepalived/etc/init.d/keepalived.sysconfig /etc/sysconfig/keepalived
[[email protected] keepalived-1.2.19]# cp keepalived/etc/keepalived/keepalived.conf /etc
           

Keepalived配置詳解

Keepalived的所有配置都在一個配置檔案裡面,主要分為三大類:

  1. 全局配置
  2. VRRPD配置
  3. LVS配置

    配置檔案是以配置塊的形式存在,每個配置塊都在一個閉合的{}範圍内,所有編輯的時候注意大括号的閉合問題。#和!開頭的都是注釋。

    2.3.1 全局配置

    全局配置是對整個Keepalived生效的配置,一個典型的配置如下:

    global_defs {
    #設定keepalived再發生事件(比如切換)的時候,需要發送到的email位址,可以設定多個,每行一個。
       notification_email {
     [email protected]
       }
    #設定通知郵件發送來自于哪裡
       notification_email_from [email protected]
    #指定發送郵件的smtp伺服器  
     smtp_server 127.0.0.1
    #設定smtp連接配接逾時事件,機關是秒
       smtp_connect_timeout 30
    #設定route_id,是運作keepalived的一個标示,多個叢集設定為不同的。
       router_id nginx_ha
    }
               

VRRPD配置

VRRPD的配置是Keepalived比較重要的配置,主要分為兩個部分VRR同步組合VRRP執行個體,我們先說VRRP執行個體,也就是要想使用VRRP進行高可用選舉,那麼就一定需要配置一個VRRP執行個體,在執行個體中來定義VIP、伺服器角色等。

vrrp_instance NGINX_HA {
    #指定執行個體初始狀态,實際的MASTER和BACKUP是選舉決定的
    state MASTER
#指定執行個體綁定的網卡
    interface eth0
#設定VRID标記,多個叢集不同重複(0..255)
    virtual_router_id 51
#設定優先級,優先級高的會被競選為Master,Master要高于BACKUP至少50
    priority 150
#檢查的時間間隔,預設是1s。
    advert_int 1
#設定驗證的類型和密碼。
    authentication {
        auth_type PASS
        auth_pass nginx
    }
#設定VIP,可以設定多個,用于切換時的位址綁定。
    virtual_ipaddress {
        192.168.99.176
        192.168.99.170
    }
}
           

可選的選項:

設定路由,可以設定多條,用于切換時執行。

virtual_routes{
#src <IPADDR> to <IPADDR>/<MASK> via | gw <IPADDR> dev <STRING> scope <SCOPE>
}
#track_interface 設定額外的監控網卡,如果任何一個出現故障,就會進入FAULT狀态
#mcast_src_ip 設定發送多點傳播的位址,預設是綁定的網卡的primary IP
           

配置案例

! Configuration File for keepalived

global_defs {

notification_email {

[email protected]

}

notification_email_from [email protected]

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id  150

}



vrrp_instance haproxy_ha {

state Master

interface eth0

virtual_router_id 36

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 1111

}

virtual_ipaddress {

192.168.56.20

}

}
           

繼續閱讀