haproxy快速入门

haproxy简介

HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。

haproxy的优势

  • 专门做反向代理负载均衡
  • 有八种以上的负载均衡算法
  • 性能大于等于 nginx
  • 支持动态管理,通过haproxy的sock进行通信,可以进行管理。
  • 有比较丰富的dashboard页面。
  • 有比较强大的七层功能。

haproxy实战

haproxy基础环境准备

实验环境

主机名 ip address 操作系统
linux-node1.example.com 192.168.56.11 centos7
linux-node2.example.com 192.168.56.12 centos7

安装EPEL及基础软件包

1
2
rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
yum install -y gcc glibc gcc-c++ make screen tree lrzsz

使用两个Apache的8080端口作为后端真实服务器

linux-node1.example.com

1
2
3
4
5
6
[root@linux-node1 ~]# yum install -y httpd
[root@linux-node1 ~]# sed -i 's/Listen 80/Listen 8080/g' /etc/httpd/conf/httpd.conf
[root@linux-node1 ~]# systemctl start httpd
[root@linux-node1 ~]# echo "linux-node1.example.com" > /var/www/html/index.html
[root@linux-node1 ~]# curl http://192.168.56.11:8080/
linux-node1.example.com

linux-node2.example.com

1
2
3
4
5
6
[root@linux-node2 ~]# yum install -y httpd
[root@linux-node2 ~]# sed -i 's/Listen 80/Listen 8080/g' /etc/httpd/conf/httpd.conf
[root@linux-node2 ~]# systemctl start httpd
[root@linux-node2 ~]# echo "linux-node2.example.com" > /var/www/html/index.html
[root@linux-node2 ~]# curl http://192.168.56.12:8080/
linux-node2.example.com

让本机服务器监听非本机的IP

1
2
3
vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
sysctl -p

Haproxy源码编译安装

1
2
3
4
5
6
7
8
9
10
[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 src]# make TARGET=linux2628 PREFIX=/usr/local/haproxy-1.6.3
[root@linux-node1 src]# make install
[root@linux-node1 ~]# cp /usr/local/sbin/haproxy /usr/sbin/
[root@linux-node1 ~]# haproxy -v
HA-Proxy version 1.6.3 2015/12/25
Copyright 2000-2015 Willy Tarreau <willy@haproxy.org>

Haproxy启动脚本

1
2
3
[root@linux-node1 ~]# 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

Haproxy配置文件

1
2
3
4
[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日志文件配置

haproxy默认使用系统的 local3.* 来存储日志

1
2
3
4
5
vim /etc/rsyslog.conf

local3.* /var/log/haproxy.log

systemctl restart rsyslog.service

haproxy配置文件解读

haproxy的配置文件分为五大块

  • global (全局)
  • defaults (默认)
  • listen (监听的配置)
  • frontend (前端)name vip
  • backend(后端)name server 列表

下面来分别讲解各个配置文件的定义

global (全局)

1
2
3
4
5
6
7
8
9
10
global ##定义这是全局配置
log 127.0.0.1 local3 info
###全局的日志配置,使用log关键字,指定使用127.0.0.1上的syslog服务中的local0日志设备,记录日志等级为info的日志。
chroot /var/lib/haproxy
##使用chroot的模式运行haproxy
user haproxy
group haproxy
##设置运行haproxy的用户和组,可以使用uid gid 关键字代替。
daemon
##以守护进程的方式运行

defaults (默认)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
defaults
##defaults模块标识
log global
##使用global中定义的日志
mode http
##mode 语法: mode{http|tcp|health} , http是七层模式,tcp是四层模式,health是检查检测。返回OK。
option httplog
##启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的,只记录“时间[jan 5 13:23:46] 日志服务器[127.0.0.1] 实例名以及PID [haproxy[25218]] 信息[proxy http 80 in stoped]” ,日志格式很简单。
option dontlognull
##启用该项,日志中将不会记录空连接,所谓空连接就是在上游的负载均衡器或者监听系统为l探测该服务是否存活可用时,需要定期的连接或者获取某一股东的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接。官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数。因为互联网上的恶意扫描或其他动作就不会被记录。

timeout connect 5000
##设置成功连接到一台服务器的最长等待时间。默认单位是毫秒,新颁布的haproxy使用timeout connect 代替。该参数向换兼容。
timeout client 50000
##设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒。
timeout server 50000
##设置服务器端回应客户端数据发送的最长等待时间,默认单位是毫秒

listen (监听页面的配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
listen stats
##定义页面监控的名称
mode http
##http的7层模式
bind 0.0.0.0:8888
##服务器监听端口
stats enable
##开启状态模块
stats uri /haproxy-status
##状态模块的URI
stats auth haproxy:haproxy
##状态模块登录的用户名和密码

frontend (前端)name vip

1
2
3
4
5
6
7
8
frontend http_front
#定义前端的名称
bind *:80
#服务器对外监听的端口,类似于lvs的vip端口
stats uri /haproxy?stats
#状态页面定义
default_backend http_back
#对应的后端服务名称

backend(后端)name server 列表

1
2
3
4
5
6
7
8
9
10
11
12
backend http_back
#后端服务的名称
balance roundrobin
#定义轮询算法,roundrobin 轮询,source 源IPhash,leastconn 最小连接数,这里只列举了常用的三个。

option forwardfor header X-REAL-IP
option httpchk HEAD / HTTP/1.0
##haproxy的健康检查,如果这两行被禁用,就是四次检测。
server web-node1 192.168.56.11:8080 check inter 2000 rise 30 fall 3
server web-node2 192.168.56.12:8080 check inter 2000 rise 30 fall 3
##后端真实ip配置,check 表示开启健康检查,inter 2000ms 每隔多长时间检查一次,rise 30 服务可用的连续次数,连续30次可用,在把你加进来,fall 3 失败三次 就把你踢出去。

完整的haproxy配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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 http_front
bind *:80
stats uri /haproxy?stats
default_backend http_back

backend http_back
balance roundrobin
option httpchk GET /index.html
option httpchk GET /
server linux-node1 192.168.56.11:8080 check
server linux-node2 192.168.56.12:8080 check

haproxy的ACL控制。

推荐生产上不要使用ACL访问控制。所有这里就没有研究。如果感兴趣的可以自行百度。

haproxy动态管理

方法一:

可以listen模式中开启stats admin if TRUE #开启页面管理 通过图形界面管理服务器上下线。

方法二:

使用socat 管理haproxy服务器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#在global开启socket
global
stats socket /var/run/haproxy.sock mode 600 level admin
stats timeout 2m
#安装socat管理软件
yum install socat
使用socat管理haproxy
socat /var/run/haproxy.sock stdio
基本用法:
echo "help"| socat stdio /var/run/haproxy.sock #socat常用命令
echo "show info "| socat stdio /var/run/haproxy.sock # 显示dashboad 的信息。
echo "show pools "| socat stdio /var/run/haproxy.sock #显示内部资源池的状态
echo "show stat "| socat stdio /var/run/haproxy.sock # 显示前后端服务器的状态

echo "set maxconn"| socat stdio /var/run/haproxy.sock #修改最大连接数
echo "disable server backend_www_example_com/web-node2 "| socat stdio /var/run/haproxy.sock # 关闭 web-node2 的服务器
echo "disable server backend_www_docker_nginx/docker-web2 "| socat stdio /var/run/haproxy.sock # 关闭 web-node2 的服务器
echo "enable server backend_www_docker_nginx/docker-web2 "| socat stdio /var/run/haproxy.sock # 开启 web-node2 的服务器