haproxy学习
frontend webserver *:80 前端监听在80端口,前端名称为webserver
default_backend web
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend web 后端服务器名称web
balance roundrobin
server web1 192.168.223.137:80 check
server web2 192.168.223.146:80 check
当访问浏览器:http://192.168.223.136/,会根据roundrobin算法调度到后端服务器
配置haproxy日志:
1、将下面四行注释掉
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
2、添加如下一行
local2.* /var/log/haproxy.log
3、重启rsyslog服务:service rsyslog restart
当请求访问haproxy时,日志内容如下:
[root@node1 ~]# tail -f /var/log/haproxy.log
Aug 5 21:55:42 localhost haproxy[66553]: 192.168.223.1:56443 [05/Aug/2017:21:55:41.900] webserver web/web2 168/0/0/0/168 200 297 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"
Aug 5 21:55:42 localhost haproxy[66553]: 192.168.223.1:56443 [05/Aug/2017:21:55:42.068] webserver web/web1 158/0/0/1/159 200 260 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
可以看出实际的客户端地址192.168.223.1,以及请求的前端服务器名称,后端服务器的信息
查看后端服务器信息:(后端由一个nginx,一个httpd提供服务)
nginx日志:
[root@wadeson html]# tail -f ../logs/access.log
192.168.223.136 "-" - - [05/Aug/2017:21:55:39 +0800] "GET / HTTP/1.1" "192.168.223.136" 200 30 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" "192.168.223.1"
192.168.223.136 "-" - - [05/Aug/2017:21:55:40 +0800] "GET / HTTP/1.1" "192.168.223.136" 200 30 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" "192.168.223.1"
而httpd日志:
[root@wadeson ~]# tail -f /var/log/httpd/access_log
192.168.223.136 - - [05/Aug/2017:21:55:38 +0800] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
看不见真实客户端的ip,如何获取真实ip呢?
在haproxy配置文件中默认定义了:option forwardfor except 127.0.0.0/8
这个参数的含义:允许在发往服务器的请求首部中插入“X-Forwarded-For”,是haproxy请求发往后端服务器的过程,只需要在后端服务器的日志格式中添加这个首部就能获取到真实ip的值
nginx的日志格式:
log_format main '$remote_addr "$http_x_real_ip" - $remote_user [$time_local] "$request" "$http_host" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; 已经默认自带了这个首部,所以无需修改就可以看见
现在设置httpd的日志格式:
LogFormat "%h %{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog logs/access_log combined
在httpd的日志格式中添加该首部,然后调用格式名称,再次访问网站,刷新日志如下:
192.168.223.136 - - [05/Aug/2017:21:55:43 +0800] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.223.136 192.168.223.1 - - [05/Aug/2017:22:23:02 +0800] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
至此,nginx和httpd两个后端都能收到真实的客户端的ip
haproxy的算法:
backend web
balance source
hash-type consistent
server web1 192.168.223.137:80 check
server web2 192.168.223.146:80 check
查看haproxy日志:
Aug 5 22:32:25 localhost haproxy[66820]: Proxy webserver started.
Aug 5 22:32:25 localhost haproxy[66820]: Proxy web started.
Aug 5 22:32:31 localhost haproxy[66821]: 192.168.223.1:57002 [05/Aug/2017:22:32:31.349] webserver web/web2 1/0/0/1/2 200 297 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"
Aug 5 22:32:31 localhost haproxy[66821]: 192.168.223.1:57002 [05/Aug/2017:22:32:31.351] webserver web/web2 198/0/0/1/199 304 149 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"
Aug 5 22:32:31 localhost haproxy[66821]: 192.168.223.1:57002 [05/Aug/2017:22:32:31.551] webserver web/web2 183/0/1/1/185 304 149 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"
可以看出请求都被发往web2这台后端服务器了
2、uri的hash算法:
现在将两台web服务器都增加一个test.html文件:
echo "<h1>test 192.168.223.137</h1>" > test.html
echo "<h1>test 192.168.223.146</h1>" > test.html
修改haproxy配置文件:
backend web
balance uri
hash-type consistent
server web1 192.168.223.137:80 check
server web2 192.168.223.146:80 check
访问网站:http://192.168.223.136/test.html
查看haproxy日志:
Aug 5 22:36:44 localhost haproxy[66860]: Proxy webserver started.
Aug 5 22:36:44 localhost haproxy[66860]: Proxy web started.
Aug 5 22:36:55 localhost haproxy[66861]: 192.168.223.1:57065 [05/Aug/2017:22:36:55.365] webserver web/web1 0/0/0/0/0 200 260 - - ---- 1/1/0/0/0 0/0 "GET /test.html HTTP/1.1"
Aug 5 22:36:57 localhost haproxy[66861]: 192.168.223.1:57065 [05/Aug/2017:22:36:55.366] webserver web/web1 1903/0/0/1/1904 304 173 - - ---- 1/1/0/0/0 0/0 "GET /test.html HTTP/1.1"
可以看出请求test.html的uri都被请求到web1这台服务器了
3、hdr(name),基于header内容的hash算法
修改haproxy配置文件:
backend web
balance hdr(User-Agent)
hash-type consistent
server web1 192.168.223.137:80 check
server web2 192.168.223.146:80 check
查看haproxy日志:
Aug 5 22:43:00 localhost haproxy[66910]: Proxy webserver started.
Aug 5 22:43:00 localhost haproxy[66910]: Proxy web started.
Aug 5 22:43:15 localhost haproxy[66911]: 192.168.223.1:57124 [05/Aug/2017:22:43:15.826] webserver web/web2 0/0/0/1/1 304 149 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"
Aug 5 22:43:17 localhost haproxy[66911]: 192.168.223.1:57124 [05/Aug/2017:22:43:15.827] webserver web/web2 1916/0/0/0/1916 304 149 - - ---- 1/1/0/1/0 0/0 "GET / HTTP/1.1"
请求都被派发到了web2,而web2的日志如下:
192.168.223.136 192.168.223.1 - - [05/Aug/2017:22:43:22 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.223.136 192.168.223.1 - - [05/Aug/2017:22:43:22 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
配置文件说明:
1、代理
-defaults:用于为所有其他配置提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定
-frontend:用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接
-backend:用于定义一系列后端服务器,代理将会将对应客户端的请求转发至这些服务器
-listen:把一个前端和一个后端绑在一起,通过关联前端和后端定义了一个完整的代理,通常只对tcp流量有用
所有代理的名称只能使用大写字母、小写字母、数字、-、_、点号、冒号,此外ACL名称会区分字母大小写
bind [<address>]:<port_range> [, ...] [param*]
在前端定义一个或多个地址或者端口
mode { tcp|http|health }
实例运行的模式或者协议
use_backend dynamic if url_dyn
use_backend static if url_css url_img extension_img
default_backend dynamic
cookie SRV insert indirect nocache
backend web
balance roundrobin
cookie SRV insert indirect nocache 在原有的cookie信息上insert上SRV:{web1_session|web2_session},实现cookie的绑定
server web1 192.168.223.137:80 check cookie web1_session
server web2 192.168.223.146:80 check cookie web2_session
Aug 5 23:38:17 localhost haproxy[67250]: Proxy webserver started.
Aug 5 23:38:17 localhost haproxy[67250]: Proxy web started.
Aug 5 23:38:22 localhost haproxy[67251]: 192.168.223.1:58602 [05/Aug/2017:23:38:22.923] webserver web/web1 0/0/1/0/1 200 260 - - --NI 1/1/0/0/0 0/0 "GET / HTTP/1.1"
Aug 5 23:38:23 localhost haproxy[67251]: 192.168.223.1:58602 [05/Aug/2017:23:38:22.924] webserver web/web1 558/0/1/0/559 304 173 - - --VN 1/1/0/1/0 0/0 "GET / HTTP/1.1"
![](https://images2017.cnblogs.com/blog/1168897/201708/1168897-20170806132549928-2123052686.png)
Aug 6 13:25:55 localhost haproxy[67660]: 192.168.223.1:53986 [06/Aug/2017:13:25:50.539] base_stats base_stats/<STATS> 5014/0/0/0/5015 200 18268 - - LR-- 1/1/0/0/0 0/0 "GET /haproxy?stats HTTP/1.1"
Aug 6 13:25:55 localhost haproxy[67660]: 192.168.223.1:54110 [06/Aug/2017:13:25:55.577] base_stats base_stats/<NOSRV> 0/-1/-1/-1/0 503 212 - - SC-- 1/1/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"
日志显示也是五秒刷新一条记录
如果要做到在该页面进行后端服务器的操作,那么可以加上stats admin if true这条指令:
frontend webserver *:80
default_backend web
listen base_stats
bind *:8090
stats enable
stats hide-version
stats uri /haproxy?stats
stats realm "haproxy statistics"
stats auth wadeson:redhat
stats admin if TRUE 如果认证通过就能管理节点server
capture request header <name> len <length>
捕获请求首部,并指定首部长度
frontend webserver *:80
default_backend web
capture request header Host len 15
capture request header Referer len 60 ----》跳转---》防盗链
查看haproxy日志:
Aug 6 13:32:11 localhost haproxy[67789]: Proxy web started.
Aug 6 13:32:21 localhost haproxy[67790]: 192.168.223.1:54212 [06/Aug/2017:13:32:21.201] webserver web/web1 0/0/0/0/0 304 173 - - --VN 1/1/0/0/0 0/0 {192.168.223.136} "GET / HTTP/1.1"
Aug 6 13:32:21 localhost haproxy[67790]: 192.168.223.1:54212 [06/Aug/2017:13:32:21.201] webserver web/web1 694/0/1/0/695 304 173 - - --VN 1/1/0/0/0 0/0 {192.168.223.136} "GET / HTTP/1.1"
可以看出标红的就是捕获的请求首部host的具体内容,捕获的内容出现在日志以{}出现
capture response header <name> len <length>
捕获响应首部,并指定长度
frontend webserver *:80
default_backend web
capture request header Host len 15
capture request header X-Forwarded-For len 15
capture response header Content-length len 9
capture response header Location len 15
Aug 6 13:43:58 localhost haproxy[67911]: 192.168.223.1:54419 [06/Aug/2017:13:43:58.989] webserver web/web1 1/0/0/1/2 304 173 - - --VN 1/1/0/0/0 0/0 {192.168.223.136|} {|} "GET / HTTP/1.1"
Aug 6 13:43:59 localhost haproxy[67911]: 192.168.223.1:54419 [06/Aug/2017:13:43:58.991] webserver web/web1 782/0/0/0/782 304 173 - - --VN 1/1/0/0/0 0/0 {192.168.223.136|} {|} "GET / HTTP/1.1"
响应捕获的首部{}不存在使用|为分隔符出现在日志中
option httplog [ clf ]
启用该参数,能够看见在日志中记录更多内容,当然你也可以设置log-format,支持更多内置变量,该参数默认是开启的
更早的记录请求到日志中
option dontlognull
启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该 服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听 或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来
全局配置段的一些参数:
nbproc <number>:只有运行在守护模式下才能创建更多进程数,因为一个进程所处理的文件描述符的数量有限,haproxy也能工作在多进程条件下
ulimit-n <number>:设置一个进程所能处理的最大的文件描述符的数量,it is automatically computed, so it is recommended not to use this option.,不建议更改
maxconn <number>:
[root@node1 haproxy]# haproxy -v
HA-Proxy version 1.5.18 2016/05/10
Copyright 2000-2016 Willy Tarreau <willy@haproxy.org
Build options :
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -O2 -g -fno-strict-aliasing
OPTIONS = USE_LINUX_TPROXY=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_PCRE=1
Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200
Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.3
Compression algorithms supported : identity, deflate, gzip
Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 7.8 2008-09-05
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
ACL:访问控制列表 acl <aclname> <criterrion> [flags][operator]<value>区分字符大小写 flags: -i:不区分字符大小 path_beg <string>:path路径以某字符串开始 path_end <string>:path路径以什么结尾(文件名扩展名都可以) path_reg <regex>:支持正则 url <string>:整个后面的路径 method <string> acl url_static path_beg /static /images /img /css:定义以/images /img /css为开头的url acl url_static path_end -i .gif .png .jpg .css .js:定义以它们结尾,不区分大小写 acl host_www hdr_beg(host) -i www :hdr_reg(header) <regex>:对首部host进行正则表达式 use_backend static if url_static :如果满足url_static控制列表定义的使用后端static组 use_backend www if host_www :如果满足host_www控制列表定义的使用后端www组 default_backend web :其他没有满足的使用web后端组
实例:动静分离
frontend webserver *:80
default_backend web
capture request header Host len 15
capture request header X-Forwarded-For len 15
capture response header Content-length len 9
capture response header Location len 15
capture response header Via len 15
acl url_static path_beg -i /static /images /javascript /stylesheets /css 以path的url开头为条件
acl url_static path_end -i .jpg .jpeg .gif .png .css .js .html .htm 以结尾为条件
use_backend static_servers if url_static 当满足url_static定义的条件时就使用静态服务器
default_backend dynamic_servers 默认使用动态服务器
listen base_stats
bind *:8090
stats enable
stats hide-version
stats uri /haproxy?stats
stats realm "haproxy statistics"
stats auth wadeson:redhat
stats admin if TRUE
backend static_servers
balance roundrobin
server web2 192.168.223.146:80 check maxconn 6000
backend dynamic_servers
balance roundrobin
cookie SRV insert indirect nocache
参考另一篇:
http://huangsir007.blog.51cto.com/6159353/1840877
http://blog.csdn.net/wylfengyujiancheng/article/details/52336854