Loading

负载均衡与正反向代理

代理的方式

  • 正向代理:找完正向代理之后,还需要找服务器(无法直接访问到目标服务器)

    应用:V^P*N

    image

  • 反向代理:只需要找反向代理,不需要找服务器

    应用:负载均衡

    image

正向代理

代理的作用是将流量分配

  • Nginx代理服务支持的协议

    模块 代理语言
    ngx_http_uwsgi_module Python
    ngx_http_fastcgi_module PHP
    ngx_http_scgi_module Java
    ngx_http_v2_module Golang
    ngx_http_proxy_module HTTP
  • 代理实战

  • 部署web01-搭建马里奥小游戏

    [root@web01 conf.d]# vim Mario.conf 
    server{
        listen 80;
        server_name 192.168.15.7;
        location / {
        root /opt/Super_Mario;
            index index.html;
        }
        location ~ /images {
            root /opt/image;
        }
    }
    
  • 部署Lb01-Web01部署Nginx

    # 下载Nginx源代码包,yum安装不支持负载均衡
    [root@lb01 ~]# wget https://nginx.org/download/nginx-1.20.2.tar.gz
    
    # 解压
    [root@lb01 ~]# tar -xf nginx-1.20.2.tar.gz
    
    # 进入源代码目录
    [root@lb01 ~]# cd nginx-1.20.2
    
    # 安装依赖包
    [root@lb01 nginx-1.20.2]# yum install openssl openssl-devel zlib zlib-devel -y
    
    # 设置编译参数
    [root@lb01 nginx-1.20.2]# ./configure  --with-http_gzip_static_module    --with-stream     --with-http_ssl_module
    
    # 编译
    [root@lb01 nginx-1.20.2]# make 
    
    # 安装
    [root@lb01 nginx-1.20.2]# make install 
    
    # 优化
    [root@lb01 nginx]# mkdir /etc/nginx
    [root@lb01 nginx]# mv /usr/local/nginx/conf/* /etc/nginx/
    [root@lb01 nginx]# mkdir /etc/nginx/conf.d
    
    # 修改配置文件(拷贝以下web01的),统一内容
    [root@web01 ~]# cat /etc/nginx/nginx.conf
    # 拷贝到lb01配置文件中
    [root@lb01 nginx]# vim /etc/nginx/nginx.conf
    
    
    [root@lb01 nginx]# groupadd www -g 666
    [root@lb01 nginx]# useradd www -u 666 -g 666 -M -r -s /sbin/nologin
    
    [root@lb01 nginx]# vim /usr/lib/systemd/system/nginx.service
    [Unit]
    Description=nginx - high performance web server
    Documentation=http://nginx.org/en/docs/
    After=network-online.target remote-fs.target nss-lookup.target
    Wants=network-online.target
    
    [Service]
    Type=forking
    PIDFile=/var/run/nginx.pid
    ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
    ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)"
    ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)"
    
    [Install]
    WantedBy=multi-user.target
    
    [root@lb01 sbin]# ln -s /etc/nginx/nginx.conf /usr/local/nginx/conf/nginx.conf
    [root@lb01 sbin]# mv /usr/local/nginx/sbin/nginx /usr/sbin/
    # 重载 
    [root@lb01 sbin]# systemctl daemon-reload
    [root@lb01 sbin]# mkdir /var/log/nginx
    [root@lb01 sbin]# systemctl start nginx 
    # 查看模块
    [root@lb01 nginx]# nginx -V
    
  • 部署反向代理

    [root@lb01 conf.d]# vim /etc/nginx/conf.d/game.conf 
    server {
        listen 80;
        server_name _;
        location / {
            proxy_pass http://172.16.1.7:80;
        }
    }
    # 测试
    真机访问192.168.15.5(lb01)
    
    image
  • Nginx代理常用参数

    • 添加发往后端服务器的请求头信息

      通过tail -f /var/log/nginx/access.log监控日志,发现客户端ip是lb01的,通过以下三个参数修改就能记录真实的客户端ip

      Syntax:    proxy_set_header field value;
      Default:    proxy_set_header Host $http_host;
                  proxy_set_header Connection close;
      Context:    http, server, location
      
      # 用户请求的时候HOST的值是linux.proxy.com, 那么代理服务会像后端传递请求的还是linux.proxy.com
      proxy_set_header Host $http_host;
      # 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
      proxy_set_header X-Real-IP $remote_addr;
      # 客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      
      # 添加参数
      [root@lb01 nginx]# vim /etc/nginx/conf.d/game.conf
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://172.16.1.7:80;
              proxy_set_header Host $http_host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          }
      }
      [root@lb01 nginx]# nginx -t
      nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
      nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
      [root@lb01 nginx]# systemctl restart nginx 
      
      再次监控web01,发现真实ip为”xff”: "192.168.15.1"
    • 代理到后端的TCP连接、响应、返回等超时时间

      #nginx代理与后端服务器连接超时时间(代理连接超时)
      Syntax: proxy_connect_timeout time;
      Default: proxy_connect_timeout 60s;
      Context: http, server, location
      
      #nginx代理等待后端服务器的响应时间
      Syntax:    proxy_read_timeout time;
      Default:    proxy_read_timeout 60s;
      Context:    http, server, location
      
      #后端服务器数据回传给nginx代理超时时间
      Syntax: proxy_send_timeout time;
      Default: proxy_send_timeout 60s;
      Context: http, server, location
      
      # 添加以下参数
      proxy_connect_timeout 1s;   # 连接时间
      proxy_read_timeout 3s;     # 响应时间
      proxy_send_timeout 3s;     # 回传代理时间
      
      [root@lb01 nginx]# cat /etc/nginx/conf.d/game.conf
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://172.16.1.7:80;
              proxy_set_header Host $http_host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              # -----------------------------------------------------
              proxy_connect_timeout 1s;
              proxy_read_timeout 3s;
              proxy_send_timeout 3s;
          }
      }
      
    • proxy_buffer代理缓冲区

      代理缓冲区的存在增快了访问速度

      #nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端
      Syntax: proxy_buffering on | off;
      Default: proxy_buffering on;  
      Context: http, server, location
      
      #设置nginx代理保存用户头信息的缓冲区大小
      Syntax: proxy_buffer_size size;
      Default: proxy_buffer_size 4k|8k;
      Context: http, server, location
      
      #proxy_buffers 缓冲区
      Syntax: proxy_buffers number size;
      Default: proxy_buffers 8 4k|8k;
      Context: http, server, location
      
      proxy_buffering on; 
      proxy_buffer_size 8k;
      proxy_buffers 8 8k;
      
      # 添加参数
      proxy_buffering on;  # 打开缓冲区
      proxy_buffer_size 8k;   # 缓冲区大小,设置为8kb
      proxy_buffers 8 8k;   # 8个缓冲区,每个缓冲区8kb
      
      
      [root@lb01 nginx]# cat /etc/nginx/conf.d/game.conf
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://172.16.1.7:80;
              proxy_set_header Host $http_host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              # -----------------------------------------------------
              proxy_connect_timeout 1s;
              proxy_read_timeout 3s;
              proxy_send_timeout 3s;
              # ----------------------------------------------------
              proxy_buffering on;
              proxy_buffer_size 8k;
              proxy_buffers 8 8k;
          }
      }
      
    • 配置代理优化文件

      因为上面参数在配置的时候是不需要修改的,通过写入到文件内来优化

      [root@lb01 ~]# cd /etc/nginx/
      [root@lb01 ~]# vim /etc/nginx/proxy_params 
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_connect_timeout 10s;
      proxy_read_timeout 10s;
      proxy_send_timeout 10s;
      proxy_buffering on;
      proxy_buffer_size 8k;
      proxy_buffers 8 8k;
      
      # 编辑配置文件,通过添加外部配置文件-include,就不需要写上述的参数了
      [root@lb01 conf.d]# vim game.conf 
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://172.16.1.7:80;
              include /etc/nginx/proxy_params;
          }
      }
      
      # 测试
      通过监控进程来查看真实ip是否为本机访问的真实ip即可
      tail -f /var/log/nginx/access.log
      

反向代理(负载均衡)

可以拓展代理,使用负载均衡可以代理多个主机,

  • 负载均衡的架构

    通过代理将流量按照一定的比例,转发到后端。

  • 负载均衡的实现

    • 连接池

      将后端服务打包成一个IP连接池。
      
      1、反向代理格式
      server {
         listen 80;
         server_name _;
         location / {
              proxy_pass http://[连接池];
         }
      }
      
      2、IP连接池格式
      upstream [连接池名称] {
          server [ip]:[port];
          server [ip]:[port];
          server [ip]:[port];
      }
      
    • 实现步骤

      # 搭建
      web02和web03 用nginx搭建马里奥小游戏
      1、上传文件到/opt/目录下
      [root@web01 conf.d]# scp Super_Mario.tar.gz 172.16.1.8:/opt/
      [root@web01 conf.d]# scp Super_Mario.tar.gz 172.16.1.9:/opt/
      2、下载nginx : yum install nginx
      3、编辑配置文件:Mario.conf
      [root@web01 conf.d]# scp Mario.conf 172.16.1.8:/etc/nginx/conf.d/
      [root@web01 conf.d]# scp Mario.conf 172.16.1.9:/etc/nginx/conf.d/
      4、修改配置文件和web01统一
      [root@web01 conf.d]# scp /etc/nginx/nginx.conf 172.16.1.8:/etc/nginx/nginx.conf 
      [root@web01 conf.d]# scp /etc/nginx/nginx.conf 172.16.1.9:/etc/nginx/nginx.conf 
      5、web02和web03测试配置文件和重启服务
       nginx -t -c /etc/nginx/nginx.conf
       systemctl restart nginx 
      
      # lb01实现负载均衡
      6、创建连接池
      [root@lb01 conf.d]# vim /etc/nginx/conf.d/game.conf
      upstream supermarie {
          server 172.16.1.7:80;
          server 172.16.1.8:80;
          server 172.16.1.9:80;
      }
      
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://supermarie;
              include /etc/nginx/proxy_params;
          }
      }
      [root@lb01 conf.d]# nginx -t
      [root@lb01 conf.d]# systemctl restart nginx 
      # 测试真机访问lb01 ip
      
      image
  • 负载均衡的比例

    • 轮询

      # 通过web01字符显示示例
      [root@web01 Super_Mario]# echo Web01 > web.html
      [root@web01 Super_Mario]# echo Web02 > web.html
      [root@web01 Super_Mario]# echo Web03 > web.html
      # 默认情况下,Nginx负载均衡的轮询状态。
      upstream supermarie {
          server 172.16.1.7:80;
          server 172.16.1.8:80;
          server 172.16.1.9:80;
      }
      
    • 权重

      # Nginx中的权重0-100,数字越大,权重越高。
      upstream supermarie {
          server 172.16.1.7:80 weight=9;
          server 172.16.1.8:80 weight=5;
          server 172.16.1.9:80 weight=1;
      }
      # 这样web01获得流量分配的几率就大
      
    • ip_hash

      # 每一个IP固定访问某一个后端。
      upstream supermarie {
          server 172.16.1.7:80;
          server 172.16.1.8:80;
          server 172.16.1.9:80;
          ip_hash;
      }
      
      # 这样就固定访问web01服务器ip,172.16.1.7
      
  • 负载均衡后端状态

    状态 概述
    down 当前的server暂时不参与负载均衡
    backup 预留的备份服务器
    max_fails 允许请求失败的次数
    fail_timeout 经过max_fails失败后, 服务暂停时间
    • down

      # 暂时不分配流量
      upstream supermarie {
          server 172.16.1.7:80 down;
          server 172.16.1.8:80;
          server 172.16.1.9:80;
      }
      
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://supermarie;
              include /etc/nginx/proxy_params;
          }
      }
      # 这样172.16.1.7这个服务器暂时就不会分配流量,不参与负载均衡
      
    • backup

      # 只有当所有的机器全部宕机,才能启动。
      upstream supermarie {
          server 172.16.1.7:80 backup;
          server 172.16.1.8:80;
          server 172.16.1.9:80;
      }
      
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://supermarie;
              include /etc/nginx/proxy_params;
          }
      }
      
      # 这样只有web02和web03宕机了才会访问172.16.1.7服务器
      
    • max_fails、fail_timeout

      max_fails:允许请求失败的次数
      fail_timeout:经过max_fails失败后, 服务暂停时间
      # proxy_next_upstream 后端错误标识
      
      [root@lb01 ~]# cat /etc/nginx/conf.d/game.conf 
      upstream supermarie {
          server 172.16.1.7:80 max_fails=3 fail_timeout=3s;
          server 172.16.1.8:80 max_fails=3 fail_timeout=3s;
          server 172.16.1.9:80 max_fails=3 fail_timeout=3s;
      }
      
      server {
          listen 80;
          server_name _;
          location / {
              proxy_pass http://supermarie;
              proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_404; 
              include /etc/nginx/proxy_params;
          }
      }
      # 后端出现错误,会自动干掉服务,不会去访问
      

      proxy_next_upstream监控的错误类型

      # proxy_next_upstream可以指定的错误类型如下👇:
      
      error             # 与服务器建立连接,向其传递请求或读取响应头时发生错误;
      timeout           # 在与服务器建立连接,向其传递请求或读取响应头时发生超时;
      invalid_header    # 服务器返回空的或无效的响应;
      http_500          # 服务器返回代码为500的响应;
      http_502          # 服务器返回代码为502的响应;
      http_503          # 服务器返回代码为503的响应;
      http_504          # 服务器返回代码504的响应;
      http_403          # 服务器返回代码为403的响应;
      http_404          # 服务器返回代码为404的响应;
      http_429          # 服务器返回代码为429的响应(1.11.13);
      non_idempotent    # 通常,请求与 非幂等 方法(POST,LOCK,PATCH)不传递到请求是否已被发送到上游服务器(1.9.13)的下一个服务器; 启用此选项显式允许重试此类请求;
      off               # 禁用将请求传递给下一个服务器。
      
  • 负载均衡部署BBS

    • 部署后端服务

      • 部署Python

        web01、web02、web03部署,统一步骤

        1、创建用户
        [root@web01 opt]# groupadd django -g 888
        [root@web01 opt]# useradd django -u 888 -g 888 -r -M -s /bin/sh
        
        2、安装依赖软件
        [root@web01 opt]# yum install python3 libxml* python-devel gcc* pcre-devel openssl-devel python3-devel -y
        
        3、上传文件
        [root@web01 ~]# scp bbs.zip 172.16.1.8:/opt/
        [root@web01 ~]# scp bbs.zip 172.16.1.9:/opt/
        
      • 部署Django和uwsgi
        4、安装Django和uwsgi
        [root@web01 opt]# pip3 install django==1.11
        [root@web01 opt]# pip3 install uwsgi
        [root@web01 opt]# pip3 install pymysql
        
        5、创建项目
        [root@web01 opt]# unzip bbs.zip 
        [root@web03 bbs]# pwd
        /opt/bbs
        [root@web03 bbs]# vim bbs/settings.py 
        ALLOWED_HOSTS = ['*']
        DATABASES = {
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'bbs',
                'USER': 'root',
                'PASSWORD': '123456',
                'HOST': '172.16.1.61',
                'PORT': 3306,
                'CHARSET': 'utf8'
            }
        }
        
        # 启动测试
        [root@web01 bbs]# python3 manage.py runserver 0.0.0.0:8000
        # 注意数据库远程连接必须开启
        
      • 配置并启动uwsgi
        6、编辑项目配置文件
        [root@web01 bbs]# vim /opt/bbs/myweb_uwsgi.ini 
        [uwsgi]
        # 端口号
        socket            = :8000
        # 指定项目的目录
        chdir           = /opt/bbs
        # wsgi文件路径
        wsgi-file       = bbs/wsgi.py
        # 模块wsgi路径
        module          = bbs.wsgi
        # 是否开启master进程
        master          = true
        # 工作进程的最大数目
        processes       = 4
        # 结束后是否清理文件
        vacuum          = true
        
        7、启动uwsgi(在bbs目录测试)
        [root@web01 bbs]# uwsgi -d --ini myweb_uwsgi.ini --uid 666
        
        -d 	  : 以守护进程方式运行
        --ini : 指定配置文件路径
        --uid : 指定uid
        
        TCP 服务
        
        8、编辑Nginx配置文件
        [root@web01 ~]# vim /etc/nginx/conf.d/python.conf 
        server {
            listen 80;
            server_name py.test.com;
            location / { 
                include uwsgi_params;
                uwsgi_pass 127.0.0.1:8000;
                uwsgi_read_timeout 2;
                uwsgi_param UWSGI_SCRIPT bbs.wsgi;
                uwsgi_param UWSGI_CHDIR /opt/bbs;
                index  index.html index.htm;
                client_max_body_size 35m;
            }
        }
        
        9、测试且重启Nginx配置
        nginx -t
        systemctl restart nginx
        
    • 部署负载均衡

      [root@lb01 conf.d]# vim python.conf 
      upstream bbs {
          server 172.16.1.7:80 max_fails=3 fail_timeout=3s;
          server 172.16.1.8:80 max_fails=3 fail_timeout=3s;
          server 172.16.1.9:80 max_fails=3 fail_timeout=3s;
      }
      
      server {
          listen 80;
          server_name py.test.com;
          location / {
              proxy_pass http://bbs;
              proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_404; 
              include /etc/nginx/proxy_params;
          }
      }
      
      [root@lb01 conf.d]# nginx -t
      [root@lb01 conf.d]# systemctl restart nginx 
      
      # 域名解析
      windows下hosts文件
      # 注意连接池的名称不能相同,和其他的负载均衡连接池区分
      
      # 真机测试是否成功
      
      image
posted @ 2022-10-13 23:35  爱learn  阅读(86)  评论(0编辑  收藏  举报