HAProxy优化应用程序速度
HAProxy
HAProxy高性能的反向代理软件,更专注于TCP,HTTP处理,它可以基于四层或七层进行反向代理,尤其适合于高负载且需要进行七层处理的 Web 站点.
单进程、事件驱动模型,通常用于超高流量的负载均衡.
我们也可以使用它来作为中转站,使直连连通率不好的请求进过中转提升速度.
编译安装
apt-get update && apt-get install -y wget gcc g++ make libpcre++0v5 libpcre++-dev
yum update && yum install wget gcc make
HAPROXY_VERSION=haproxy-1.7.9
CPU_NUM=`cat /proc/cpuinfo | grep processor | wc -l`
wget http://www.haproxy.org/download/1.7/src/${HAPROXY_VERSION}.tar.gz
tar zxf ${HAPROXY_VERSION}.tar.gz
cd ${HAPROXY_VERSION}
export CFLAGS="-O3"
make TARGET=linux2628 ARCH=X86_64 USE_STATIC_PCRE=1 -j$CPU_NUM && make install
编译32位版本make TARGET=linux26 ARCH=i686 USE_STATIC_PCRE=1 -j$CPU_NUM
在64位系统下编译32位需要apt-get install gcc-multilib g++-multilib
我编译好的haproxy version 1.7.9
/etc/systemd/system/haproxy.service
[Unit]
Description=haproxy service
[Service]
TimeoutStartSec=0
ExecStart=/usr/local/sbin/haproxy -f /etc/haproxy.cfg
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
alpine里静态编译
apk update && apk upgrade
apk add gcc g++ make wget linux-headers pcre-dev
cd /tmp
HAPROXY_VERSION=haproxy-1.7.9
wget http://www.haproxy.org/download/1.7/src/${HAPROXY_VERSION}.tar.gz
tar zxf ${HAPROXY_VERSION}.tar.gz
cd ${HAPROXY_VERSION}
make TARGET=linux2628 ARCH=X86_64 USE_STATIC_PCRE=1 LDFLAGS="-static" ADDLIB="/usr/lib/libc.a" -j2 && make install
编译很快,一分钟即可编译完成.
不能直接使用LDFLAGS="-static"
静态编译. 需要将 /usr/lib/libc.a
静态链接到最终文件内,因此需要添加ADDLIB="/usr/lib/libc.a"
他使得在link 阶段静态链接/usr/lib/libc.a
上述脚本执行后,即可得到可执行文件. strip后大大减小目标文件.
使用Docker版本的HAProxy
这里提供一份编译好的最新版HAProxy镜像 https://hub.docker.com/r/suconghou/haproxy/
useradd -M -s /sbin/nologin haproxy
-M:不创建家目录
-s:指定用户登陆时使用的shell,nologin就是登陆不了
优化国外主机速度
HAProxy有多种连接模型,还有多种负载均衡算法,由于只有一台机器,我们主要侧重于使用它的反向代理.
HAProxy可以一边保持与代理后端的长连接,一边又保持对客户端的连接. 这样双向保持持久连接,省去了中间反复创建连接可以在一定程度上优化速度.
其只需要一个配置文件,配置主要有以下几部分功能
default
:用于为所有其它配置段提供默认参数frontend
:用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接backend
:用于定义一系列后端服务器,代理将会将对应客户端的请求转发至这些服务器listen
: 通过关联前端和后端定义了一个完整的代理
配置写在haproxy.cfg
文件中,启动的时候指定使用的配置文件.
如haproxy -c -f /etc/haproxy/haproxy.cfg
检查配置文件,haproxy -f /etc/haproxy/haproxy.cfg
使用此配置文件启动
使用listen 直接定义前端/后端
global
pidfile /var/run/haproxy.pid
ulimit-n 65535
user nobody
group nobody
daemon
defaults
log global
mode tcp
retries 3
option dontlognull
timeout connect 10s
timeout client 15m
timeout server 15m
option srvtcpka
option clitcpka
listen sss
bind 0.0.0.0:9878
server v 1.2.3.4:443
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
一个简单的配置文件如下
global
pidfile /var/run/haproxy.pid
user haproxy
group haproxy
daemon
defaults
mode tcp
log global
retries 3
option dontlognull
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 30000
frontend http-in
mode http
bind 0.0.0.0:1080
option http-keep-alive
default_backend servers
backend servers
option http-keep-alive
server myserver 1.2.3.4:80 check maxconn 6000
转发 ssh 服务时,注意,需要将 timeout client
timeout server
设置一个较大的时间,如120m
防止静置的时候ssh被断开
示例
global
pidfile /var/run/haproxy.pid
user nobody
group nobody
ulimit-n 8000
daemon
defaults
mode tcp
log global
retries 3
option dontlognull
option srvtcpka
option clitcpka
option http-keep-alive
timeout connect 10s
timeout client 120m
timeout server 120m
maxconn 30000
listen vpnssh
bind 0.0.0.0:27897
server v 192.243.115.210:27897 maxconn 2048
listen vpn6060
bind 0.0.0.0:16060
server v 192.243.115.210:6060 maxconn 2048
listen vpn8080
bind 0.0.0.0:18080
server v 192.243.115.210:8080 maxconn 2048
listen vpn19090
bind 0.0.0.0:19090-19099
server v 192.243.115.210 maxconn 2048
timeout http request :在客户端建立连接但不请求数据时,关闭客户端连接 timeout queue :等待最大时长 timeout connect: 定义haproxy将客户端请求转发至后端服务器所等待的超时时长 timeout client:客户端非活动状态的超时时长 timeout server:客户端与服务器端建立连接后,等待服务器端的超时时长, timeout http-keep-alive :定义保持连接的超时时长 timeout check:健康状态监测时的超时时间,过短会误判,过长资源消耗
八种负载算法
‘roundrobin’, 简单的轮询 ‘static-rr’, 根据权重 ‘leastconn’, 最少连接者先处理 ‘source’, 根据请求源IP ‘uri’, 根据请求的URI ‘url_param’, 根据请求的URl参数 ‘hdr(name)’ 根据HTTP请求头来锁定每一次HTTP请求 ‘rdp-cookie(name)’ 很据cookie(name)来锁定并哈希每一次TCP请求
长连接
KeepAlive 就是通常所称的长连接,KeepAlive带来的好处是可以减少tcp连接的开销,这对于短response body的请求效果更加明显。
HAProxy后端keepalive指的是在HAProxy服务完一次与后端的交互后,不关闭HAProxy和后端的连接,而是维护这个连接以备后续的请求复用。
HAProxy后端Keepalive 配置,启用HAProxy后端长连接需要配置如下
option http-pretend-keepalive
option srvtcpka
option clitcpka
option forwardfor
其中option forwardfor允许在转发请求到后端时加上X-Forwarded-For头部,可以不使用.
tcp 层的默认链接保持时间,一般默认为2个小时
cat /proc/sys/net/ipv4/tcp_keepalive_time
timeout client
与 timeout server
设置的就是当没有数据传送时,最大空闲多少时间就关闭链接
https://serverfault.com/questions/589804/haproxy-configuration-for-rabbitmq/652326#652326
还有一个在应对高并发时通常都需要改的
ulimit -n 8192
ulimit -n
可以查看当前的
-st
是立即结束原有进程(SIGTERM,立即重启)
-sf
是原有进程执行完后退出(SIGUSR1,平滑重启)
重启HAProxy
# haproxy-reload
haproxy -f /etc/haproxy/haproxy.cfg -st $(cat /var/run/haproxy.pid)
# haproxy-hot-reload
haproxy -f /etc/haproxy/haproxy.cfg -sf $(cat /var/run/haproxy.pid)
/etc/rc.local
(软连接到/etc/rc.d/rc.local
)是开机后自动执行的脚本
可以加入haproxy -f /etc/haproxy/haproxy.cfg
到其中实现开机启动.
配置文件参考 https://github.com/chenzhiwei/linux/tree/master/haproxy
一份haproxy加速ss
global
pidfile /var/run/haproxy.pid
ulimit-n 65535
user nobody
group nobody
daemon
defaults
log global
mode tcp
retries 3
option dontlognull
timeout connect 120s
timeout client 120m
timeout server 120m
option srvtcpka
option clitcpka
frontend ss-in
bind *:80
default_backend ss-out
backend ss-out
server server1 208.81.202.x:443 maxconn 20480
可以直接使用listen,更加简洁的创建一个关联server
global
pidfile /var/run/haproxy.pid
ulimit-n 65535
user nobody
group nobody
daemon
defaults
log global
mode tcp
retries 3
option dontlognull
timeout connect 120s
timeout client 120m
timeout server 120m
option srvtcpka
option clitcpka
listen sss
bind 0.0.0.0:9878
server v 192.243.x.x:1443 maxconn 2048
haproxy -D -f /etc/haproxy/haproxy.cfg
启动,参数-D
为goes daemon
参考 http://liaoph.com/haproxy-tutorial/
https://gist.github.com/SilverBut/32be4a41cbdc50dd3a02627738b2b9cb
升级glibc
版本,最新发布 http://www.gnu.org/software/libc/
所有版本见http://mirror.hust.edu.cn/gnu/libc/
错误 libc.so.6: version GLIBC_2.14 not found
表明当前系统的glibc版本较低
strings libc.so.6 |grep GLIBC_
可以查看当前系统支持的版本
wget http://mirror.hust.edu.cn/gnu/libc/glibc-2.19.tar.xz
tar Jxf glibc-2.19.tar.xz
cd glibc-2.19
mkdir build
cd build
../configure
make -j4 && make install
见 https://cnodejs.org/topic/56dc21f1502596633dc2c3dc 此编译需要较长时间
dog-tunnel端口映射
开启服务器端(须有外网IP)
dtunnel_lite -service 0.0.0.0:1234 -v -tcp -xor 121333 > /tmp/dog.log 2>&1 &
开启客户端(任意一台可联网的机器)
反向映射客户机22端口到服务器的30222端口,代理ssh建议使用tcp,pipe通道为1
dtunnel_lite -service 服务器端IP:1234 -v -action 127.0.0.1:22 -encrypt -tcp -xor 121333 -local 172.168.1.99:30222 -r > /tmp/dog.log 2>&1 &
可以使用客户端连接多个服务器,将22端口映射到多个服务器端.
用crontab
守护进程,每5分钟检查一次
*/5 * * * * sh /data/bin/connect.sh > /tmp/dog.log 2>&1
#!/bin/bash
echo "`date` start shell process ">> /tmp/connect.log
if test $( pgrep -f dtunnel_lite | wc -l ) -eq 0
then
while true
do
echo "`date` dtunnel_lite process is starting...">> /tmp/connect.log
touch /run/connect.lock
dtunnel_lite -service x.x.x.x:1234 -v -action 127.0.0.1:22 -encrypt -tcp -xor 121333 -local 172.168.1.99:30222 -r
echo "`date` dtunnel_lite process killed,todo restart ">> /tmp/connect.log
sleep 5
done
else
touch /run/connect.lock
echo "`date` dtunnel_lite process is already running ">> /tmp/connect.log
fi
先手动启动一次 sh /data/bin/connect.sh > /tmp/dog.log 2>&1 &
TCP 端口转发
Socat:
优点:支持 TCP/UDP 转发。缺点:不支持端口段(多个端口需要开启多个转发)
HaProxy:
优点:支持 TCP 转发,支持 端口段 转发。缺点:不支持 UDP 转发。
iptables:
优点:支持 TCP/UDP 转发,支持 端口段 转发。缺点:配置麻烦,容易出错。
socat 支持unixsocket转发
socat TCP4-LISTEN:15432,fork UNIX-CONNECT:/srv/mongodb-27017.sock
haproxy 用作缓存
https://github.com/jiangwenyuan/nuster/wiki/Performance-benchmark:-nuster-vs-nginx-vs-varnish