高可用负载均衡架构

 

1     前言

1.1  LVS介绍

LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。目前有三种IP负载均衡技术(VS/NAT、VS/TUN和VS/DR),十种调度算法(rrr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq):

1.1.1     静态调度

①rr(Round Robin):轮询调度,轮叫调度

轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。【提示:这里是不考虑每台服务器的处理能力】

 

②wrr:weight,加权(以权重之间的比例实现在各主机之间进行调度)

由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,我们根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。

 

③sh:source hashing,源地址散列。主要实现会话绑定,能够将此前建立的session信息保留了

源地址散列调度算法正好与目标地址散列调度算法相反,它根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的并且没有超负荷,将请求发送到该服务器,否则返回空。它采用的散列函数与目标地址散列调度算法的相同。它的算法流程与目标地址散列调度算法的基本相似,除了将请求的目标IP地址换成请求的源IP地址,所以这里不一个一个叙述。

 

④Dh:Destination hashing:目标地址散列。把同一个IP地址的请求,发送给同一个server。

目标地址散列调度算法也是针对目标IP地址的负载均衡,它是一种静态映射算法,通过一个散列(Hash)函数将一个目标IP地址映射到一台服务器。目标地址散列调度算法先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

 

1.1.2     动态调度

①lc(Least-Connection):最少连接

最少连接调度算法是把新的连接请求分配到当前连接数最小的服务器,最小连接调度是一种动态调度短算法,它通过服务器当前所活跃的连接数来估计服务器的负载均衡,调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1,当连接中止或超时,其连接数减一,在系统实现时,我们也引入当服务器的权值为0时,表示该服务器不可用而不被调度。

简单算法:active*256+inactive(谁的小,挑谁)

 

②wlc(Weighted Least-Connection Scheduling):加权最少连接。

加权最小连接调度算法是最小连接调度的超集,各个服务器用相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权限,加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。

简单算法:(active*256+inactive)/weight【(活动的连接数+1)/除以权重】(谁的小,挑谁)

 

③sed(Shortest Expected Delay):最短期望延迟

基于wlc算法

简单算法:(active+1)*256/weight 【(活动的连接数+1)*256/除以权重】

 

④nq(never queue):永不排队(改进的sed)

无需队列,如果有台realserver的连接数=0就直接分配过去,不需要在进行sed运算。

 

⑤LBLC(Locality-Based Least Connection):基于局部性的最少连接

基于局部性的最少连接算法是针对请求报文的目标IP地址的负载均衡调度,不签主要用于Cache集群系统,因为Cache集群中客户请求报文的布标IP地址是变化的,这里假设任何后端服务器都可以处理任何请求,算法的设计目标在服务器的负载基本平衡的情况下,将相同的目标IP地址的请求调度到同一个台服务器,来提高个太服务器的访问局部性和主存Cache命中率,从而调整整个集群系统的处理能力。

基于局部性的最少连接调度算法根据请求的目标IP地址找出该目标IP地址最近使用的RealServer,若该Real Server是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。

 

⑥LBLCR(Locality-Based Least ConnectionswithReplication):带复制的基于局部性最少链接

带复制的基于局部性最少链接调度算法也是针对目标IP地址的负载均衡,该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按“最小连接”原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接”原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。

 

1.1.3     IPVS实现负载均衡的方法

l  NAT:地址转换(类似于DNAT)

1、集群点跟director必须工作在同一个IP的网络中

2、RIP通常是私有地址,仅用于各集群节点间的的通信

3、director位于client和real server之间,并负责处理进出的所有通道。

4、realserver必须将网关执行DIP

5、director支持端口映射

6、realserver可以使用任何类型的操作系统(os)

7、较大规模应用场景中,director易成为系统瓶颈

l  DR:直接路由(及用于作为源地址)

1、各集群节点跟director必须在同一个物理网络中;

2、RIP可以使用公网地址,实现便携的远程管理和监控;

3、director仅负责处理入站请求,形影报文则有realserver直接发往客户端

4、realserver不能将网关指向DIP,而是直接指向前端网关;

5、director不支持端口映射

6、大多数操作系统能够用在realserver

7、director能够处理更多的realserver

l  TUN:隧道

1、集群节点可以跨越Internet

2、RIP必须是公网地址

3、director仅负责处理入站请求,形影报文则有realserver直接发往客户端

4、realserver网关不能指向director

5、只有咫尺隧道功能的OS才能用于realserver

6、不支持端口映射

1.2  Keepalived

Keepalived在这里主要用作RealServer的健康状态检查以及Master主机和BackUP主机之间failover的实现下面,搭建基于LVS+Keepalived的高可用负载均衡集群,其中,LVS实现负载均衡,但是,简单的LVS不能监控后端节点是否健康,它只是基于具体的调度算法对后端服务节点进行访问。同时,单一的LVS又存在单点故障的风险。在这里,引进了Keepalived,可以实现以下几个功能:

1. 检测后端节点是否健康。

2. 实现LVS本身的高可用。

 

1.3  Haproxy

HAProxy是一个使用C语言编写的自由及开放源代码软件[1],其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。

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

HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space)实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

2     架构图

高可用负载均衡架构(1)_lvs

架构图说明:

1,LVS两台服务器,虚拟IP使用在Haproxy服务器上,保证高可用。

2,Haproxy主要作用是夸网段IP支持,LVS不支持夸网段。

3,Nginx Proxy主要有缓存作用增加性能。

4,后端数据库层次,再次使用了LVS高可用,虚拟IP使用在mycat服务器上。

5,Mycat作用是读写分离,增加性能和高可用Mysql。正常情况下写是Mysql Master1,读是Mysql Master2,Mysql Slave,如Mysql Master1出现故障。则读写切换到Mysql Master2。

PS:最上层两台LVS服务器建议用高性能物理机。

 

3     应用安装配置

3.1  实验环境

系统版本:Centos 7 64位

服务器角色

服务器IP

Nginx  Proxy1

192.168.8.14

Nginx  Proxy2

192.168.8.15

Nginx  Web1

192.168.8.16

Nginx  Web2

192.168.8.17

Tomcat1

192.168.8.18

Tomcat2

192.168.8.19

Tcpserver(ftp)1

192.168.8.20

Tcpserver(ftp)2

192.168.8.21

 

3.2  Nginx Proxy安装配置

(192.168.8.14和192.168.8.15)两台服务器操作

3.2.1     nginx的yum源

vi /etc/yum.repos.d/nginx.repo

[nginx]

name=nginx  repo

baseurl=http://nginx.org/packages/centos/7/$basearch/

gpgcheck=0

enabled=1

 

3.2.2     yum安装nginx

yuminstall nginx

 

3.2.3     配置nginx

vi/etc/nginx/nginx.conf

user  nginx;

worker_processes  4;

worker_cpu_affinity  0001 0010 0100 1000;

 

error_log  logs/error.log  notice;

 

events  {

    use epoll;

    worker_connections  1024;

}

 

 

http  {

    include       mime.types;

    default_type  application/octet-stream;

 

    log_format  main   '$http_x_forwarded_for - $remote_user [$time_local]  "$request" '

                      '$status  $body_bytes_sent "$http_referer" '

                       '"$http_user_agent" $remote_addr';

 

    #access_log  logs/access.log  main;

 

    sendfile                             on;

    tcp_nopush                           on;

    tcp_nodelay                          on;

 

    server_names_hash_bucket_size       128;

    large_client_header_buffers    4    128k;

    client_max_body_size               128m;

    client_header_buffer_size           32k;

    keepalive_timeout                   120;

 

    fastcgi_connect_timeout             300;

    fastcgi_send_timeout                300;

    fastcgi_read_timeout                300;

    fastcgi_buffer_size                128k;

    fastcgi_buffers                4   128k;

    fastcgi_busy_buffers_size          256k;

    fastcgi_temp_file_write_size       256k;

 

    gzip                                 on;

    gzip_vary                            on;

    gzip_min_length                      1k;

    gzip_buffers                   4     64k;

    gzip_http_version                   1.0;

    gzip_comp_level                       9;

    gzip_types              text/plain  application/x-javascript text/css text/javascript application/javascript  application/xml p_w_picpath/jpeg p_w_picpath/gif p_w_picpath/png;

 

    proxy_cache_path /etc/nginx/cache  levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=30g;

 

    upstream testweb {

        server 192.168.8.16:80;

        server 192.168.8.17:80;

        }

 

    upstream testtomcat {

        server 192.168.8.18:8080;

        server 192.168.8.19:8080;

        }

 

    server {

        listen       80;

        server_name  testweb.com.cn;

 

        access_log  logs/testweb.access.log  main;

 

        location ~ .*\.(css|js|gif|jpg|png)$  {

                proxy_pass http://testweb;

                proxy_cache cache_one;

                proxy_cache_valid 200 301 302  5m;

                proxy_cache_valid any      1m;

                proxy_cache_key            $host$uri$is_args$args;

                expires 30d;

                }

 

        location / {

            proxy_pass http://testweb;

            proxy_redirect off;   

            proxy_set_header Host $host;   

            proxy_set_header X-Real-IP  $remote_addr;   

            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;   

            client_max_body_size 10m;   

            client_body_buffer_size  128k;   

            proxy_connect_timeout 300;   

            proxy_send_timeout 300;   

            proxy_read_timeout 300;   

            proxy_buffer_size 4k;   

            proxy_buffers 4 32k;   

            proxy_busy_buffers_size 64k;   

            proxy_temp_file_write_size  64k; 

        }

 

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

             root   html;

        }

    }

 

    server {

        listen       80;

        server_name  testtomcat.com.cn;

 

        access_log  logs/testtomcat.access.log  main;

 

        location / {

            proxy_pass http://testtomcat;

            proxy_redirect off;

            proxy_set_header Host $host;

            proxy_set_header X-Real-IP  $remote_addr;

            proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;

            client_max_body_size 10m;

            client_body_buffer_size 128k;

            proxy_connect_timeout 300;

            proxy_send_timeout 300;

            proxy_read_timeout 300;

            proxy_buffer_size 4k;

            proxy_buffers 4 32k;

            proxy_busy_buffers_size 64k;

            proxy_temp_file_write_size 64k;

        }

 

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

        }

    }

}

 

mkdir/etc/nginx/logs/

 

启动nginx

/etc/init.d/nginxstart

 

3.3  Nginx Web安装配置

(192.168.8.16和192.168.8.17)两台服务器操作

3.3.1     nginx的yum源

vi /etc/yum.repos.d/nginx.repo

[nginx]

name=nginx  repo

baseurl=http://nginx.org/packages/centos/7/$basearch/

gpgcheck=0

enabled=1

 

3.3.2     yum安装nginx

yuminstall nginx

 

3.3.3     配置nginx

略,根据生产情况配置

在网站根目录配置一个测试文件,如:

192.168.8.16服务器:

cattest.html

web16

 

192.168.8.17服务器:

web17

启动nginx

/etc/init.d/nginxstart

3.4  tomcat 安装配置

(192.168.8.18和192.168.8.19)两台服务器操作

3.4.1     安装JAVA

yum install–y java-1.8.0-openjdk

3.4.2     下载tomcat

官网下载http://tomcat.apache.org/

 

3.4.3     安装tomcat

tarzxvf apache-tomcat-8.5.20.tar.gz

mvapache-tomcat-8.5.20 /usr/local/

3.4.4     测试页面

cd/usr/local/apache-tomcat-8.5.20/webapps/ROOT/

192.168.8.18服务器:

vitest.html

tomcat18

192.168.8.19服务器:

vitest.html

tomcat19

启动tomcat

/usr/local/apache-tomcat-8.5.20/bin/startup.sh

 

3.5  ftp安装配置

(192.168.8.20和192.168.8.21)两台服务器操作

3.5.1     安装ftp

yuminstall vsftpd

3.5.2     配置ftp

vi/etc/vsftpd/vsftpd.conf

增加配置:

pasv_enable=YES

pasv_promiscuous=YES

port_enable=YES

port_promiscuous=NO

pasv_min_port=10001

pasv_max_port=10010     #如果用户较多,可以放大

 

启动ftp

/etc/init.d/vsftpdstart

 

4     haproxy安装配置

4.1  实验环境

系统版本:Centos 7 64位

服务器角色

服务器IP

Haproxy

192.168.8.12

Haproxy

192.168.8.13

(192.168.8.12和192.168.8.13)两台服务器操作

4.2  安装haproxy

tarzxvf haproxy-1.7.7.tar.gz

makeTARGET=linux2628 PREFIX=/usr/local/haproxy

#”TARGET”指定编译对应的os对应的内核版本,通过”uname -r”查询内核版本呢,README文件可查询对应关系。

makeinstall PREFIX=/usr/local/haproxy

 

groupaddhaproxy

useradd-g haproxy haproxy -s /sbin/nologin

 

4.3  配置haproxy

默认安装目录下没有配置文件,只有”doc”,“sbin”,“share”三个目录,可手工创建目录及配置文件。

haproxy的配置文件主要是以下5部分:

global全局配置、defaults默认配置、监控页面配置、frontend配置、backend配置。

mkdir-p /usr/local/haproxy/etc

cd/usr/local/haproxy/etc/

vimhaproxy.cfg

4.3.1     示例配置

global

    #定义全局日志, 配置在本地, 通过local0 输出, 默认是info级别,可配置两条

    log 127.0.0.1 local0 warning

    #定义日志级别【error warning info debug】

    #log 127.0.0.1 local1 info

     

    #运行路径

    chroot /usr/local/haproxy

    #PID 文件存放路径

    pidfile /var/run/haproxy.pid

     

    #设置每haproxy进程的最大并发连接数, 其等同于命令行选项“-n”; “ulimit -n”自动计算的结果参照此参数设定.

    maxconn 4096

     

    #运行haproxy 用户, 或者使用关键字uid

    user haproxy

    #运行haproxy 用户组, 或者使用关键字gid

    group haproxy

     

    #后台运行haproxy

    daemon

  

    #设置启动的haproxy进程数量, 只能用于守护进程模式的haproxy;

    #默认只启动一个进程, 鉴于调试困难等多方面的原因, 一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式.

    nbproc 1

    #设置每进程所能够打开的最大文件描述符数目, 默认情况其会自动进行计算, 因此不推荐修改此选项.

    #ulimit-n 819200

     

    #调试级别, 一般只在开启单进程时调试, 且生产环境禁用.

    #debug

    #haproxy启动后不会显示任何相关信息, 这与在命令行启动haproxy时加上参数“-q”相同

    #quiet

     

    #定义统计信息保存位置

    stats socket /usr/local/haproxy/stats

 

#默认配置

defaults

    #默认的模式【tcp:4层; http:7层;  health:只返回OK】

    mode http

     

    #继承全局的日志定义输出

    log global

     

    #日志类别, httplog

    #option httplog

  

    #如果后端服务器需要记录客户端真实ip, 需要在HTTP请求中添加”X-Forwarded-For”字段;

    #但haproxy自身的健康检测机制访问后端服务器时, 不应将记录访问日志,可用except来排除127.0.0.0,即haproxy本身.

    #option forwardfor except 127.0.0.0/8

    option forwardfor

  

    #开启http协议中服务器端关闭功能, 每个请求完毕后主动关闭http通道, 使得支持长连接,使得会话可以被重用,使得每一个日志记录都会被记录.

    option httpclose

  

    #如果产生了一个空连接,那这个空连接的日志将不会记录.

    option dontlognull

  

    #当与后端服务器的会话失败(服务器故障或其他原因)时, 把会话重新分发到其他健康的服务器上; 当故障服务器恢复时, 会话又被定向到已恢复的服务器上;

    #还可以用”retries”关键字来设定在判定会话失败时的尝试连接的次数

    option redispatch

    retries 3

     

    #当haproxy负载很高时, 自动结束掉当前队列处理比较久的链接.

    option abortonclose

  

    #默认http请求超时时间

    timeout http-request 10s

    #默认队列超时时间, 后端服务器在高负载时, 会将haproxy发来的请求放进一个队列中.

    timeout queue 1m

    #haproxy与后端服务器连接超时时间.

    timeout connect 5s

    #客户端与haproxy连接后, 数据传输完毕,  不再有数据传输, 即非活动连接的超时时间.

    timeout client 1m

    #haproxy与后端服务器非活动连接的超时时间.

    timeout server 1m

    #默认新的http请求连接建立的超时时间,时间较短时可以尽快释放出资源,节约资源.

    timeout http-keep-alive 10s

    #心跳检测超时时间

    timeout check 10s

     

    #最大并发连接数

    maxconn 2000

     

    #设置默认的负载均衡方式

    #balance source

    #balnace leastconn

 

#统计页面配置, frontend和backend的组合体, 监控组的名称可按需自定义

listen  admin_status

    #配置监控运行模式

    mode http

     

    #配置统计页面访问端口

    bind 0.0.0.0:1080

     

    #统计页面默认最大连接数

    maxconn 10

     

    #http日志格式

    option httplog

     

    #开启统计

    stats enable

     

    #隐藏统计页面上的haproxy版本信息

    stats hide-version

     

    #监控页面自动刷新时间

    stats refresh 30s

     

    #统计页面访问url

    stats uri /stats

     

    #统计页面密码框提示文本

    stats realm mCloud\ Haproxy

     

    #监控页面的用户和密码:admin, 可设置多个用户名

    stats auth admin:admin

     

    #手工启动/禁用后端服务器, 可通过web管理节点

    stats admin if TRUE

    #设置haproxy错误页面

    errorfile 400  /usr/local/haproxy/errorfiles/400.http

    errorfile 403  /usr/local/haproxy/errorfiles/403.http

    errorfile 408  /usr/local/haproxy/errorfiles/408.http

    errorfile 500  /usr/local/haproxy/errorfiles/500.http

     errorfile 502 /usr/local/haproxy/errorfiles/502.http

    errorfile 503  /usr/local/haproxy/errorfiles/503.http

    errorfile 504  /usr/local/haproxy/errorfiles/504.http

 

#监控haproxy后端服务器的监控状态

listen  site_status

       bind 0.0.0.0:1081 #监听端口

       mode http #http的7层模式

       log 127.0.0.1 local2 err #[err warning  info debug]

       monitor-uri /site_status #网站健康检测URL,用来检测HAProxy管理的网站是否可以用,正常返回200,不正常返回503

       acl site_dead nbsrv(php_server) lt 1 #定义网站down时的策略当挂在负载均衡上的指定backend的中有效机器数小于1台时返回true

       acl site_dead nbsrv(html_server) lt 1

       acl site_dead nbsrv(backend_default)  lt 1

       monitor fail if site_dead #当满足策略的时候返回503,网上文档说的是500,实际测试为503

       monitor-net 192.168.4.171/32 #来自192.168.4.152的日志信息不会被记录和转发

       monitor-net 192.168.4.172/32

     

#frontend,  名字自定义

frontend  HAproxy_Cluster

    #定义前端监听端口, 建议采用bind *:80的形式,否则做集群高可用的时候有问题,vip切换到其余机器就不能访问.

    bind 0.0.0.0:80

 

    #acl后面是规则名称,当请求的url末尾是以.php结尾时,匹配触发php_web规则,以下两种写法均可.

 

    #当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾时,匹配并触发static_web规则.

    #acl static_web path_end .gif .png .jpg  .css .js .jpeg

    #acl static_web url_reg  /*.(css|jpg|png|jpeg|js|gif)$

    #-i为忽略大小写,当被请求的是以www.test.com开头的主机时,匹配并触发dns_name规则.

    acl html_web hdr_beg(host) -i  www.haproxytest.com

    #acl html_web hdr_beg(host) 10.11.4.152

    #当客户端的IP是x.x.x.x时,匹配并触发src_ip规则.

    #acl src_ip src x.x.x.x

    #如果匹配acl规则php_web,将请求转交到php_server组处理;如果匹配acl规则html_web,将请求转交到html_server组处理.

    use_backend php_server if php_web

    use_backend html_server if html_web

    #如果以上规则都不匹配时,将请求转交到default_backend组处理.

    default_backend backend_default

 

#backend后端配置, 配置php_server组与html_server组

backend  php_server

    #定义负载均衡方式为roundrobin方式, 即基于权重进行轮询调度的算法, 在服务器性能分布较均匀情况下推荐.

    #另有如下几种负载均衡方式:

    #-- static-rr: 也是基于权重进行轮转调度, 但属于静态方法, 运行时调整后端机组权重不会使用新的权重;

    #-- source: 基于请求源IP进行hash运算匹配后端服务器组;

    #-- leastconn: 不适合会话较短的环境, 如基于http的应用;

    #-- uri: 对整个URI进行hash运算;

    #-- uri_param: 对URI中的参数进行转发;

    #-- hdr(<name>):根据http头进行转发, 无该头部则转为使用roundrobin.

    balance roundrobin

    mode http

    #允许插入serverid到cookie中,serverid后面可定义

    cookie SERVERID

    #心跳检测方式为检测后端服务器index.html文件,还有其他方式

    option httpchk GET /index.html

    #后端服务器定义, maxconn 1024表示该服务器的最大连接数, cookie 1表示serverid为1, weight代表权重(默认1,最大为265,0则表示不参与负载均衡),

    #check inter 1500是检测心跳频率, rise 2是2次正确认为服务器可用, fall 3是3次失败认为服务器不可用.

    server php1 192.168.4.171:80 maxconn 1024  cookie 1 weight 3 check inter 1500 rise 2 fall 3

 

backend  html_server

    balance source

    mode http

    server html1 192.168.4.172:80 maxconn  1024 cookie 1 weight 3 check inter 1500 rise 2 fall 3

 

backend  backend_default

    balance source

    mode http

    server default1 192.168.4.171:80 maxconn  1024 cookie 1 weight 3 check inter 1500 rise 2 fall 3

 

4.3.2     生产配置

global

    log 127.0.0.1 local0 warning

    chroot /usr/local/haproxy

    pidfile /var/run/haproxy.pid

    maxconn 4096

    user haproxy

    group haproxy

    daemon

    nbproc 1

    stats socket /usr/local/haproxy/stats

 

defaults

    mode http

    log global

    option forwardfor except 127.0.0.0/8

    option httpclose

    option dontlognull

    option redispatch

    retries 3

    option abortonclose

    timeout http-request 10s

    timeout queue 1m

    timeout connect 5s

    #timeout client 1m

    #timeout server 1m

    timeout http-keep-alive 10s

    timeout check 10s

    maxconn 200000

     

 

listen  admin_status

    mode http

    bind 0.0.0.0:1080

    maxconn 10

    option httplog

    stats enable

    stats hide-version

    stats refresh 30s

    stats uri /stats

    stats realm mCloud\ Haproxy

    stats auth admin:123456

    stats admin if TRUE

    errorfile 400  /usr/local/haproxy/errorfiles/400.http

    errorfile 403  /usr/local/haproxy/errorfiles/403.http

    errorfile 408  /usr/local/haproxy/errorfiles/408.http

    errorfile 500 /usr/local/haproxy/errorfiles/500.http

    errorfile 502  /usr/local/haproxy/errorfiles/502.http

    errorfile 503  /usr/local/haproxy/errorfiles/503.http

    errorfile 504  /usr/local/haproxy/errorfiles/504.http

 

listen  site_status

       bind 0.0.0.0:1081

       mode http

       log 127.0.0.1 local2 err

       monitor-uri /site_status

       acl site_dead nbsrv(nginx_proxy1) lt 1

       monitor fail if site_dead

monitor-net 192.168.8.14/32

       monitor-net 192.168.8.15/32

       monitor-net 192.168.8.20/32

       monitor-net 192.168.8.21/32

frontend  nginx_cluster

       mode http

       bind 0.0.0.0:80

       acl nginx_1 hdr_beg(host) -i  testweb.com.cn

       acl nginx_2 hdr_beg(host) -i  testtomcat.com.cn

       use_backend nginx_proxy1 if nginx_1

       use_backend nginx_proxy1 if nginx_2

backend  nginx_proxy1

       mode http

       balance roundrobin

       server nginx1 192.168.8.14:80 maxconn  10240 cookie 1 weight 3 check inter 1500 rise 2 fall 3

       server nginx2 192.168.8.15:80 maxconn  10240 cookie 2 weight 3 check inter 1500 rise 2 fall 3

listen  ftp_service

      bind 0.0.0.0:21

      bind 0.0.0.0:10001-10010

      mode tcp

      option tcplog

      balance   roundrobin

      server     ftp_20 192.168.8.20 weight 2 check port 21 inter 10s rise 1 fall 2

      server     ftp_21 192.168.8.21 weight 2 check port 21 inter 10s rise 1 fall 2

error文件

cp -r/usr/local/src/haproxy-1.7.7/examples/errorfiles/ /usr/local/haproxy/

 

日志文件

mkdir-p /usr/local/haproxy/log

touch/usr/local/haproxy/log/haproxy.log

ln -s/usr/local/haproxy/log/haproxy.log /var/log/

chownhaproxy:haproxy /var/log/haproxy.log

 

vim/etc/sysconfig/rsyslog

SYSLOGD_OPTIONS="-c2 -r -m 0"

 

cd/etc/rsyslog.d/

touchhaproxy.conf

chownhaproxy:haproxy haproxy.conf

vimhaproxy.conf

#  Provides UDP syslog reception

$ModLoad  imudp

$UDPServerRun  514

#  haproxy.log

#

local0.*  /usr/local/haproxy/log/haproxy.log

#local1.*  /usr/local/haproxy/log/haproxy.log

local2.*  /usr/local/haproxy/log/haproxy.log

&~

 

systemctlrestart rsyslog.service

#haproxy默认没有日志,依靠rsyslog收集日志;

#文件最末尾的“&~”,如果没有此配置,日志除写入指定文件外,会同步写入messages文件;

 

chown-R haproxy:haproxy /usr/local/haproxy/

mkdir-p /etc/haproxy

ln -s/usr/local/haproxy/etc/haproxy.cfg /etc/haproxy/

chown-R haproxy:haproxy /etc/haproxy

 

cp/usr/local/src/haproxy-1.7.7/examples/haproxy.init /etc/rc.d/init.d/haproxy

chownhaproxy:haproxy /etc/rc.d/init.d/haproxy

#/etc/rc.d/init.d/haproxy会有一个报错:

/etc/init.d/haproxy:line 26: [: =: unary operator expected

修改haproxy

vihaproxy

26行:

[[${NETWORKING} = "no" ]] && exit 0

 

chmod+x /etc/rc.d/init.d/haproxy

 

ln -s/usr/local/haproxy/sbin/haproxy /usr/sbin/

chownhaproxy:haproxy /usr/sbin/haproxy

 

启动haproxy

/etc/init.d/haproxystart

 

5     keepalived安装配置

5.1  实验环境

服务器角色

服务器IP

VIP1

192.168.8.100

LVS1

192.168.8.10

LVS2

192.168.8.11

(192.168.8.10和192.168.8.11)两台服务器操作

5.2  安装keepalived

yum install -y keepalived ipvsadm

5.3  配置keepalived

5.3.1     示例配置

vim/etc/keepalived/keepalived.conf

!  Configuration File for keepalived

 

global_defs  {

   notification_email {

     acassen@firewall.loc     #设置报警邮件地址,可以设置多个,每行一个。

     failover@firewall.loc      #需开启本机的sendmail服务

     sysadmin@firewall.loc

   }

   notification_email_from  Alexandre.Cassen@firewall.loc  #设置邮件的发送地址

   smtp_server 127.0.0.1        #设置smtp server地址

   smtp_connect_timeout 30    #设置连接smtp server的超时时间

   router_id LVS_DEVEL        #表示运行keepalived服务器的一个标识。发邮件时显示在邮件主题的信息

}

 

vrrp_instance  VI_1 {

state BACKUP              #指定keepalived的角色,MASTER表示此主机是主服务器,BACKUP表示此主机是备用服务器,但主挂了之后,再恢复会导致抢资源现象。所以这边都设置BACKUP,为了防止抢资源。

    interface eth0           #指定HA监测网络的接口

    virtual_router_id 51      #虚拟路由标识,这个标识是一个数字,同一个vrrp实例使用唯一的标识。即同一vrrp_instance下,MASTER和BACKUP必须是一致的

    priority 100              #定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级

advert_int 1              #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒

nopreempt                        #不抢占资源,意思就是它活了之后也不会再把主抢回来

    authentication {          #设置验证类型和密码

        auth_type PASS        #设置验证类型,主要有PASS和AH两种

        auth_pass 1111        #设置验证密码,在同一个vrrp_instance下,MASTER与BACKUP必须使用相同的密码才能正常通信

    }

    virtual_ipaddress {       #设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个

        192.168.8.97

    }

}

 

virtual_server  192.168.8.97 3306 {  #设置虚拟服务器,需要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开

    delay_loop 6              #设置运行情况检查时间,单位是秒

    lb_algo rr                #设置负载调度算法,这里设置为rr,即轮询算法

    lb_kind DR                #设置LVS实现负载均衡的机制,有NAT、TUN、DR三个模式可选

    nat_mask 255.255.255.0

    persistence_timeout 50    #会话保持时间,单位是秒。这个选项对动态网页是非常有用的,为集群系统中的session共享提供了一个很好的解决方案。有了这个会话保持功能,用户的请求会被一直分发到某个服务节点,直到超过这个会话的保持时间。需要注意的是,这个会话保持时间是最大无响应超时时间,也就是说,用户在操作动态页面时,如果50秒内没有执行任何操作那么接下来的操作会被分发到另外的节点,但是如果用户一直在操作动态页面,则不受50秒的时间限制

    protocol TCP              #指定转发协议类型,有TCP和UDP两种

 

    real_server 192.168.8.90 3306 { #配置服务节点1,需要指定real server的真实IP地址和端口,IP与端口之间用空格隔开

        weight 1              #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值大小可以为不同性能的服务器。分配不同的负载,可以为性能高的服务器设置较高的权值,而为性能较低的服务器设置相对较低的权值,这样才能合理地利用和分配系统资源

        TCP_CHECK {           #realserver的状态检测设置部分,单位是秒

            connect_timeout 3    #表示3秒无响应超时

            nb_get_retry 3        #表示重试次数

            delay_before_retry 3  #表示重试间隔

            connect_port 3306   #健康检查端口

        }

    }

    real_server 192.168.8.91 3306 {  #配置服务节点1,需要指定real server的真实IP地址和端口,IP与端口之间用空格隔开

        weight 1                 #配置服务节点的权值,权值大小用数字表示,数字越大,权值越高,设置权值大小可以为不同性能的服务器。分配不同的负载,可以为性能高的服务器设置较高的权值,而为性能较低的服务器设置相对较低的权值,这样才能合理地利用和分配系统资源

        TCP_CHECK {             #realserver的状态检测设置部分,单位是秒

            connect_timeout 3    #连接超时时间

            nb_get_retry 3        #重连次数

            delay_before_retry 3  #表示重试间隔

            connect_port 3306    #健康检查端口

        }

    }

}

 

5.3.2     生产配置

LVS-DR-Master上,其配置如下(192.168.8.10操作):

!  Configuration File for keepalived

 

global_defs  {

   notification_email {

     acassen@firewall.loc

     failover@firewall.loc

     sysadmin@firewall.loc

   }

   notification_email_from  Alexandre.Cassen@firewall.loc

   smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}

 

vrrp_instance  VI_1 {

    state BACKUP

    interface ens160

    virtual_router_id 51

    priority 100

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 123456

    }

    virtual_ipaddress {

        192.168.8.100

    }

}

 

virtual_server  192.168.8.100 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    nat_mask 255.255.255.0

    persistence_timeout 50

    protocol TCP

 

    real_server 192.168.8.12 80 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 80

        }

    }

 

    real_server 192.168.8.13 80 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 80

        }

    }

}

 

virtual_server  192.168.8.100 21 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    nat_mask 255.255.255.0

    persistence_timeout 50

    protocol TCP

 

    real_server 192.168.8.12 21 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 21

        }

    }

 

    real_server 192.168.8.13 21 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 21

        }

    }

}

 

LVS-DR-Backup上,其配置如下(192.168.8.11操作):

!  Configuration File for keepalived

 

global_defs  {

   notification_email {

     acassen@firewall.loc

     failover@firewall.loc

     sysadmin@firewall.loc

   }

   notification_email_from  Alexandre.Cassen@firewall.loc

    smtp_server 192.168.200.1

   smtp_connect_timeout 30

   router_id LVS_DEVEL

}

 

vrrp_instance  VI_1 {

    state BACKUP

    interface ens160

    virtual_router_id 51

    priority 90

    advert_int 1

    authentication {

        auth_type PASS

        auth_pass 123456

}

     virtual_ipaddress {

        192.168.8.100

    }

}

 

virtual_server  192.168.8.100 80 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    nat_mask 255.255.255.0

    persistence_timeout 50

    protocol TCP

 

    real_server 192.168.8.12 80 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 80

        }

    }

 

    real_server 192.168.8.13 80 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 80

        }

    }

}

 

virtual_server  192.168.8.100 21 {

    delay_loop 6

    lb_algo rr

    lb_kind DR

    nat_mask 255.255.255.0

    persistence_timeout 50

    protocol TCP

 

    real_server 192.168.8.12 21 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 21

        }

    }

 

    real_server 192.168.8.13 21 {

        weight 1

        TCP_CHECK {

            connect_timeout 3

            nb_get_retry 3

            delay_before_retry 3

            connect_port 21

        }

    }

}

 

5.4  虚拟IP脚本

haproxy服务器(192.168.8.12和192.168.8.13)操作

chmod+x /etc/rc.d/init.d/functions

vi/usr/local/bin/realserver.sh

#!/bin/bash

#description:  Config realserver

 

VIP=192.168.8.100

 

/etc/rc.d/init.d/functions

 

case  "$1" in

start)

       /sbin/ifconfig lo:0 $VIP netmask  255.255.255.255 broadcast $VIP

       /sbin/route add -host $VIP dev lo:0

       echo "1"  >/proc/sys/net/ipv4/conf/lo/arp_ignore

       echo "2"  >/proc/sys/net/ipv4/conf/lo/arp_announce

       echo "1"  >/proc/sys/net/ipv4/conf/all/arp_ignore

       echo "2"  >/proc/sys/net/ipv4/conf/all/arp_announce

       sysctl -p >/dev/null 2>&1

       echo "RealServer Start OK"

       ;;

stop)

       /sbin/ifconfig lo:0 down

       /sbin/route del $VIP >/dev/null  2>&1

       echo "0"  >/proc/sys/net/ipv4/conf/lo/arp_ignore

       echo "0"  >/proc/sys/net/ipv4/conf/lo/arp_announce

       echo "0"  >/proc/sys/net/ipv4/conf/all/arp_ignore

       echo "0"  >/proc/sys/net/ipv4/conf/all/arp_announce

       echo "RealServer Stoped"

       ;;

*)

       echo "Usage: $0 {start|stop}"

       exit 1

esac

 

exit  0

启动脚本

/usr/local/bin/realserver.shstart

 

5.5  启动keepalived

LVS-DR-Master(192.168.8.12)和LVS-DR-Backup(192.168.8.13)分别操作:

/etc/init.d/keepalivedstart

通过ipvsadm -L命令查看VIP是否能成功映射到后端服务。如果失败了,可通过/var/log/messages日志定位keepalived启动失败的原因。

IPVirtual Server version 1.2.1 (size=4096)

ProtLocalAddress:Port Scheduler Flags

  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

TCP  test1:ftp rr persistent 50

  -> 192.168.8.12:ftp            Route   1     0          0        

  -> 192.168.8.13:ftp            Route  1      0          0        

TCP  test1:http rr persistent 50

  -> 192.168.8.12:http           Route   1     0          0        

  -> 192.168.8.13:http           Route   1     0          0