ha proxy可以用于mysql吗

ha proxy可以用于mysql吗,第1张

可以用于mysql。

使用HAProxy路由MySQL读请求

以下的例子使用HAProxy转发请求到两台mysql从库上。

Mysql:mysql 5.5

HAProxy IP: 172.28.10.192

Mysql Slave1:172.28.10.145

Mysql Slave2:172.28.10.150

在172.28.10.192上编译和安装haproxy

[root@cscscslocalhost 1109]# tar -zvfx haproxy-1.4.21.tar.gz

[root@cscscslocalhost haproxy-1.4.21]#make TARGET=linux26 PERFIX=/usr/local/haproxy

[root@cscscslocalhost haproxy-1.4.21]# make install PREFIX=/usr/local/haproxy

install -d /usr/local/haproxy/sbin

install haproxy /usr/local/haproxy/sbin

install -d /usr/local/haproxy/share/man/man1

install -m 644 doc/haproxy.1 /usr/local/haproxy/share/man/man1

install -d /usr/local/haproxy/doc/haproxy

for x in configuration architecture haproxy-en haproxy-frdo \

install -m 644 doc/$x.txt /usr/local/haproxy/doc/haproxy \

--查看haproxy版本,如有返回表示安装成功

[root@cscscslocalhost haproxy-1.4.21]# haproxy -v

HA-Proxy version 1.4.21 2012/05/21

Copyright 2000-2012 Willy Tarreau <w@1wt.eu>

[root@cscscslocalhost haproxy]# cd /usr/local/haproxy

--在haproxy安装目录中,新建conf和logs目录

[root@cscscslocalhost haproxy]# mkdir conf

[root@cscscslocalhost haproxy]# mkdir logs

[root@cscscslocalhost haproxy]# ls

conf doc logs sbin share

--编写haproxy的配置文件,在haproxy的软件包中examples中有例子,可以复制过来再修改.

值得注意的有轮询方式,转发方式,每服务器的权重等信息。

[root@cscscslocalhost haproxy]# vi /etc/haproxy.cfg

global

log 127.0.0.1 local0

log 127.0.0.1 local1 notice

#log loghostlocal0 info

maxconn 4096

chroot /usr/share/haproxy

uid 99

gid 99

daemon

#debug

#quiet

defaults

log global

modetcp

option httddplog

option dontlognull

retries 3

redispatch

maxconn 2000

contimeout 5000

clitimeout 50000

srvtimeout 50000

listen mysql_proxy

bind 0.0.0.0:23306

mode tcp

balance roundrobin

server db1 172.28.10.145:3307 check inter 2000 rise 2 fall 5 weight 1

server db2 172.28.10.150:3306 check inter 2000 rise 2 fall 5 weight 1

--新建对应的chroot目录,否则会报错,haproxy不能正常启动

[root@cscscslocalhost haproxy]# haproxy -f /etc/haproxy.cfg

[ALERT] 314/142955 (12657) : [haproxy.main()] Cannot chroot(/usr/share/haproxy).

[root@cscscslocalhost haproxy]# mkdir /usr/share/haproxy

--启动haproxy,查看端口,确保启动成功.

[root@cscscslocalhost haproxy]# haproxy -f /etc/haproxy.cfg

[root@cscscslocalhost haproxy]# netstat -nltp | grep haproxy

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name

tcp0 0 0.0.0.0:23306 0.0.0.0:* LISTEN 12674/haproxy

--修改日志的相关配置,让haproxy能够输出日志信息

[root@cscscslocalhost log]# vi /etc/syslog.conf

local6.* /var/log/haproxy.log

[root@cscscslocalhost haproxy]# vi /etc/sysconfig/syslog

SYSLOGD_OPTIONS=" -r -m 0"

[root@cscscslocalhost haproxy]# service syslog restart

Shutting down kernel logger: [ OK ]

Shutting down system logger: [ OK ]

Starting system logger: [ OK ]

Starting kernel logger: [ OK ]

--到此haproxy已经能够正常的转发mysql请求到后端的真正mysql服务器上了。

Haproxy作为MySQL中间层是很成熟的方案,特别是解决从库的负载均衡和故障切换,在生产环境中有着广泛的应用。

MySQL client(应用工程) <------> HAproxy <----->MySQL

HAproxy作为反向代理,会使用自己的IP地址作为源地址连接后端的MySQL服务器。

根据TCP协议,无论任何类型 *** 作系统都只能拥有64K个左右的源TCP端口,用于向外发起TCP连接。

一旦"srcIP:port =>dstIP:port"建立,这个源端口将不能被重用于其它连接。

TCP状态图中有一个TIME_WAIT状态,就是所谓的2MSL状态。

MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。

MSL在RFC 1122上建议是2分钟,而源自Berkeley的TCP实现传统上使用30秒。

因而,TIME_WAIT状态一般维持在1-4分钟。

该状态是为了可靠地实现TCP全双工连接的终止,保证在tcp客户端发给tcp服务端的最后一个ACK能顺利到达。

若没有TIME_WAIT状态,tcp客户端将直接进入CLOSED状态。

如果tcp客户端直接进入CLOSED状态,那么由于IP协议的不可靠性或者是其它网络原因,导致tcp服务端没有收到tcp客户端最后回复的ACK。那么tcp服务端就会在超时之后继续发送FIN,此时由于tcp客户端已经CLOSED了,就找不到与重发的FIN对应的连接,最后tcp服务端就会收到 RST而不是ACK,tcp服务端就会以为是连接错误把问题报告给高层协议。

这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。

所以,tcp客户端不是直接进入CLOSED状态,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。

注意2点:

1、对于tcp请求来说,tcp的客户端服务端概念和http的不同,请求双方,哪边关闭请求,哪边就是tcp客户端,另一边就为服务端。

2、tcp的一个链接由4个值确定,源ip、源端口、目标ip、目标地址。

根据上述的论述,如果一个源端口在2分钟内不能再次使用,则超过534个/秒的MySQL Client请求将会耗尽其本地TCP源端口。

64000 (可用端口) / 120 (2分钟,即120秒) = 533.333

因为HAproxy作为反向代理,会将所有MySQL请求转发给MySQL Server,因此HAproxy会比MySQL Client更快的耗尽本地TCP源端口!

但是如果MySQL Client和MySQL Server在同一台主机上,使用looback接口通信,则MySQL关闭序列是一个相对"干净"的序列。

对于分布式部署架构,用 loopback接口是不现实了。

1.增加本地端口范围

2.允许处于TIME_WAIT状态的源端口重用

注意:不要开启此参数 net.ipv4.tcp_tw_recycle = 1 ,某些情况下会导致数据包被丢弃。

如果client通过NAT连接HAproxy,并且HAproxy端打开了tcp_tw_recycle,同时tcp_timestamps也没有关闭,当第一个连接建立并关闭后,此端口(句柄)处于TIME_WAIT状态,在2*MSL时间内又一个client(相同IP,如果打开了相同PORT)发一个syn包,此时Linux内核就会认为这个数据包异常,从而丢掉这个包,并发送RST包。

不过通常情况下,client都是通过内网直接连接HAproxy,所以可以认为tcp_tw_recycle是安全的,只是需要记住此坑。

新版本内核中已经将此配置废弃了。

3.使用多个IP连接单一dstIP:port,并让HAproxy来管理源端口

配置示例:

经过测试,如果不让HAproxy管理源端口,则4个源IP地址最多管理不超过80K个TIME_WAIT连接,但是haproxy管理源端口可以达到170K+个TIME_WAIT连接!

Linux Increase TCP Port Range with net.ipv4.ip_local_port_range Kernel Parameter

https://www.cyberciti.biz/tips/linux-increase-outgoing-network-sockets-range.html

HAProxy, High MySQL Request Rate and TCP Source Port Exhaustion

https://www.haproxy.com/blog/haproxy-high-mysql-request-rate-and-tcp-source-port-exhaustion

http://omnitraining.net/networking-101/98-networking-101-understanding-tcp-part-2

How to view and edit the ephemeral port range on Linux?

https://stackoverflow.com/questions/28573390/how-to-view-and-edit-the-ephemeral-port-range-on-linux

如何解决使用nginx作为反向代理端口耗尽问题?

https://blog.csdn.net/michaelwoshi/article/details/120170134

HAproxy开启了IP_BIND_ADDRESS_NO_PORT支持 ,即可以复用source port

这样可以从更基础的内核层面解决这个问题,唯一不足是需要将内核升级到4.2以上版本才可以

http://www.haproxy.org/download/1.7/src/CHANGELOG

https://kernelnewbies.org/Linux_4.2#head-8ccffc90738ffcb0c20caa96bae6799694b8ba3a

Overcoming Ephemeral Port Exhaustion in NGINX and NGINX Plus

https://www.nginx.com/blog/overcoming-ephemeral-port-exhaustion-nginx-plus

tcp四次挥手状态 TIME_WAIT

https://www.jianshu.com/p/3658730d76d7

nginx使用proxy_bind负载tcp socket,解决代理端口耗尽

https://b.sundayle.com/nginx-proxy-65535-port


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7391351.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-05
下一篇 2023-04-05

发表评论

登录后才能评论

评论列表(0条)

保存