负载均衡

  • 高可用就是为了避免单节点故障的

  • 如果保证了机器不会坏,但是访问量特别大的话,就需要负载均衡了,多弄几台机器接收请求即可

nginx,反向代理做负载均衡,七层的负载均衡

lvs 也是做负载均衡的,但是机器不能超过100台,开源的四层负载均衡

haproxy也可以做负载均衡,七层的负载均衡

一、nginx部署LB集群

  • 通过代理功能实现负载均衡

1、代理

1、正向代理

  • 代理的是客户端,客户端直接访问代理服务器,然后找到对应的服务器

  • 服务端不知道实际发起请求的客户端

  • 代替客户端发送请求

  • 就是自己使用vpn这个代理,代理自己的电脑(客户端)可以访问外网

  • 正向代理允许客户端通过它访问任意网站并且隐蔽客户端自身,因此你必须采取安全措施来确保仅为经过授权的客户端提供服务

  • 正向代理是客户端访问代理服务器去访问目标服务器,并且对目标服务器隐藏了客户端的真实信息(IP等信息)

# 也就是通过这个跳板可以访问外网

# 代理的是客户端,为客户端收发请求

# 对于服务端而言,真正的客户端不可见,因为是通过代理服务器来实现的访问


2、反向代理

  • 代理的是服务端

  • 客户端直接访问代理服务器,然后

  • 客户端不知道实际提供服务的服务端

  • 代替服务端接收请求

  • 可以用于负载均衡

  • 对外是透明的,访问者并不知道自己访问的是代理。对访问者而言,他以为访问的就是原始服务器

# 代理的是服务端

# 为服务端收发请求

# 客户端访问代理服务器 (接收了客户端的请求)

# 然后发送到任意一台服务端上面,发送给代理服务器(接收服务端的信息)

# 代理服务器实现了收发作用

# 最后返回给客户端

# 后台真实的服务器是不可见的


img

3、应用

  • 公司使用的内网的话,有一个代理服务器

  • 这个代理服务器连接着内网和外网

2、环境准备

  • 四台虚拟机

  • 三台网站服务器,一个nginx代理服务器

  • 代理服务器上面有2张网卡,一个内网的,一个外网的

  • 客户端

# 三个服务器的ip地址为
192.168.200.61 62 63

# 代理服务器地址为
192.168.200.11(内网地址)

192.168.100.90 (外网地址)


1、配置服务器

  • 首先安装httpd软件,编写三个页面

2、配置代理服务器

  • 安装nginx软件,yum安装和源码包安装都可以

  • 修改nginx配置文件

  • 跟server是同一级的

[root@proxy nginx]# grep -Ev '^$|#' nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}

  • 下面是修改好的配置文件
[root@proxy nginx]# grep -Ev '^$|#' nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    worker_connections 1024;
}
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    include /etc/nginx/conf.d/*.conf;
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
        include /etc/nginx/default.d/*.conf;
        location / {
		root html;
		index index.html,index.htm;
		proxy_pass http://webgroup;   # 配置的反向代理,将接收到的访问网站的请求发送到webgroup的服务器组,也就是后台代理的几个服务器

}
        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
   upstream webgroup {  # 配置代理的后台服务器
	server 192.168.200.61:80;
	server 192.168.200.62:80;
	server 192.168.200.63:80;
}
}

# 检查配置文件语法
[root@proxy nginx]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful


# 重启nginx服务


3、客户端测试

# 这样就实现了负载均衡
# 轮询
[root@proxy nginx]# curl 192.168.100.90
61
[root@proxy nginx]# curl 192.168.100.90
62
[root@proxy nginx]# curl 192.168.100.90
62
[root@proxy nginx]# curl 192.168.100.90
63
[root@proxy nginx]# curl 192.168.100.90
63


  • 当然,也可以将proxy_pass 的参数改为 baidu.com,这样访问代理服务器就相当于是访问百度了

proxy_pass https://www.baidu.com;

3、nginx支持的调度算法

  • 轮询,默认算法

  • LC 最少连接调度

  • ip hash 基于源地址的哈希值选择合适服务器,ip地址不变的话,就一直发送给这个服务器

# 买东西的服务器是10,就一直发送给这个服务器即可

   upstream webgroup {
        ip_hash;
        server 192.168.200.61:80;
        server 192.168.200.62:80;
        server 192.168.200.63:80;
}

# 访问的时候,基于ip_hash算法算的

# 访问的总是一个服务器,因为ip地址没有变


# 就不会轮询了,第一次访问的是哪个服务器,后续就会一直访问了

  • ip_hash 算法,购物的时候,2个服务器,我收藏了一个衣服,这个就建立了一个连接a,,收藏了一个鞋子,又建立了一个连接,b,结账的时候,就又建立了一个连接a

  • 这样的话,总价钱不一样,因此就需要这个ip_hash算法,买东西的时候,都建立在同一个连接上,然后结账就算出总结的

  • 保持同一会话

4、设置服务器组中服务器的状态

  • max_conns最大的连接数

1、down状态

  • 设置服务器状态为down,nginx不会发送到请求给它

  • 维修的时候用的

   upstream webgroup {
        server 192.168.200.61:80;
        server 192.168.200.62:80 down;
        server 192.168.200.63:80;
}

# 这样nginx就不会发送请求给62服务器了


2、backup状态

  • 当集群服务器出现问题的了时候,backup状态的机器才会发送作用
   upstream webgroup {
        server 192.168.200.61:80;
        server 192.168.200.62:80 backup;
        server 192.168.200.63:80 backup;
}


# 当61服务器出现了故障,才会使用backup状态的机器

3、max_fails和fail_timeout

  • 用于健康检查,其中max_fails表示nginx对后端服务器请求失败的次数,默认值为1

  • 如果1次失败后,nginx就会在fail_timeout设定的时间内,不会将请求转发到这个服务器,在fail_timeout时间后,nginx会把新的请求转发到这个服务器,如果还没有恢复正常,继续在fail_timeout时间内,不会转发到这个服务器里面

   upstream webgroup {
        server 192.168.200.61:80;
        server 192.168.200.62:80 max_conns=100;
        server 192.168.200.63:80 max_fails=1 fail_timeout=300;
}

4、slow_start

  • 用于健康检查,当集群有服务器在等待fail_timeout后,nginx检查到服务器恢复后,仍不会发送到这个服务器上,而是等待slow_start指定时间后,才发送请求到服务器上面

  • 避免服务器恢复后,有大量的请求分发

  • 这个参数写着,有语法错误,好像只能商业版使用才可以

5、weight

  • 访问的权重
   upstream webgroup {
        server 192.168.200.61:80 weight=3;
        server 192.168.200.62:80 max_conns=100;
        server 192.168.200.63:80 max_fails=1 fail_timeout=300 ;
}

# 数字越大,接收的访问就越多

二、haproxy部署LB集群

1、haproxy介绍

  • 支持四层和七层的负载均衡

  • 支持acl功能,访问控制

  • 支持图形化监控

  • 多种调度算法

2、算法介绍

3、主配置文件

4、haproxy部署LB实验

1、环境准备

  • 四台网站服务器,一个代理服务器
# 61 62 63 64

# 代理服务器 80

  • 四个网站服务器编辑网站页面

2、proxy服务器配置

[root@proxy haproxy]# yum -y install haproxy.x86_64 


[root@proxy haproxy]# cat haproxy.cfg 
#---------------------------------------------------------------------
# Example configuration for a possible web application.  See the
# full configuration options online.
#
#   https://www.haproxy.org/download/1.8/doc/configuration.txt
#
#---------------------------------------------------------------------

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    user        haproxy
    group       haproxy
    daemon
    maxconn     4000

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    retries                 3
    timeout http-request    5s
    timeout queue           1m
    timeout connect         5s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 5s
    timeout check           5s
    maxconn                 3000

frontend main
    bind *:80
    default_backend         http_back

backend http_back
    balance     roundrobin
    server  node1 127.0.0.1:5001 check
    server  node2 127.0.0.1:5002 check
    server  node3 127.0.0.1:5003 check
    server  node4 127.0.0.1:5004 check(做健康检查,default里面有配置的)
[root@proxy haproxy]# 


frontend main  # haproxy的名字,可以修改
    bind *:80  # 监听后端服务器的端口都是80
    default_backend         http_back # 监听到了请求,将请求发送给这个工作组


backend http_back
    balance     roundrobin  # 调度算法,轮询
    server  node1(网站服务器起的名字) 127.0.0.1:5001 check
    server  node2 127.0.0.1:5002 check
    server  node3 127.0.0.1:5003 check
    server  node4 127.0.0.1:5004 check

  • 修改好的配置文件
frontend main
    bind *:80
    default_backend         http_back

backend http_back
    balance     roundrobin
    server  node1 192.168.200.61:80 check
    server  node2 192.168.200.62:80 check
    server  node3 192.168.200.63:80 check
    server  node4 192.168.200.64:80 check

  • 启动服务
[root@proxy haproxy]# systemctl restart haproxy.service 

[root@proxy haproxy]# netstat -pant|grep haproxy
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2563/haproxy   


3、客户端测试

  • 访问代理服务器

  • 80主机上面的80端口,读取自己的配置文件,然后发送给http_back这个服务器组

  • 也就是分发给后台的服务器

[root@proxy haproxy]# curl 192.168.200.80
63
[root@proxy haproxy]# curl 192.168.200.80
64
[root@proxy haproxy]# curl 192.168.200.80
61
[root@proxy haproxy]# curl 192.168.200.80
62


5、haproxy通过acl实现业务分离

  • 把客户端的请求发送给后端不同的服务器组做负载均衡处理

  • 四台服务器分成2个工作组

  • 访问html请求由61,62处理

  • 访问.php(动态请求)交给63,64处理

  • 因此就需要配置不同的页面

  • 可以控制请求访问到指定的服务器,静态的页面访问指定服务器,动态请求访问指定服务器

1、配置nginx解析php脚本

# 停止 63 64 apache服务

# 配置63,64 nginx网站

# 实现对php脚本解析

# 允许访问index.php
        location / {
            root   html;
            index  index.php index.html index.htm;
        }

# 取消注释
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            include        fastcgi.conf;
        }

# 64服务器也是这样配置的

# 安装软件包
[root@httpd-63 yum.repos.d]# yum -y install php php-devel php-fpm

# 修改这个文件下的监听的方式,改为监听9000端口
[root@httpd-63 php-fpm.d]# pwd
/etc/php-fpm.d

 38 ;listen = /run/php-fpm/www.sock
 39 listen = 127.0.0.1:9000

# 启动php-fpm服务

[root@httpd-63 php-fpm.d]# netstat -pant|grep 9000
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      3748/php-fpm: maste 

# 编写php页面

[root@httpd-63 html]# pwd
/usr/share/nginx/html
[root@httpd-63 html]# cat index.php 
<?php
echo "192.168.200.63\n";
?>

# 64也是这样的


2、编写网站页面

# 61 62 服务器配置除了首页文件之外的a.html

# 但是内容不一样
[root@httpd-62 html]# cat a.html 
62 a

# 63 64 服务器配置其他的.php页面

[root@httpd-63 html]# cat a.php 
<?php
echo "63 a \n";

?>

3、haproxy配置acl

  • 当有多个acl的时候,通过名字来进行区分
frontend main
    bind *:80
    default_backend         http_back

    acl htmlpage(取的名字) path_end(基于文件后缀来进行匹配)  .html  (匹配的.html页面) 
    acl phppage path_end .php

    use_backend htmlweb if htmlpage  # 匹配到了htmlpage的请求的话,转发给 htmlweb这个服务器组
    use_backend phpweb if phppage

# curl localhost  的请求转发给 61 62 服务器
backend http_back  
   balance     roundrobin
   server  node1 192.168.200.61:80 check
   server  node2 192.168.200.62:80 check

# curl localhost/a.html 请求转发给 61 62 服务器
backend htmlweb
    balance     roundrobin
    server  node1 192.168.200.61:80 check
    server  node2 192.168.200.62:80 check

# curl localhost/a.php 请求转发给 63 64 服务器
backend phpweb
    balance     roundrobin
    server  node3 192.168.200.63:80 check
    server  node4 192.168.200.64:80 check


4、客户端测试

[root@proxy haproxy]# curl localhost
61
[root@proxy haproxy]# curl localhost
62
[root@proxy haproxy]# curl localhost/a.html
61 a
[root@proxy haproxy]# curl localhost/a.html
62 a
[root@proxy haproxy]# curl localhost/a.php
64 a 
[root@proxy haproxy]# curl localhost/a.php
63 a 

5、要点

  • acl有多个匹配规则,上面的path_end是根据文件名后缀来进行匹配的

  • 还有基于以下的方式

    • 基于 IP 地址的 ACL

    • 基于 URL 路径的 ACL

    • 基于端口的 ACL

    • 基于请求头的 ACL

    • 等等

posted @ 2025-06-14 15:53  乔的港口  阅读(34)  评论(0)    收藏  举报