负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。根据官方数据,其最高极限支持10G的并发。

 HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上。

 

 

haproxy配置

(确保没有rhcs套件的影响,关闭tgtd clvmd mysql luci ricci在浏览器中清除资源,删除集群,节点,最好是换一个虚拟机,之前高可用实验中的corosync对本次实验有影响

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

 

1,安装haproxy软件

构建rpm包需要的软件和依赖

yum install -y rpm-build

yum install gcc -y

yum install -y pcre-devel

rpmbuild -tb haproxy-1.6.11.tar.gz   -tb 把tar包转化为二进制文件

Wrote: /root/rpmbuild/RPMS/x86_64/haproxy-1.6.11-1.x86_64.rpm  这个就是rpm包的位置

Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.Xmz1AH

+ umask 022

+ cd /root/rpmbuild/BUILD

+ cd haproxy-1.6.11

+ '[' /root/rpmbuild/BUILDROOT/haproxy-1.6.11-1.x86_64 '!=' / ']'

+ /bin/rm -rf /root/rpmbuild/BUILDROOT/haproxy-1.6.11-1.x86_64

+ exit 0

安装rpm -ivh haproxy-1.6.11-1.x86_64.rpm

 

2,配置haproxy

rpm -qpl haproxy-1.6.11-1.x86_64.rpm   查看安装会生成的文件

/etc/haproxy

/etc/rc.d/init.d/haproxy

/usr/sbin/haproxy

/usr/share/doc/haproxy-1.6.11

/usr/share/doc/haproxy-1.6.11/CHANGELOG

/usr/share/doc/haproxy-1.6.11/README

/usr/share/doc/haproxy-1.6.11/architecture.txt

/usr/share/doc/haproxy-1.6.11/configuration.txt

/usr/share/doc/haproxy-1.6.11/intro.txt

/usr/share/doc/haproxy-1.6.11/management.txt

/usr/share/doc/haproxy-1.6.11/proxy-protocol.txt       没有配置文件,需要自己建立

 

tar zxf haproxy-1.6.11.tar.gz   用一个存在的配置文件模版改写,在tar包里面找example

cd haproxy-1.6.11

(find -name *.spec  之所以可以构建rpm包是因为有.spec文件,只要是以spec结尾的文件都会自动出现rpm包的构建模板,vim test.spec可以看到,已经出现的模板)

cd examples/

content-sw-sample.cfg 这个是主配置模版文件

cp content-sw-sample.cfg /etc/haproxy/haproxy.cfg    

(/etc/rc.d/init.d/haproxy

# processname: haproxy

# config: /etc/haproxy/haproxy.cfg  这里有要读取的配置文件的位置和名字

# pidfile: /var/run/haproxy.pid)

 

修改配置文件

#

# This is a sample configuration. It illustrates how to separate static objects

# traffic from dynamic traffic, and how to dynamically regulate the server load.

#

# It listens on 192.168.1.10:80, and directs all requests for Host 'img' or

# URIs starting with /img or /css to a dedicated group of servers. URIs

# starting with /admin/stats deliver the stats page.

#

 

global    定义全局变量

        maxconn         10000    并发最大链接数

        stats socket    /var/run/haproxy.stat mode 600 level admin

        log             127.0.0.1 local0    日志保存在本地  local0是自定义

        uid             200    指定了用户uid gid,所以必须要创建用户

        gid             200

        chroot          /var/empty   chroot是切换根目录,安全,防黑客

        daemon    后台运行

 

defaults    backend和frontend共有的放在defaults

        mode            http     默认使用 http 的 7 层模式 tcp: 4 层

        log             global    表示在全局变量里面找

        option          httplog    http 日志格式

        option          dontlognull     禁用空链接日志

        monitor-uri     /monitoruri   检测haproxy服务本身

        maxconn         8000     覆盖全局变量

        timeout client  30s   客户端超时

        stats uri       /admin/stats   haproxy监控页面

        option prefer-last-server

        retries         2   重试2次失败认为服务器不可用

        option redispatch    当 client 连接到挂掉的机器时,重新分配到健康的主机

        timeout connect 5s   连接超时

        timeout server  5s    服务端超时

 

# The public 'www' address in the DMZ

frontend public

        bind            *:80 name clear      监听所有的80端口

        #bind            192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem

        #use_backend     static if { hdr_beg(host) -i img }

        #use_backend     static if { path_beg /img /css   }

        default_backend static   默认返回后端的static

 

# The static backend backend for 'Host: img', /img and /css.

backend static

        mode            http

        balance         roundrobin   轮询算法

        server          statsrv1 172.25.28.2:80 check inter 1000 后端httpd服务器

        server          statsrv2 172.25.28.3:80 check inter 1000

 

3,创建haproxy用户

[[email protected] haproxy]# grep 200 /etc/passwd   全局配置要求uid和gid是200

[[email protected] haproxy]# groupadd -g 200 haproxy   

[[email protected] haproxy]# useradd -u 200 -g 200 -M haproxy  这里不创建也不指定家目录

-M, --no-create-home          do not create the user's home directory

[[email protected] haproxy]# id haproxy

uid=200(haproxy) gid=200(haproxy) groups=200(haproxy)

[[email protected] haproxy]# su - haproxy

su: warning: cannot change directory to /home/haproxy: No such file or directory

-bash-4.1$ logout  #没有家目录但是有bash

[[email protected] haproxy]# vim /etc/security/limits.conf    实验可以不写,但是生产中必须要写

# End of file

haproxy -       nofile  10000

(sysctl -a | grep file

fs.file-nr = 544       0     98861

fs.file-max = 98861               内核限制>操作系统>程序 等于也不会出错

 

4,server1启动服务

/etc/init.d/haproxy start

server2,server3开启httpd

 

5,客户端访问测试

访问172.25.28.1/monitoruri     200ok那么haproxy服务本身是正常的,跟server2,3httpd服务是否启动无关

访问172.25.28.1/admin/stats  监控页面,颜色都有说明,显示监控服务的状态

访问172.25.28.1 轮询server2,server3httpd服务器

 

 

配置haproxy日志

1,修改日志文件系统的配置文件

/etc/rsyslog.conf

# Provides UDP syslog reception

$ModLoad imudp

$UDPServerRun 514

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

local0不保存在/var/log/messages

 

# Save boot messages also to boot.log

local7.*                                                /var/log/boot.log

local0.*                                                /var/log/haproxy.log

#local0.*保存在/var/log/haproxy.log

2,重启日志系统

/etc/init.d/rsyslog restart

 

3,客户端访问测试

curl和网页随便访问都行

tail -f /var/log/haproxy.log  -f 表示追加显示最新数据

 

haproxy调度后端服务器的多种算法

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

本机客户端改变或者后端服务器挂了,否则分配的后端服务器是不会改变的

注意:这个有先后顺序,这个server2坏了,server3上,如果server2又好了,那么server2上,因为sevrer2写在前面

 

八种算法

 1、roundrobin

表示简单的轮询,每个服务器根据权重轮流使用,在服务器的处理时间平均分配的情况下这是最流畅和公平的算法。该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。

2、leastconn

连接数最少的服务器优先接收连接。leastconn建议用于长会话服务,例如LDAP、SQL、TSE等,而不适合短会话协议。如HTTP.该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。

3、static-rr

每个服务器根据权重轮流使用,类似roundrobin,但它是静态的,意味着运行时修改权限是无效的。另外,它对服务器的数量没有限制。

该算法一般不用;

4、source

对请求源IP地址进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个客户端IP地址总是访问同一个服务器。如果哈希的结果随可用服务器数量而变化,那么客户端会定向到不同的服务器;

该算法一般用于不能插入cookie的Tcp模式。它还可以用于广域网上为拒绝使用会话cookie的客户端提供最有效的粘连;

该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

5、uri

表示根据请求的URI左端(问号之前)进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个URI地址总是访问同一个服务器。一般用于代理缓存和反病毒代理,以最大限度的提高缓存的命中率。该算法只能用于HTTP后端;

该算法一般用于后端是缓存服务器;

该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

6、url_param

在HTTP GET请求的查询串中查找<param>中指定的URL参数,基本上可以锁定使用特制的URL到特定的负载均衡器节点的要求;

该算法一般用于将同一个用户的信息发送到同一个后端服务器;

该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

7、hdr(name)

在每个HTTP请求中查找HTTP头<name>,HTTP头<name>将被看作在每个HTTP请求,并针对特定的节点;

如果缺少头或者头没有任何值,则用roundrobin代替;

该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

8、rdp-cookie(name)

为每个进来的TCP请求查询并哈希RDP cookie<name>;

该机制用于退化的持久模式,可以使同一个用户或者同一个会话ID总是发送给同一台服务器。如果没有cookie,则使用roundrobin算法代替;

该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。

 

 

 

 

 

 

haproxy动静分离

1,修改配置文件

frontend public

        bind            *:80 name clear

        #bind            192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem

        #use_backend     static if { hdr_beg(host) -i img }

use_backend     static2 if { path_end -i .php }  如果uri路径是以.php结尾那么就去static2策略,这里php是动态请求

        default_backend static1   如果不满足上面的,默认访问static1策略,这个名字是随便起的,但是要和下面策略对应上

 

# The static backend backend for 'Host: img', /img and /css.

backend static1

        balance         roundrobin

        #balance         source

        server          statsrv1 172.25.28.2:80 check inter 1000

 

#分开了两个策略看实验现象,实际每个方法里面都可以有多个服务器

backend static2

        balance         roundrobin

        server          statsrv1 172.25.28.3:80 check inter 1000

 

2,重启服务/etc/init.d/haproxy restart

3,server3作为动态请求的响应

安装php 重启httpd

index.php

<?php

phpinfo();

?>

如果apache安装了php,同时存在index.phpindex.html那么默认找index.php

4,访问测试

路径中以.php结尾 172.25.28.1/index.php那么就访问server3的动态服务器

否则默认返回static1的静态服务器

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

 

 

 

acl访问控制

1,403报错重定向

frontend public

        bind            *:80 name clear

        #bind            192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem

        #use_backend     static if { hdr_beg(host) -i img }

#可以对src dst src_port dst_port 进行acl访问控制 #

         acl blacklist src 172.25.28.250  源重定向

#acl blacklist src 172.25.28.251  这个可以多次添加到黑名单

#acl blacklist src 172.25.28.0/24  网段黑名单

        

http-request deny if blacklist   在黑名单的直接出现403Forbidden报错

errorloc 403 http://172.25.28.1:8080  也可以不写,那么就不会重定向,如果4403Forbidden报错,那么重定向到这个地址8080端口(server1安装httpdindex.html页面可以是 网站正在维护,修改httpd.conf监听端口为8080,因为80端口被haproxy占用

 

        use_backend     static2 if { path_end -i php  }

        default_backend static1

/etc/init.d/haproxy reload  每次修改都要重新加载配置

 

客户端访问测试

注意curl 172.25.28.1是不会显示重点向页面的,因为curl不支持,但是curl -I 可以看到

HTTP/1.1 302 Found  这是做了重定向的)

这个网站是做了两个重定向,taobao.com--->http://www.taobao.com--->https://www.taobao.com

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

 

2,直接重定向

frontend public

        bind            *:80 name clear

        #bind            192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem

        #use_backend     static if { hdr_beg(host) -i img }

 

        acl blacklist src 172.25.28.250

        #http-request deny if blacklist

        #errorloc 403 http://172.25.28.1:8080

        redirect location http://172.25.28.3   黑名单访问直接访问这个地址

        use_backend     static2 if { path_end -i php  }

        default_backend static1

客户端访问测试:

浏览器访问172.25.28.3

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

 

haproxy读写分离

配置文件

frontend public

        bind            *:80 name clear

        #bind            192.168.1.10:443 ssl crt /etc/haproxy/haproxy.pem

        #use_backend     static if { hdr_beg(host) -i img }

        #use_backend     static if { path_beg /img /css   }

 

        acl blacklist src 172.25.28.250

 

        acl write method POST  请求

        acl write method PUT    上传

 

        #redirect location http://172.25.28.3

 

        #use_backend     static2 if { path_end -i .php }

        use_backend     static2 if write  如果是请求,上传那么交给static2策略

        default_backend static1  否则默认返回static1策略

 

# The static backend backend for 'Host: img', /img and /css.

backend static1

        balance         roundrobin

        server          statsrv1 172.25.28.2:80 check inter 1000

 

backend static2

        balance         roundrobin

        server          statsrv2 172.25.28.3:80 check inter 1000

 

 

 

server2和server3

yum install php -y

在默认发布目录下建立upload目录并且给777权限,允许任何人上传,实际是apache身份

vim 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";

  }

?>

 

vim index.php

<html>

<body>

 

<form action="upload_file.php" method="post"

enctype="multipart/form-data">

<label for="file">Filename:</label>

<input type="file" name="file" id="file" />

<br />

<input type="submit" name="submit" value="Submit" />

</form>

</body>

</html>

 

重启httpd服务

/etc/init.d/httpd restart

 

客户端访问测试

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

 这个页面其实读的是static1 ,server2作为静态服务

负载均衡 | Haproxy配置 haproxy日至文件 | haproxy动静分离 | acl访问控制 | haproxy读写分离

这个页面上传是static2,server3作为动态服务器

#可以查看上传的文件只在server3中,实现了读写分离

[[email protected] upload]# pwd

/var/www/html/upload

[[email protected] upload]# ll

total 56

-rw-r--r-- 1 apache apache 54157 Aug  4 23:06 redhat.jpg   身份,组都是apache