前言 :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界面显示,红色表明故障
查询返回的结果只显示其中一个