haproxy是个高性能的tcp和http的反向代理。它就是个代理。不像nginx还做web服务器
nginx的优点和缺点
1
2
3
4
5
6
7
8
9
10
11
|
优点: 1、web服务器,应用比较广泛,大家都会 2、可以作为7层负载均衡,location设置复杂的基于HTTP的负载均衡 3、性能强大,网络依赖小 4、安装配置简单 缺点: 1、健康检查单一,不支持基于url的健康检查(可以使用第三方插件实现) 2、负载均衡算法少 3、不能动态管理,比如踢出某个web节点,需要reload配置 4、没有集群upstream的状态页面 |
haproxy的优点和缺点
1
2
3
4
5
6
7
8
9
10
11
|
优点: 1、专门做反向代理负载均衡 2、负载均衡算法比较多,大于等于8种,比nginx丰富 3、性能不低于nginx,大于等于nginx 4、支持动态管理,通过和haproxy的sock进行通信,可以进行管理 5、有比较丰富的Dashboard的页面,监控方便。有管理页面 6、比较强大的7层反向代理功能,在7层方便,功能强大 7、会话保持比nginx丰富。可以基于cookie和源IP(nginx也能做到基于IP和cookie) 缺点: 配置没有Nginx简单(相对熟悉) |
先杀掉原先的nginx进程,防止80端口被占用,导致haproxy无法启动
1
2
3
4
|
[root@linux-node1 conf] # pkill nginx [root@linux-node1 conf] # ps aux | grep nginx root 27201 0.0 0.0 112664 972 pts /0 S+ 05:39 0:00 grep --colour=auto nginx [root@linux-node1 conf] # |
部署haproxy,这里是编译安装,版本是1.6.3,执行命令如下
1
2
3
4
5
6
7
8
|
cd /usr/local/src/ wget http: //www .haproxy.org /download/1 .6 /src/haproxy-1 .6.3. tar .gz tar xfz haproxy-1.6.3. tar .gz cd haproxy-1.6.3 make TARGET=linux2628 PREFIX= /usr/local/haproxy-1 .6.3 make install cp /usr/local/sbin/haproxy /usr/sbin/ haproxy - v |
1
2
3
4
5
|
[root@linux-node1 haproxy-1.6.3] # haproxy -v HA-Proxy version 1.6.3 2015 /12/25 Copyright 2000-2015 Willy Tarreau <willy@haproxy.org> [root@linux-node1 haproxy-1.6.3] # |
1
2
3
4
5
6
7
8
|
[root@linux-node1 haproxy-1.6.3] # pwd /usr/local/src/haproxy-1 .6.3 [root@linux-node1 haproxy-1.6.3] # cd examples/ [root@linux-node1 examples] # ls haproxy.init haproxy.init [root@linux-node1 examples] # cp haproxy.init /etc/init.d/haproxy [root@linux-node1 examples] # chmod +x /etc/init.d/haproxy [root@linux-node1 examples] # |
创建haproxy用户和相关目录
useradd -r表示创建系统账号
1
2
3
4
5
|
[root@linux-node1 examples] # useradd -r haproxy [root@linux-node1 examples] # [root@linux-node1 examples] # mkdir /etc/haproxy -p [root@linux-node1 examples] # mkdir /var/lib/haproxy -p [root@linux-node1 examples] # |
重启rsyslog
1
2
3
4
5
6
|
[root@linux-node1 ~] # vim /etc/rsyslog.conf [root@linux-node1 ~] # systemctl restart rsyslog [root@linux-node1 ~] # netstat -lnup | grep 514 udp 0 0 0.0.0.0:514 0.0.0.0:* 27509 /rsyslogd udp6 0 0 :::514 :::* 27509 /rsyslogd [root@linux-node1 ~] # |
关于mode http 你如果不写,默认继承defaults里面的
defaults默认不写好像也是http。
tcp的需要注明。
mode tcp
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
|
[root@linux-node1 ~] # cd /etc/haproxy/ [root@linux-node1 haproxy] # vim haproxy.cfg [root@linux-node1 haproxy] # cat haproxy.cfg global chroot /var/lib/haproxy daemon group haproxy user haproxy log 127.0.0.1:514 local3 info defaults log global #使用全局的日志配置 mode http option httplog option dontlognull #日志中不记录空连接,比如不记录健康检查的连接 timeout client 50000 timeout server 50000 timeout connect 5000 frontend http_front bind *:80 stats uri /haproxy ?stats default_backend http_back backend http_back balance roundrobin server linux-node1 10.0.1.105:8080 check server linux-node2 10.0.1.106:8080 check [root@linux-node1 haproxy] # |
启动haproxy
1
2
3
4
5
6
7
8
|
[root@linux-node1 ~] # /etc/init.d/haproxy start Reloading systemd: [ 确定 ] Starting haproxy (via systemctl): [ 确定 ] [root@linux-node1 ~] # [root@linux-node1 ~] # netstat -lntp | grep 80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 27556 /haproxy tcp6 0 0 :::8080 :::* LISTEN 20130 /httpd [root@linux-node1 ~] # |
1
2
3
4
5
|
[root@linux-node1 ~] # grep local3 /etc/rsyslog.conf local3.* /var/log/haproxy .log [root@linux-node1 ~] # [root@linux-node1 ~] # systemctl restart rsyslog [root@linux-node1 ~] # |
再次重启haproxy服务,就可以看到haproxy的日志文件生成了。可以看到启动过程
1
2
3
4
5
6
7
8
9
|
[root@linux-node1 ~] # /etc/init.d/haproxy restart Restarting haproxy (via systemctl): [ 确定 ] [root@linux-node1 ~] # tail -f /var/log/haproxy.log Feb 27 06:33:43 localhost haproxy[27648]: Stopping frontend http_front in 0 ms. Feb 27 06:33:43 localhost haproxy[27648]: Stopping backend http_back in 0 ms. Feb 27 06:33:43 localhost haproxy[27648]: Proxy http_front stopped (FE: 0 conns, BE: 0 conns). Feb 27 06:33:43 localhost haproxy[27648]: Proxy http_back stopped (FE: 0 conns, BE: 0 conns). Feb 27 06:33:43 localhost haproxy[27687]: Proxy http_front started. Feb 27 06:33:43 localhost haproxy[27687]: Proxy http_back started. |
继续优化更改下配置
haproxy可以自定义健康检查的url,这是nginx不具备的
check:启用健康检测
inter:健康检测间隔
rise:检测服务可用的连续次数
fall:检测服务不可用的连续次数
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
29
|
[root@linux-node1 ~] # cd /etc/haproxy/ [root@linux-node1 haproxy] # vim haproxy.cfg [root@linux-node1 haproxy] # cat haproxy.cfg global chroot /var/lib/haproxy daemon group haproxy user haproxy log 127.0.0.1:514 local3 info defaults log global mode http option httplog option dontlognull timeout client 50000 timeout server 50000 timeout connect 5000 frontend http_front mode http bind *:80 stats uri /haproxy ?stats default_backend http_back backend http_back balance roundrobin server linux-node1 10.0.1.105:8080 check inter 2000 rise 3 fall 3 weight 1 server linux-node2 10.0.1.106:8080 check inter 2000 rise 3 fall 3 weight 1 [root@linux-node1 haproxy] # |
重启服务
1
2
3
4
5
6
|
[root@linux-node1 haproxy] # /etc/init.d/haproxy restart Restarting haproxy (via systemctl): [ 确定 ] [root@linux-node1 haproxy] # netstat -lntp | grep 80 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 27849 /haproxy tcp6 0 0 :::8080 :::* LISTEN 20130 /httpd [root@linux-node1 haproxy] # |
页面测试,目前也是轮询的
多访问几次,健康页面有新的数据变化
sessions这里可以看到有没有失败的访问
结合haproxy的acl配置反向代理功能,先备份原先配置文件
设置acl
这样能支持多个域名,让不同的域名,访问不同的backend上面去
1
2
|
[root@linux-node1 conf] # cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.ori [root@linux-node1 conf] # vim /etc/haproxy/haproxy.cfg |
修改配置文件为如下
注意,配置文件中,前端和后端不要用特殊符号以及点。它对这些敏感。推荐使用下划线
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
29
30
31
32
33
34
35
36
37
|
[root@linux-node1 conf] # vim /etc/haproxy/haproxy.cfg [root@linux-node1 conf] # cat /etc/haproxy/haproxy.cfg global chroot /var/lib/haproxy daemon group haproxy user haproxy log 127.0.0.1:514 local3 info stats socket /var/lib/haproxy/haproxy .sock mode 600 level admin stats timeout 2m defaults log global mode http option httplog option dontlognull timeout client 50000 timeout server 50000 timeout connect 5000 frontend www_nmap_com mode http bind *:80 stats uri /haproxy ?stats default_backend www_nmap_com_backend acl is_other_nmap_com hdr_end(host) other.nmap-blog.com use_backend other_nmap_com_backend if is_other_nmap_com backend www_nmap_com_backend option forwardfor header X-REAL-IP option httpchk GET /index .html balance roundrobin server linux-node1 10.0.1.105:8080 check inter 2000 rise 3 fall 3 weight 1 backend other_nmap_com_backend option forwardfor header X-REAL-IP option httpchk GET /index .html balance roundrobin server linux-node2 10.0.1.106:8080 check inter 2000 rise 3 fall 3 weight 1 [root@linux-node1 conf] # |
重启haproxy
1
2
|
[root@linux-node1 conf] # /etc/init.d/haproxy restart Restarting haproxy (via systemctl): [ 确定 ] |
windows客户端配置host文件
1
|
10.0.1.105 www.nmap-blog.com other.nmap-blog.com |
这样也实现了haproxy的多域名反向代理
haproxy的acl,也可以根据正则,和后缀设置,下面2种方法。推荐第一种,正则方式匹配
1
2
|
acl is_static_reg url_reg /*.(css|jpg|png|js|jpeg|gif)$ acl is_static_path path_end .gif .png .js |
修改配置文件做基于正则的acl
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
29
30
31
32
33
34
35
36
37
38
39
40
41
|
[root@linux-node1 conf] # cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.2 [root@linux-node1 conf] # vim /etc/haproxy/haproxy.cfg [root@linux-node1 conf] # cat /etc/haproxy/haproxy.cfg global chroot /var/lib/haproxy daemon group haproxy user haproxy log 127.0.0.1:514 local3 info stats socket /var/lib/haproxy/haproxy .sock mode 600 level admin stats timeout 2m defaults log global mode http option httplog option dontlognull timeout client 50000 timeout server 50000 timeout connect 5000 frontend www_nmap_com mode http bind *:80 stats uri /haproxy ?stats default_backend www_nmap_com_backend acl is_static_reg url_reg /*.(css|jpg|png|js|jpeg|gif)$ use_backend other_nmap_com_backend if is_static_reg #acl is_static_path path_end .gif .png .js #acl is_other_nmap_com hdr_end(host) other.nmap-blog.com #use_backend other_nmap_com_backend if is_other_nmap_com backend www_nmap_com_backend option forwardfor header X-REAL-IP option httpchk GET /index .html balance roundrobin server linux-node1 10.0.1.105:8080 check inter 2000 rise 3 fall 3 weight 1 backend other_nmap_com_backend option forwardfor header X-REAL-IP option httpchk GET /index .html balance roundrobin server linux-node2 10.0.1.106:8080 check inter 2000 rise 3 fall 3 weight 1 [root@linux-node1 conf] # |
重启服务
1
2
3
4
5
6
|
[root@linux-node1 conf] # /etc/init.d/haproxy restart Restarting haproxy (via systemctl): [ 确定 ] [root@linux-node1 conf] # lsof -i:80 COMMAND PID USER FD TYPE DEVICE SIZE /OFF NODE NAME haproxy 48521 haproxy 5u IPv4 1371377 0t0 TCP *:http (LISTEN) [root@linux-node1 conf] # |
因为匹配后会连接到node2,这里就在node2上设置一个js文件,node1不做任何设置。
1
2
|
[root@linux-node2 ~] # echo ‘test111‘ >/var/www/html/test.js [root@linux-node2 ~] # |
测试成功
关于后端web节点记录检查日志的问题,因为我设置检查check inter 2000 ,也就是2秒发一次检查包。后端节点日志这里也能看到
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[root@linux-node2 ~] # tail -f /var/log/httpd/access_log 10.0.1.105 - - [04 /Mar/2017 :00:35:46 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:35:48 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:35:50 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:35:52 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:35:54 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:35:56 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:35:58 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:36:00 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:36:02 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:36:04 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:36:06 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" 10.0.1.105 - - [04 /Mar/2017 :00:36:08 +0800] "GET /index.html HTTP/1.0" 200 24 "-" "-" |
关于怎么让后端apache不记录健康检查日志,以及如何记录真正的客户端IP,这里不做实验。