反向代理负载均衡之haproxy

一、集群

详情请移步本人另一篇博客反向代理负载均衡之nginx

二、反向代理负载均衡

详情请移步本人另一篇博客反向代理负载均衡之apache

三、使用haproxy实现反向代理负载均衡实战

3.1 环境准备:两台虚拟机

第一台

  1. [root@linux-node1 ~]# uname -m
  2. x86_64
  3. [root@linux-node1 ~]# uname -r
  4. 3.10.0-229.el7.x86_64
  5. [root@linux-node1 ~]# cat /etc/hostname
  6. linux-node1.example.com
  7. [root@linux-node1 ~]# cat /etc/hosts
  8. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
  9. ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
  10. 192.168.56.11 linux-node1.example.com
  11. 192.168.56.12 linux-node2.example.com
  12. [root@linux-node1 ~]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
  13. [root@linux-node1 ~]# yum install -y gcc glibc gcc-c++ make screen tree lrzsz

第二台

  1. [root@linux-node2 ~]# uname -m
  2. x86_64
  3. [root@linux-node2 ~]# uname -r
  4. 3.10.0-229.el7.x86_64
  5. [root@linux-node2 ~]# cat /etc/hostname
  6. linux-node2.example.com
  7. [root@linux-node2 ~]# cat /etc/hosts
  8. 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
  9. ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
  10. 192.168.56.11 linux-node1.example.com
  11. 192.168.56.12 linux-node2.example.com
  12. [root@linux-node2 ~]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
  13. [root@linux-node2 ~]# yum install -y gcc glibc gcc-c++ make screen tree lrzsz

3.2 部署应用实战

在两台机器部署apache作为RS
linux-node1.example.com

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

linux-node2.example.com

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

在linux-node1上编译安装haproxy作为反向代理服务器

  1. [root@linux-node1 ~]# cd /usr/local/src
  2. [root@linux-node1 src]# wget http://www.haproxy.org/download/1.6/src/haproxy-1.6.3.tar.gz
  3. [root@linux-node1 src]# tar zxf haproxy-1.6.3.tar.gz
  4. [root@linux-node1 src]# cd haproxy-1.6.3
  5. [root@linux-node1 src]# make TARGET=linux2628 PREFIX=/usr/local/haproxy-1.6.3
  6. [root@linux-node1 src]# make install
  7. [root@linux-node1 ~]# cp /usr/local/sbin/haproxy /usr/sbin/
  8. [root@linux-node1 ~]# haproxy -v
  9. HA-Proxy version 1.6.3 2015/12/25
  10. Copyright 2000-2015 Willy Tarreau <willy@haproxy.org>

编辑Haproxy启动脚本

  1. [root@linux-node1 ~]# cd /usr/local/src/haproxy-1.6.3
  2. [root@linux-node1 haproxy-1.6.3]# cp examples/haproxy.init /etc/init.d/haproxy
  3. [root@linux-node1 haproxy-1.6.3]# chmod 755 /etc/init.d/haproxy

针对配置文件的路径创建以下文件

  1. [root@linux-node1 ~]# useradd -r haproxy
  2. [root@linux-node1 ~]# mkdir /etc/haproxy
  3. [root@linux-node1 ~]# mkdir /var/lib/haproxy
  4. [root@linux-node1 ~]# mkdir /var/run/haproxy

编辑haproxy配置文件,配置log,并启动

  1. [root@linux-node1 haproxy]# cat haproxy.cfg
  2. global #全局配置,在所有配置段中都生效
  3. log 127.0.0.1 local3 info #记录日志
  4. chroot /var/lib/haproxy
  5. user haproxy
  6. group haproxy
  7. daemon
  8. defaults #默认配置,可以被前端和后端继承
  9. log global #使用global的log设置
  10. mode http #使用http模式,也可以使用tcp模式
  11. option httplog #启动http请求的log
  12. option dontlognull #在日志中不记录空连接(空连接:健康检查的链接)
  13. timeout connect 5000 #长连接超时时间
  14. timeout client 50000 #客户端连接超时
  15. timeout server 50000 #RS连接超时
  16. frontend www_chuck-blog_com #前端配置 + 一个配置段的名字(最好不要乱写,和项目直接相关最佳)
  17. mode http #使用http模式,也可以使用tcp模式
  18. bind *:80 #监听80端口
  19. stats uri /haproxy?stats #状态页面dashboard
  20. default_backend www_chuck-blog_com_backend #对应的backend名称
  21. backend www_chuck-blog_com_backend #对应的frontend的default_backend
  22. #source cookie SERVERID
  23. option httpchk GET /index.html #检测url
  24. balance roundrobin #使用rr负载均衡方式
  25. server linux-node1 192.168.56.11:8080 check inter 2000 rise 3 fall 3 weight 5
  26. server linux-node2 192.168.56.12:8080 check inter 2000 rise 3 fall 3 weight 1 #RS健康检测时间间隔2秒,重试三次,失败三次不可用,权重1
  27. [root@linux-node1 haproxy]# vim /etc/rsyslog.conf
  28. 15 $ModLoad imudp #打开注释
  29. 16 $UDPServerRun 514 #打开注释
  30. 74 local3.* /var/log/haproxy.log #local3的路径
  31. [root@linux-node1 haproxy]# /etc/init.d/haproxy start
  32. Starting haproxy (via systemctl): [ OK ]
  33. [root@linux-node1 haproxy]# systemctl restart rsyslog.service
  34. [root@linux-node1 haproxy]# ll /var/log/haproxy.log
  35. -rw-r--r-- 1 root root 482 Mar 5 19:18 /var/log/haproxy.log

打开浏览器可以查看haproxy状态



更改配置文件的检查url,对url检查页面进行测试

  1. [root@linux-node1 haproxy]# sed -i 's/index\.html/chuck-blog.html/g' haproxy.cfg
  2. [root@linux-node1 haproxy]# /etc/init.d/haproxy restart
  3. Restarting haproxy (via systemctl): [ OK ]

可以看到状态已经改变,出现DOWN

下面是检测url和uri的几种方式

  1. option httpchk
  2. option httpchk <uri>
  3. option httpchk <method> <uri>
  4. option httpchk <method> <uri> <version>

更改配置文件获取客户端的真实ip
在banckend配置段加入一个option

  1. option forwardfor header X-REAL-IP #X-REAL-IP是自定义的一个名称

通过acl设置虚拟主机,一个前端可以对应多个后端,而实际生产环境建议一个frontend对应一个backend,并重载(生产不建议restart,restart会断开现有链接)

  1. [root@linux-node1 haproxy]# cat haproxy.cfg
  2. global
  3. log 127.0.0.1 local3 info
  4. chroot /var/lib/haproxy
  5. user haproxy
  6. group haproxy
  7. daemon
  8. defaults
  9. log global
  10. mode http
  11. option httplog
  12. option dontlognull
  13. timeout connect 5000
  14. timeout client 50000
  15. timeout server 50000
  16. frontend www_chuck-blog_com
  17. mode http
  18. bind *:80
  19. stats uri /haproxy?stats
  20. default_backend www_chuck-blog_com_backend #默认的backend
  21. acl is_other_chuck-blog_com hdr_end(host) #is_other_chuck-blog_com:给此acl起一个名字;hdr(host):固定格式,用来识别host,如果没有匹配到acl,即访问default的bankcend
  22. other.chuck-blog.com
  23. use_backend other_chuck-blog_com_backend if is_other_chuck-blog_com #use_backend:关键词,使用哪个banckend;other_chuck-blog_com_backend:指定哪个backend的名称;if is_other_chuck-blog_com:用来判断acl
  24. backend www_chuck-blog_com_backend
  25. #source cookie SERVERID
  26. option forwardfor header X-REAL-IP
  27. option httpchk GET /index.html
  28. balance roundrobin
  29. server linux-node1 192.168.56.11:8080 check inter 2000 rise 3 fall 3 weight 1
  30. backend other_chuck-blog_com_backend
  31. #source cookie SERVERID
  32. option forwardfor header X-REAL-IP
  33. option httpchk GET /index.html
  34. balance roundrobin
  35. server linux-node2 192.168.56.12:8080 check inter 2000 rise 3 fall 3 weight 1
  36. [root@linux-node1 haproxy]# /etc/init.d/haproxy reload
  37. Reloading haproxy configuration (via systemctl): [ OK ]

在本地电脑使用host解析(过后要清理掉哦,否则无法访问我的博客了,嘎嘎)

  1. 192.168.56.11 www.chuck-blog.com
  2. 192.168.56.12 other.chuck-blog.com

通过浏览器访问不同的域名


在fortend添加acl,根据静态文件,设置不同的backend(类似于location),注释的两行和前两行意义相同,分别是通过url正则匹配和url的后缀匹配

  1. acl is_static_reg url_reg /*.(css|jpg|png|js|jpeg|gif)$
  2. use_backend other_chuck-blog_com_backend if is_static_reg
  3. #acl is_static_path path_end .gif .png .css .jpg .jpeg
  4. #use_backend other_chuck-blog_com_backend if is_static_path
  5. [root@linux-node2 ~]# echo "This is a static test page " >/var/www/html/abc.jss
  6. [root@linux-node1 ~]# /etc/init.d/haproxy reload
  7. Reloading haproxy configuration (via systemctl): [ OK ]

打开浏览器到如下内容证明已生效

其他形式的acl,正则或者UA(可以理解为nginx的location),更多形式的acl,请移步:github

  1. acl is_do_path url_reg /chuck.do
  2. use_backend other_chuck-blog_com_backend if is_do_path
  3. acl is_UA_path hdr_reg(User-Agent) -i andriod
  4. use_backend other_chuck-blog_com_backend if is_UA_path

四、haproxy的动态维护

在配置文件添加socket

  1. [root@linux-node1 ~]# head -8 /etc/haproxy/haproxy.cfg
  2. global
  3. log 127.0.0.1 local3 info
  4. chroot /var/lib/haproxy
  5. user haproxy
  6. group haproxy
  7. daemon
  8. stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin #指定socket文件路径,权限,管理级别
  9. stats timeout 2m #指定超时时间

安装socat

  1. [root@linux-node1 ~]yum install -y socat

使用help查看socat的事情

  1. [root@linux-node1 ~]# echo "help" |socat stdio /var/lib/haproxy/haproxy.sock
  2. Unknown command. Please enter one of the following commands only :
  3. clear counters : clear max statistics counters (add 'all' for all counters)
  4. clear table : remove an entry from a table
  5. help : this message
  6. prompt : toggle interactive mode with prompt
  7. quit : disconnect
  8. show backend : list backends in the current running config
  9. show info : report information about the running process #查看所有信息
  10. show pools : report information about the memory pools usage #查看所有poll
  11. show stat : report counters for each proxy and server #显示状态
  12. show errors : report last request and response errors for each proxy
  13. show sess [id] : report the list of current sessions or dump this session
  14. show table [id]: report table usage stats or dump this table's contents
  15. show servers state [id]: dump volatile server information (for backend <id>)
  16. get weight : report a server's current weight #获得权重信息
  17. set weight : change a server's weight #设置权重
  18. set server : change a server's state, weight or address #改变一个server的转态权重或地址
  19. set table [id] : update or create a table entry's data
  20. set timeout : change a timeout setting
  21. set maxconn : change a maxconn sett
  22. ing
  23. set rate-limit : change a rate limiting value
  24. disable : put a server or frontend in maintenance mode #将一个server或者fortend置于维护模式
  25. enable : re-enable a server or frontend which is in maintenance mode #启用一个维护状态的server或者frontend
  26. shutdown : kill a session or a frontend (eg:to release listening ports)
  27. show acl [id] : report avalaible acls or dump an acl's contents
  28. get acl : reports the patterns matching a sample for an ACL #获取acl
  29. add acl : add acl entry #加一个acl
  30. del acl : delete acl entry #删一个acl
  31. clear acl <id> : clear the content of this acl
  32. show map [id] : report avalaible maps or dump a map's contents
  33. get map : reports the keys and values matching a sample for a map
  34. set map : modify map entry
  35. add map : add map entry
  36. del map : delete map entry
  37. clear map <id> : clear the content of this map
  38. set ssl <stmt> : set statement for ssl

查看info信息,内容值可以利用来监控

  1. [root@linux-node1 ~]# echo "show info" |socat stdio /var/lib/haproxy/haproxy.sock
  2. Name: HAProxy
  3. Version: 1.6.3
  4. Release_date: 2015/12/25
  5. Nbproc: 1
  6. Process_num: 1
  7. Pid: 56054
  8. Uptime: 0d 0h12m08s
  9. Uptime_sec: 728
  10. Memmax_MB: 0
  11. Ulimit-n: 4033
  12. Maxsock: 4033
  13. Maxconn: 2000
  14. Hard_maxconn: 2000
  15. CurrConns: 0
  16. CumConns: 2
  17. CumReq: 2
  18. Maxpipes: 0
  19. PipesUsed: 0
  20. PipesFree: 0
  21. ConnRate: 0
  22. ConnRateLimit: 0
  23. MaxConnRate: 0
  24. SessRate: 0
  25. SessRateLimit: 0
  26. MaxSessRate: 0
  27. CompressBpsIn: 0
  28. CompressBpsOut: 0
  29. CompressBpsRateLim: 0
  30. Tasks: 8
  31. Run_queue: 1
  32. Idle_pct: 100
  33. node: linux-node1.example.com
  34. description:

关闭linux-node2主机

  1. [root@linux-node1 ~]# echo "disable server other_chuck-blog_com_backend/linux-node2" |socat stdio /var/lib/haproxy/haproxy.sock
  2. Message from syslogd@localhost at Mar 6 01:11:58 ...
  3. haproxy[56054]: backend other_chuck-blog_com_backend has no server available!

可以看到linux-node2进入了维护(maintain)状态

打开linux-node2主机(只对现有的server生效,不能用来新增节点)

  1. [root@linux-node1 ~]# echo "enable server other_chuck-blog_com_backend/linux-node2" |socat stdio /var/lib/haproxy/haproxy.sock

可以看到linux-node2恢复正常

五、生产环境遇到的问题

haproxy的本地端口可能用尽,解决方案如下4条
1)更改local的端口范围,调整内核参数

  1. [root@linux-node1 ~]# cat /proc/sys/net/ipv4/ip_local_port_range
  2. 32768 61000

2)调整timewait的端口复用,设置为1

  1. [root@linux-node1 ~]# cat /proc/sys/net/ipv4/tcp_tw_reuse
  2. 0

3)缩短tcp_wait的时间,并不建议修改

  1. [root@linux-node1 ~]# cat /proc/sys/net/ipv4/tcp_fin_timeout
  2. 60
  3. 4)终极方案:增加为多个ip,自然端口数就够了

六、haproxy对比nginx

nginx

  • 优点
    1.web服务器,应用比较广泛
    2.7层负载均衡,location设置复杂的基于HTTP的负载均衡
    3.性能强大,网络依赖小
    4.安装配置简单
  • 缺点
    1.健康检查单一
    2.负载均衡算法少
    3.不能动态管理
    4.没有集群upstream的状态页面
    haproxy
  • 优点
    1.专门做负载均衡
    2.负载均衡算法多
    3.性能》=nginx
    4.通过和socket通信进行动态管理
    5.有比较丰富的dashboard页面
    6.强大的7层代理
  • 缺点
    1.配置没有nginx简单
    2.应用没有nginx广泛
0
未经许可,不得转载,否则将受到作者追究,博主联系方式见首页右上角

该文章由 发布

这货来去如风,什么鬼都没留下!!!
发表我的评论
取消评论
代码 贴图 加粗 链接 删除线 签到