前言 :HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是免費、快速而且可靠的一種解決方案。而mysql一主多從是比較通用的架構,咱們能夠利用haproxy在tcp層對數據庫的讀請求進行代理,從而實現多個從庫讀的負載均衡。mysql
目前公司的業務都是一主多從,想要把查詢分到多個從庫上,都是經過開發維護多個從庫的配置來實現,這樣比較麻煩,經過haproxy開發只須要一個配置項,開發不用理會後端有多少從庫,並且能夠把多個從庫都利用起來,同時後臺db有故障haproxy能夠自動摘除,不須要像原先那樣須要開發改數據庫配置。linux
一 環境說明:web
我這裏都是debian系統 haproxy +mysql_master 192.168.6.123 mysql_slave1 192.168.4.21 mysql_slave2 192.168.9.53
二 haprox安裝
下載,解壓,下載鏈接 http://down.51cto.com/data/2458810sql
make TARGET=linux26 ARCH=x86_64 PREFIX=/home/yx/server/haproxy # 編譯 make install PREFIX=/home/yx/server/haproxy # 安裝
二 配置文件默認沒有,須要手動建立數據庫
global log 127.0.0.1 local2 # chroot /var/lib/haproxy pidfile /home/yx/server/haproxy/haproxy.pid maxconn 4000 #user haproxy #group haproxy daemon defaults mode tcp log global option httplog option dontlognull retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 ## 定義一個監控頁面,監聽在1080端口,並啓用了驗證機制 listen stats mode http bind 192.168.6.123:1080 stats enable stats hide-version stats uri /haproxyadmin?stats stats realm Haproxy\ Statistics stats auth admin:admin stats admin if TRUE frontend mysql bind *:3306 mode tcp #log global option tcplog default_backend mysqlservers backend mysqlservers balance leastconn server zook-3 192.168.4.21:3306 check port 3306 rise 1 fall 2 maxconn 300 server zook-2 192.168.9.53:3306 check port 3306 rise 1 fall 2 maxconn 300
配置文件參數介紹vim
backup:設定爲備用服務器,僅在負載均衡場景中的其它server均不可用於啓用此server; check:啓動對此server執行健康狀態檢查,其能夠藉助於額外的其它參數完成更精細的設定,如: inter <delay>:設定健康狀態檢查的時間間隔,單位爲毫秒,默認爲2000;也可使用fastinter和downinter來根據服務器端狀態優化此時間延遲; rise <count>:設定健康狀態檢查中,某離線的server從離線狀態轉換至正常狀態須要成功檢查的次數; fall <count>:確認server從正常狀態轉換爲不可用狀態須要檢查的次數; cookie <value>:爲指定server設定cookie值,此處指定的值將在請求入站時被檢查,第一次爲此值挑選的server將在後續的請求中被選中,其目的在於實現持久鏈接的功能; maxconn <maxconn>:指定此服務器接受的最大併發鏈接數;若是發往此服務器的鏈接數目高於此處指定的值,其將被放置於請求隊列,以等待其它鏈接被釋放;
三 啓動後端
yx@es-2:~/server/haproxy$ sudo ./sbin/haproxy -f etc/haproxy.cfg -c #檢測配置文件是否正確 出現 Configuration file is valid 是正常 sudo ./sbin/haproxy -f etc/haproxy.cfg 啓動服務 sudo /etc/init.d/haproxy start # 用腳本啓動 用ps aux | grep haprox查看
啓動腳本實例瀏覽器
#!/bin/bash # # haproxy # # chkconfig: 35 85 15 # description: HAProxy is a free, very fast and reliable solution \ # offering high availability, load balancing, and \ # proxying for TCP and HTTP-based applications # processname: haproxy # config: /etc/haproxy.cfg # pidfile: /var/run/haproxy.pid # Source function library. # . /etc/rc.d/init.d/functions . /lib/lsb/init-functions # Source networking configuration. # . /etc/sysconfig/network #/run/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 config="/home/yx/server/haproxy/etc/haproxy.cfg" # 根據本身安裝的路徑來寫 exec="/home/yx/server/haproxy/sbin/haproxy" #根據本身安裝的路徑來寫 prog=$(basename $exec) [ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog lockfile=/run/lock/haproxy check() { $exec -c -V -f $config } start() { $exec -c -q -f $config if [ $? -ne 0 ]; then echo "Errors in configuration file, check with $prog check." return 1 fi echo -n $"Starting $prog: " # start it up here, usually something like "daemon $exec" start-stop-daemon --quiet --oknodo --start --pidfile /var/run/"$prog.pid" \ --exec "$exec" -- -f "$config" -D -p /var/run/"$prog.pid" || return 2 retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " # stop it here, often "killproc $prog" killproc $prog retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { $exec -c -q -f $config if [ $? -ne 0 ]; then echo "Errors in configuration file, check with $prog check." return 1 fi stop start } reload() { $exec -c -q -f $config if [ $? -ne 0 ]; then echo "Errors in configuration file, check with $prog check." return 1 fi echo -n $"Reloading $prog: " $exec -D -f $config -p /var/run/$prog.pid -sf $(cat /var/run/$prog.pid) retval=$? echo return $retval } force_reload() { restart } fdr_status() { status } case "$1" in start|stop|restart|reload) $1 ;; force-reload) force_reload ;; checkconfig) check ;; status) fdr_status ;; condrestart|try-restart) [ ! -f $lockfile ] || restart ;; *) echo $"Usage: $0 {start|stop|status|checkconfig|restart|try-restart|reload|force-reload}" exit 2 esac
把上面的腳本放到/etc/init.d/目錄下,加上執行權限便可bash
用腳本啓動的時候若是報下面的錯誤服務器
Proxy 'admin_stats': stats admin will not work correctly in multi-process mode. [./haproxy.main()] FD limit (16384) too low for maxconn=20000/maxsock=40014. Please raise 'ulimit-n' to 40014 or more to avoid any trouble. 請設置參數ulimit-n 的值等於maxconn的2倍
四 瀏覽器訪問
http://192.168.6.123:1080/haproxyadmin?stats # 後面的路徑跟你配置文件裏面的要一致
五 開啓haproxy日誌
建立日誌目錄 mkdir -p /home/yx/server/haproxy/log 更改 sudo vim /etc/rsyslog.conf 這個配置文件 $ModLoad imudp # 把前面的#號去掉 $UDPServerRun 514 # 把前面的#號去掉 local2.* /home/yx/server/haproxy/log/haproxy.log # 手動添加,local2.* 要跟你haproxy配置文件裏面的一致 sudo etc/init.d/rsyslog restart # 重啓rsylog服務
六 從數據庫設置
在slave1和slave2上分別給haproxy的ip受權:
> grant all privileges on *.* to yx1@192.168.6.123 identified by '123456'; grant all privileges on *.* to 'yx1'@'192.168.6.123' identified by '123456'; > flush privileges;
在6.123上面及haproxy上面,測試可否用新建立的帳戶登陸slave上面的數據庫,若是能正常登陸才能夠
mysql -uyx1 -p123456 -h192.168.4.21 -P3306
用瀏覽器查看,兩個從數據庫也正常了
七 負責均衡測試:
在兩個從上面分別在一個數據庫裏面創建兩個不一樣的表,我這裏一個只有一個tb1 ,另外一個有兩個表分別是tb1,和tb2
#slave1: create table tb1 (`id` int(4),`name` char(40)); # slave2 create table tb1 (`id` int(4),`name` char(40)); create table tb2 (`id` int(4),`name` char(40));
而後用下面的命令在haproxy上面執行,查詢獲得的結果
mysql -h192.168.6.123 -P3306 -uyx1 -p123456 -e "use test;show tables;"
以下圖所示:
八 failover測試,把其中一個slave服務停掉
查詢日誌顯示
2019-01-10T14:50:10+08:00 localhost haproxy[8445]: Server mysqlservers/zook-3 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue
web界面顯示,紅色表明故障
查詢返回的結果只顯示其中一個