Haproxy实现负载均衡

  • 1 Haproxy的简介
  • 2 Haproxy的部署
  • 2.1 实验环境
  • 2.2 下载Haproxy软件
  • 2.3 查看Haproxy监控页面
  • 2.4 日志路径
  • 2.5 Haproxy的负载均衡算法(balance)
  • 2.6 静动分离的实现
  • 2.7 访问控制的实现
  • 2.8 读写分离的实现


1 Haproxy的简介

Haproxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
Haproxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。Haproxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。其支持从4层至7层的网络交换,即覆盖所有的TCP协议

Haproxy的架构:

haproxy四层 haproxy原理_配置文件

相同点:在功能上,proxy通过反向代理方式实现 WEB均衡负载。和 Nginx,ApacheProxy,lighttpd,Cheroke 等一样。
不同点:Haproxy 并不是 web 服务器。以上提到所有带反向代理均衡负载的产品,都清一色是 WEB 服务器。简单说,就是他们能处理解析页面的。而Haproxy 仅仅是一款的用于均衡负载的应用代理。其自身并不能提供web服务。但其配置简单,拥有非常不错的服务器健康检查功能还有专门的系统状态监控页面,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。

2 Haproxy的部署

2.1 实验环境

  • haproxy服务:server1
  • 客户端:server2、server3,配置apache服务并编辑apache的默认发布页面

2.2 下载Haproxy软件

(1)下载软件:yum install haproxy.x86_64 -y

haproxy四层 haproxy原理_配置文件_02

(2)haproxy的配置文件:/etc/haproxy/haproxy.cfg

2.3 查看Haproxy监控页面

stats uri /status  ##设置Haproxy 监控统计页面的URL 路径,可随意指定
	 stats auth user:passwd ##定义查看Haproxy 监控统计页面的用户:密码

编辑haproxy的配置文件: vim /etc/haproxy/haproxy.cfg

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    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                 3000
    stats uri /status  ##设置Haproxy 监控统计页面的URL 路径,可随意指定
    stats auth user:passwd ##定义查看Haproxy 监控统计页面的用户:密码
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:80
#    acl url_static       path_beg       -i /static /images /javascript /stylesheets
#    acl url_static       path_end       -i .jpg .gif .png .css .js
#
#    use_backend static          if url_static
    default_backend             app
   
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
#backend static
#    balance     roundrobin
#    server      static 127.0.0.1:4331 check

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     roundrobin
    server  app1 172.25.12.2:80 check
    server  app2 172.25.12.3:80 check

(2)启动haproxy服务:systemctl start haproxy.service

haproxy四层 haproxy原理_配置文件_03

(3)测试:172.25.12.1/status,输入正确的账号密码即可访问

haproxy四层 haproxy原理_配置文件_04

haproxy四层 haproxy原理_配置文件_05

  • 停止server2的apache服务,刷新监控界面

haproxy四层 haproxy原理_配置文件_06


haproxy四层 haproxy原理_haproxy四层_07

2.4 日志路径

linux资源限制配置文件是/etc/security/limits.conf;限制用户进程的数量对于linux系统的稳定性非常重要。
limits.conf文件限制着用户可以使用的最大文件数,最大线程,最大内存等资源使用量。

core - 限制内核文件的大小

date - 最大数据大小

fsize - 最大文件大小

memlock - 最大锁定内存地址空间

nofile - 打开文件的最大数目

(1)编辑linux资源限制配置文件:/etc/security/limits.conf

haproxy四层 haproxy原理_配置文件_08

(2)编辑haproxy的配置文件:vim /etc/haproxy/haproxy.cfg

haproxy四层 haproxy原理_vim_09

(3) 编辑rsyslog参数:/etc/sysconfig/rsyslog

  • 在“SYSLOGD_OPTIONS”行上加“-r”选项以允许接受外来日志消息

haproxy四层 haproxy原理_vim_10

(4)编辑rsyslog的配置文件:vim /etc/rsyslog.conf

  • 允许514端口接收使用UDP协议转发过来的日志

haproxy四层 haproxy原理_php_11

  • local2的所有日志信息存放到/var/log/haproxy.log

haproxy四层 haproxy原理_php_12


(5)重启服务

  • 重启日志服务: systemctl restart rsyslog.service
  • 重新加载服务:systemctl reload haproxy.service

(6)测试

  • 访问172.25.12.1,生成日志信息,可以发现日志文件已经生成

haproxy四层 haproxy原理_vim_13


haproxy四层 haproxy原理_haproxy四层_14

2.5 Haproxy的负载均衡算法(balance)

Haproxy的8种负载均衡算法:

roundrobin,表示简单的轮询
static-rr,表示根据权重,
leastconn,表示最少连接者先处理,
source,表示根据请求源IP,
uri,表示根据请求的URI;
url_param,表示根据请求的URl参数’balance url_param’ requires an URL parameter name
hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求;
rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求。

balance roundrobin :haproxy把请求轮流的转发到每一个服务器上,依据每台服务器的权重,此权重会动态调整。最常见的默认配置。

balance source :haproxy按照客户端的IP地址进行负载均衡策略,即同一IP地址的所有请求都发送到同一服务器时,需要配置此选项。

测试:balance source

(1)编辑haproxy的配置文件:vim /etc/haproxy/haproxy.cfg

haproxy四层 haproxy原理_haproxy四层_15

(2)重新加载服务:systemctl reload haproxy.service (3)测试,在浏览器中输入172.24.12.1时,所有的请求发送到server2

haproxy四层 haproxy原理_配置文件_16


haproxy四层 haproxy原理_haproxy四层_17

2.6 静动分离的实现

(1)编辑配置文件:vim /etc/haproxy/haproxy.cfg

# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    ##测试URL以/static /images /javascript /stylesheets开头的策略url_static 
    acl url_static       path_end       -i .jpg .gif .png .css .js
    ##测试URI是否以.jpg .gif .png .css .js结尾
#
    use_backend static          if url_static ##如果是静态
    default_backend             app  ##默认动态

#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
    balance     roundrobin
    server      static 172.25.12.3:80 check ##静态访问server3

#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     roundrobin
    #balance     source
    server  app1 172.25.12.2:80 check  ##动态访问server2
    #server  app2 172.25.12.3:80 check

(2)在server3中创建apache的默认发布目录:mkdir /varwww/html/images,并在此目录上传图片1.jpg

(3)重启服务

  • 重新加载haproxy服务:systemctl reload haproxy.service
  • 重启apache服务:systemctl restart httpd.service

(4)测试:在浏览器中输入 172.25.12.1/images/1.jpg,验证访问以.jpg结尾的URL访问的是server3

haproxy四层 haproxy原理_vim_18

在浏览器中输入172.25.254.1,访问的是server2

haproxy四层 haproxy原理_配置文件_16

2.7 访问控制的实现

(1)禁止 172.25.12网段的用户访问 172.25.12.1

# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js
    acl blacklist        src          172.25.12.0/24
    block if  blacklist
#
    use_backend static          if url_static
    default_backend             app

#---------------------------------------------------------------------
# static backend for serving up images, stylesheets

重新加载服务:systemctl reload haproxy.service

测试:在浏览器中输入172.25.254.1,提示403错误

haproxy四层 haproxy原理_配置文件_20

(2)将错误页面进行重定向

重定向(临时)旧地址依旧在,但网站希望你访问新的(盗链)

  • 编辑配置文件:vim /etc/haproxy/haproxy.cfg
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js
    acl blacklist        src          172.25.12.0/24
    block if  blacklist
    errorloc 403  http://www.baidu.com  ##如果出现403错误,页面将重定向到百度
#
    use_backend static          if url_static
    default_backend             app
  • 重新加载服务:systemctl reload haproxy.service
  • 测试:在浏览器中输入172.25.254.1,页面将重定向到 http://www.baidu.com

haproxy四层 haproxy原理_vim_21

重定向(永久)旧地址永久移除

  • 编辑配置文件:vim /etc/haproxy/haproxy.cfg
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js
    acl blacklist        src          172.25.12.0/24
    redirect            location       http://www.163.com ##永久重定向
    #block if  blacklist
    #errorloc 403  http://www.baidu.com
#
    use_backend static          if url_static
    default_backend             app
  • 重新加载服务:systemctl reload haproxy.service
  • 测试:在浏览器中输入172.25.254.1,页面将重定向到 http://www.163.com

haproxy四层 haproxy原理_haproxy四层_22

haproxy四层 haproxy原理_配置文件_23

2.8 读写分离的实现

(1)编辑haproxy的配置文件:vim /etc/haproxy/haproxy.cfg

# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js
    acl write            method         POST ##method表示“方式”,写有两种方式:POST、PUT
    acl write            method         PUT


    #acl blacklist        src          172.25.12.0/24
    #redirect            location       http://www.163.com
    #block if  blacklist
    #errorloc 403  http://www.baidu.com
#
    
    use_backend static          if write  ##写操作是访问static,也即server3
    default_backend             app   ##默认访问app,也即srver2

#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
    balance     roundrobin
    server      static 172.25.12.3:80 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     roundrobin
    #balance     source
    server  app1 172.25.12.2:80 check  
    #server  app2 172.25.12.3:80 check

(2)server2和server3均安装php插件,都使用php编辑“读”时的发布页面和文件写入的信息页面,为了验证读写分离,server2和server3的apache新建upload目录:/var/www/html/upload

yum install php
	mkdir /var/www/html/upload
	chmod 777 /var/www/html/upload/ ##更改目录的权限
  • 编辑php的发布页面:/var/www/html/index.php
<html>
<body>

<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">server2   filename:</label> 
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Submit" />
</form>

</body>
</html>
  • 编辑上传的发布页面:/var/www/html/upload_file.php
<?php
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 2000000))
  {
  if ($_FILES["file"]["error"] > 0)
    {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
    }
  else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

    if (file_exists("upload/" . $_FILES["file"]["name"]))
      {
      echo $_FILES["file"]["name"] . " already exists. ";
      }
    else
      {
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "upload/" . $_FILES["file"]["name"]);
      echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
      }
    }
  }
else
  {
  echo "Invalid file";
  }
?>

(3)重启服务

  • 重新加载haproxy服务:systemctl reload haproxy.service
  • 重启apache服务:systemctl restart httpd.service

(4)测试

  • 在浏览器中输入172.25.254.1/index.php,此时可以验证读是在server2上完成的

haproxy四层 haproxy原理_haproxy四层_24

  • 在网页上传文件1.jpg

haproxy四层 haproxy原理_php_25


haproxy四层 haproxy原理_vim_26

  • 可以发现文件的写是在server3上完成的

haproxy四层 haproxy原理_vim_27