HAProxy 代理負載均衡


 

                        HAProxy

    HAProxy是免費 高效 可靠的高可用及負載均衡解決方案,該軟件非常適合於處理高負載
站點的七層數據請求,HAProxy的工作模式使其可以非常容易且安全地集成到我們現有的站點
架構中。使用類似的代理軟件還可以對外屏蔽內部真實Web服務器,防止內部服務器遭受外部攻擊

 

Haproxy有8種負載均衡算法(balance),分別如下:

1.balance roundrobin # 輪詢,軟負載均衡基本都具備這種算法

2.balance static-rr # 根據權重,建議使用

3.balance leastconn # 最少連接者先處理,建議使用

4.balance source # 根據請求源IP,建議使用

5.balance uri # 根據請求的URI

6.balance url_param,# 根據請求的URl參數'balance url_param' requires an URL parameter name

7.balance hdr(name) # 根據HTTP請求頭來鎖定每一次HTTP請求

8.balance rdp-cookie(name) # 根據據cookie(name)來鎖定並哈希每一次TCP請求

 

由於負載請求分發到不同服務器,可能導致Session會話不同步的問題,若想實現會話共享或保持,可采用如下3種方式:

1.用戶IP 識別

haroxy 將用戶IP經過hash計算后 指定到固定的真實服務器上(類似於nginx 的IP hash 指令)

配置指令

balance source

2.Cookie 識別

haproxy 將WEB服務端發送給客戶端的cookie中插入(或添加加前綴)haproxy定義的后端的服務器COOKIE ID。

配置指令例舉

cookie SESSION_COOKIE insert indirect nocache

用firebug可以觀察到用戶的請求頭的cookie里 有類似” Cookie jsessionid=0bc588656ca05ecf7588c65f9be214f5; SESSION_COOKIE=app1” SESSION_COOKIE=app1就是haproxy添加的內容

3.Session 識別

haproxy 將后端服務器產生的session和后端服務器標識存在haproxy中的一張表里。客戶端請求時先查詢這張表。

配置指令例舉

appsession JSESSIONID len 64 timeout 5h request-learn

 

 

 

安裝部署HAProxy

 

環境准備:兩台機器

linux-node1.example.com     192.168.56.11

linux-node2.example.com     192.168.56.12

 

第一台

[root@linux-node1 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@linux-node1 ~]# uname -r 3.10.0-327.el7.x86_64 關閉防火牆及SELIUNX #systemctl disable firewalld #systemctl disable NetworkManager # cat /etc/selinux/config SELINUX=disabled 安裝依賴包epel rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
yum -y install net-tools vim lrzsz tree screen lsof tcpdump nc mtr nmap wget gcc glibc gcc-c++ make 

 

第二台

[root@linux-node2 ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@linux-node2 ~]# uname -r 3.10.0-327.el7.x86_64 關閉防火牆及SELIUNX #systemctl disable firewalld #systemctl disable NetworkManager # cat /etc/selinux/config SELINUX=disabled 安裝系統依賴包 #rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
#yum -y install net-tools vim lrzsz tree screen lsof tcpdump nc mtr nmap wget gcc glibc gcc-c++ make 


 

 

部署應用

在兩台機器部署apache作為RS

linux-node1.example.com

[root@linux-node1 ~]# yum -y install httpd [root@linux-node1 ~]# vim /etc/httpd/conf/httpd.conf ServerName 192.168.56.11 Listen 8080 [root@linux-node1 ~]# systemctl enable httpd [root@linux-node1 ~]# systemctl start httpd [root@linux-node1 ~]# echo "chuck-test1" > /var/www/html/index.html [root@linux-node1 ~]# netstat -tunlp | grep httpd tcp6 0      0 :::8080                 :::*                    LISTEN      2836/httpd [root@linux-node1 ~]# curl http://192.168.56.11:8080
chuck-test1

 

linux-node2.example.com

[root@linux-node2 ~]# yum -y install httpd [root@linux-node2 ~]# vim /etc/httpd/conf/httpd.conf ServerName 192.168.56.12 Listen 8080 [root@linux-node2 ~]# systemctl enable httpd [root@linux-node2 ~]# systemctl start httpd [root@linux-node2 ~]# echo "chuck-test2" > /var/www/html/index.html [root@linux-node2 ~]# netstat -tunlp | grep httpd tcp6 0      0 :::8080                 :::*                    LISTEN      2836/httpd [root@linux-node2 ~]# curl http://192.168.56.12:8080
chuck-test2

 

Linux-node1上面安裝HAProxy軟件

[root@linux-node1 ~]# cd /usr/local/src/ [root@linux-node1 src]# wget http://www.haproxy.org/download/1.6/src/haproxy-1.6.3.tar.gz
[root@linux-node1 src]# tar zxf haproxy-1.6.3.tar.gz [root@linux-node1 src]# cd haproxy-1.6.3 [root@linux-node1 haproxy-1.6.3]# make TARGET=linux2628 PREFIX=/usr/local/haproxy-1.6.3 [root@linux-node1 haproxy-1.6.3]# make install [root@linux-node1 haproxy-1.6.3]# cp /usr/local/sbin/haproxy /usr/sbin/ [root@linux-node1 haproxy-1.6.3]# haproxy -v HA-Proxy version 1.6.3 2015/12/25 Copyright 2000-2015 Willy Tarreau <willy@haproxy.org>

 

編輯haproxy啟動腳本

[root@linux-node1 haproxy-1.6.3]# cd /usr/local/src/haproxy-1.6.3 [root@linux-node1 haproxy-1.6.3]# cp examples/haproxy.init /etc/init.d/haproxy [root@linux-node1 haproxy-1.6.3]# chmod 755 /etc/init.d/haproxy

 

針對配置文件下的路徑創建目錄

[root@linux-node1 ~]# useradd -r haproxy [root@linux-node1 ~]# mkdir /etc/haproxy [root@linux-node1 ~]# mkdir /var/lib/haproxy [root@linux-node1 ~]# mkdir /var/run/haproxy

 

編輯haproxy配置文件,配置log,並啟動

[root@linux-node1 ~]# cd /etc/haproxy/ [root@linux-node1 haproxy]# cat haproxy.cfg global #全局配置,在所有配置段中都生效 log 127.0.0.1 local3 info #記錄日志 chroot /var/lib/haproxy user haproxy group haproxy daemon defaults #默認配置,可以被前端和后端繼承 log global #使用global的log設置 mode http #使用http模式,也可以使用tcp模式 option httplog #啟動http請求的log option dontlognull #在日志中不記錄空連接(空連接:健康檢查的鏈接) timeout connect 5000 #長連接超時時間 timeout client 50000 #客戶端連接超時 timeout server 50000 #RS連接超時 frontend www_chuck-blog_com #前端配置 + 一個配置段的名字(最好不要亂寫,和項目直接相關最佳) mode http #使用http模式,也可以使用tcp模式 bind *:80 #監聽80端口 stats uri /haproxy?stats #狀態頁面dashboard default_backend www_chuck-blog_com_backend #對應的backend名稱 backend www_chuck-blog_com_backend #對應的frontend的default_backend #source cookie SERVERID option httpchk GET /index.html #設置檢測url的詳細的頁面 balance roundrobin #使用rr負載均衡方式 server linux-node1 192.168.56.11:8080 check inter 2000 rise 3 fall 3 weight 5 server linux-node2 192.168.56.12:8080 check inter 2000 rise 3 fall 3 weight 1 #RS健康檢測時間間隔2秒,重試三次,失敗三次不可用,權重1

 

打開rsyslog配置文件的注釋

[root@linux-node1 haproxy]# vim /etc/rsyslog.conf 15 $ModLoad imudp #打開注釋 16 $UDPServerRun 514 #打開注釋 local7.* /var/log/boot.log #在此行的下面添加如下內容 local3.* /var/log/haproxy.log #local3的路徑

 

啟動HAProxy

[root@linux-node1 haproxy]# systemctl restart rsyslog.service [root@linux-node1 haproxy]# /etc/init.d/haproxy start

 

檢查是否成功

查看檢測狀態

 

 通過ACL設置虛擬主機

 

通過acl設置虛擬主機,一個前端可以對應多個后端

[root@linux-node1 haproxy]# cat 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 www_chuck-blog_com mode http bind *:80 stats uri /haproxy?stats
   #默認的backend default_backend www_chuck
-blog_com_backend acl is_other_chuck-blog_com hdr_end(host) other.chuck-blog.com
  #is_other_chuck-blog_com:給此acl起一個名字;hdr(host):固定格式,用來識別host,如果沒有匹配到acl,即訪問default的bankcend use_backend other_chuck
-blog_com_backend if is_other_chuck-blog_com
  #use_backend:關鍵詞,使用哪個banckend;other_chuck-blog_com_backend:指定哪個backend的名稱;if is_other_chuck-blog_com:用來判斷acl backend www_chuck
-blog_com_backend option forwardfor header X-REAL-IP option httpchk GET /index.html balance roundrobin server linux-node1 192.168.56.11:8080 check inter 2000 rise 3 fall 3 weight 1 backend other_chuck-blog_com_backend option forwardfor header X-REAL-IP option httpchk GET /index.html balance roundrobin server linux-node2 192.168.56.12:8080 check inter 2000 rise 3 fall 3 weight 1

 

重啟

[root@linux-node1 ~]# systemctl reload haproxy

 

在本地電腦使用host解析

192.168.56.11 www.chuck-blog.com other.chuck-blog.com

 

通過瀏覽器訪問不同的域名

在fortend添加acl,根據靜態文件,設置不同的backend(類似於location),注釋的兩行和前兩行的意義相同

分別是通過url正則匹配和url的后綴匹配

acl is_static_reg url_reg /*.(css|jpg|png|js|jpeg|gif)$ use_backend other_chuck-blog_com_backend if is_static_reg #acl is_static_path path_end .gif .png .css .jpg .jpeg #use_backend other_chuck-blog_com_backend if is_static_path

[root@linux-node2 ~]# echo "This is a static test page " >/var/www/html/abc.js
[root@linux-node1 ~]# /etc/init.d/haproxy restart

 

打開瀏覽器查看

其它ACL  可以查看百度

acl is_do_path url_reg /chuck.do use_backend other_chuck-blog_com_backend if is_do_path acl is_UA_path hdr_reg(User-Agent) -i andriod #基於安卓手機 use_backend other_chuck-blog_com_backend if is_UA_path

 

 

HAProxy動態維護

在配置文件添加socket

[root@linux-node1 haproxy]# head -8 haproxy.cfg global log 127.0.0.1 local3 info chroot /var/lib/haproxy user haproxy group haproxy daemon  stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
  #指定socket文件路徑,權限,管理級別 stats timeout 2m
  #指定超時時間

 

重啟服務生效

[root@linux-node1 haproxy]# /etc/init.d/haproxy restart

 

安裝socat連接haproxy.sock文件

[root@linux-node1 ~]yum install -y socat

 

使用help查看socat的事情

[root@linux-node1 haproxy]# echo "help" |socat stdio /var/lib/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 backend : list backends in the current running config show info : report information about the running process #查看所有信息 show pools : report information about the memory pools usage #查看所有poll 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
  show servers state [id]: dump volatile server information (for backend <id>) get weight     : report a server's current weight #獲得權重信息
  set weight     : change a server's weight #設置權重
  set server     : change a server's state, weight or address #改變一個server的轉態權重或地址
  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 #將一個server或者fortend置於維護模式 enable : re-enable a server or frontend which is in maintenance mode #啟用一個維護狀態的server或者frontend 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

 

 設置監控

查看info信息,內容值可以利用來監控

[root@linux-node1 haproxy]# echo "show info" |socat stdio /var/lib/haproxy/haproxy.sock Name: HAProxy Version: 1.6.3 Release_date: 2015/12/25 Nbproc: 1 Process_num: 1 Pid: 6778 Uptime: 0d 0h16m20s Uptime_sec: 980 Memmax_MB: 0 Ulimit-n: 4033 Maxsock: 4033 Maxconn: 2000 Hard_maxconn: 2000 CurrConns: 0 CumConns: 10 CumReq: 12 Maxpipes: 0 PipesUsed: 0 PipesFree: 0 ConnRate: 0 ConnRateLimit: 0 MaxConnRate: 2 SessRate: 0 SessRateLimit: 0 MaxSessRate: 2 CompressBpsIn: 0 CompressBpsOut: 0 CompressBpsRateLim: 0 Tasks: 8 Run_queue: 1 Idle_pct: 100 node: linux-node1.example.com description: 

 

關閉主機

關閉linux-node2主機

 

[root@linux-node1 haproxy]# echo "disable server other_chuck-blog_com_backend/linux-node2" |socat stdio /var/lib/haproxy/haproxy.sock [root@linux-node1 haproxy]# Message from syslogd@localhost at Dec  4 13:31:37 ... haproxy[6778]: backend other_chuck-blog_com_backend has no server available!

可以看到 linux -node2  進入了維護maintain狀態 

 

開啟主機

打開linux-node2主機(只對現有的server生效,不能用來新增節點)

[root@linux-node1 haproxy]# echo "enable server other_chuck-blog_com_backend/linux-node2" |socat stdio /var/lib/haproxy/haproxy.sock

可以看到linux-node2恢復正常

 

 

生產問題

haproxy的本地端口可能用盡,解決方案

1)更改local的端口范圍,調整內核參數

[root@linux-node1 haproxy]# cat /proc/sys/net/ipv4/ip_local_port_range 32768    61000

 

2)調整timewait的端口復用,設置為1

[root@linux-node1 haproxy]# cat /proc/sys/net/ipv4/tcp_tw_reuse 0

 

3)縮短tcp_wait的時間,並不建議修改

[root@linux-node1 haproxy]# cat /proc/sys/net/ipv4/tcp_fin_timeout 60

 

4)終極方案:增加為多個ip,自然端口數就夠了

 

haproxy對比nginx

 

nginx

優點:

1 web服務器,應用比較廣泛

2 7層負載均衡,location設置復雜的基於HTTP的負載均衡

3 性能強大,網絡依賴小

4 安裝配置簡單

缺點

1 監控檢查單一

2 負載均衡算法少

3 不能動態管理

4 沒有集群upstream的狀態頁面

 

haproxy

優點

1 專門做負載均衡

2 負載均衡算法多

3 性能>=nginx

4 通過和haproxy socker通信進行動態管理

5 有比較豐富的dashboard頁面

6 強大的7層代理

 

缺點

1 配置沒有nginx簡單

2 應用沒有nginx廣泛

 

提示:很多CDN會使用LVS+Haproxy來做負載均衡

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM