Nginx反向代理及负载均衡

Nginx反向代理及负载均衡

  • 实验环境

    • 四台虚拟机

      IP 说明
      172.25.254.101 nginx负载均衡器
      172.25.254.102 客户端
      172.25.254.103 web服务器1
      172.25.254.104 web服务器2

一、nginx反向代理

1.1 nginx反向代理原理

​ 反向代理服务器架设在服务器端,通过缓冲经常被请求的页面来缓解服务器的工作量,将客户机请求转发给内部网络上的目标服务器;并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器与目标主机一起对外表现为一个服务器。

Nginx 反向代理的原理是将客户端的请求转发到后端真实服务器,并将后端服务器的响应返回给客户端,同时对客户端隐藏后端服务器的真实信息。以下是其详细原理:

  • 客户端发起请求:客户端向 Nginx 反向代理服务器发送请求,请求中包含目标 URL 等信息。
  • Nginx 接收请求:Nginx 监听在特定的端口上,接收客户端的请求。它会根据配置文件中的规则来判断如何处理该请求。
  • 请求匹配与转发:Nginx 根据配置的虚拟主机、域名、URL 路径等规则,将请求匹配到对应的后端服务器组。然后,Nginx 会选择一台后端服务器,并将请求转发给它。
  • 后端服务器处理请求:后端服务器接收到 Nginx 转发的请求后,进行相应的处理,如查询数据库、执行应用程序逻辑等,生成响应数据。
  • Nginx 接收后端服务器响应:后端服务器将响应数据发送给 Nginx。
  • Nginx 将响应返回给客户端:Nginx 接收后端服务器的响应后,根据配置进行一些额外的处理,如添加响应头、缓存响应等,然后将响应数据返回给客户端。

通过以上过程,Nginx 作为反向代理服务器,充当了客户端和后端服务器之间的中间桥梁,实现了对后端服务器的负载均衡、缓存加速、安全防护等功能,同时提高了系统的性能和可扩展性。

1.2 nginx反向代理配置

  • 安装nginx

    复制代码
    ## 在nginx负载均衡器和服务器三台机器上分别安装nginx
    [root@Rocky ~]# dnf install nginx -y
  • 配置用于测试的Web服务(以下操作在两台web服务器)

    复制代码
    ## 创建日志文件目录
    [root@Rocky ~]# mkdir -p /usr/share/nginx/html/{www,bbs}/logs
    [root@Rocky ~]# cd /etc/nginx/conf.d/
    [root@Rocky conf.d]# vim vhost.conf
    [root@Rocky conf.d]# cat vhost.conf
    server {
    		listen 80;
    		server_name bbs.yunjisuan.com;
    		location / {
    				root /usr/share/nginx/html/bbs;
    				index index.html index.htm;
    		}
    		access_log /usr/share/nginx/html/bbs/logs/access_bbs.log main;
    }
    server {
    		listen 80;
    		server_name www.yunjisuan.com;
    		location / {
    				root /usr/share/nginx/html/www;
    				index index.html index.htm;
    		}
    		access_log /usr/share/nginx/html/www/logs/access_www.log main;
    }
    ## 检查是否有语法错误
    [root@Rocky conf.d]# nginx -t
    [root@Rocky conf.d]# echo "`hostname -I ` . www" > /usr/share/nginx/html/www/index.html
    [root@Rocky conf.d]# echo "`hostname -I ` . bbs" > /usr/share/nginx/html/bbs/index.html
    
    ## 启动服务测试
    [root@Rocky conf.d]# systemctl start nginx
    [root@Rocky ~]# curl -H host:bbs.yunjisuan.com 172.25.254.103
    172.25.254.103 . bbs
    [root@Rocky ~]# curl -H host:bbs.yunjisuan.com 172.25.254.104
    172.25.254.104 . bbs
    [root@Rocky ~]# curl -H host:www.yunjisuan.com 172.25.254.104
    172.25.254.104 . www
    [root@Rocky ~]# curl -H host:www.yunjisuan.com 172.25.254.103
    172.25.254.103 . www

二、nginx负载均衡

Nginx 通过反向代理实现负载均衡,客户端的请求先到达 Nginx,Nginx 依据配置规则,把请求转发给不同的后端服务器,并将处理结果返回给客户端。其采用多进程 + 异步非阻塞 I/O 事件模型,能高效处理大量并发请求。

2.1 nginx模块

​ Nginx的负载均衡功能依赖于ngx_http_upsteam_module模块,所支持的代理方式包括proxy_pass,fastcgi_pass,memcached_pass等,新版Nginx软件支持的方式有所增加。本文主要讲解proxy_pass代理方式。ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应Upstream组的名字上,具体写法为"proxy_pass http:// www_server_pools",其中www_server_pools就是一个Upstream节点服务器组名字。ngx_http_upstream_module模块官方地址为:http://nginx.org/en/docs/http/ngx_http_upstream_module.html。

  • 示例1:基本的upstream配置案例

    复制代码
    upstream www_server_pools {
    #upstream是关键字必须有,后面的www_server_pools为一个Upstream集群组的名字,可以自己起名,调用时就用这个名字
    	server 172.25.254.223:80 weight=5;
    	server 172.25.254.224:80 weight=10;
    	server 172.25.254.225:80 weight=15;
    #server关键字是固定的,后面可以接域名(门户会用)或IP。如果不指定端口,默认是80端口。weight代表权重,数值越大被分配的请求越多,结尾有分号。
    }
  • 示例2:较完整的upstream配置案例

    复制代码
    upstream www_server_pools {
    	server 172.25.254.223; #这行标签和下行是等价的
    	server 172.25.254.224:80 weight=1 max_fails=1 fail_timeout=10s; #这行标签和上一行是等价的,此行多余的部分就是默认配置,不写也可以。
    	server 172.25.254.225:80 weight=1 max_fails=2 fail_timeout=20s backup;
    # server最后面可以加很多参数,具体参数作用看下文的表格
    }
  • 示例3:使用域名及socket的upstream配置案例

    复制代码
    upstream backend {
    	server backend1.example.com weight=5;
    	server backend2.example.com:8080; #域名加端口。转发到后端的指定端口上
    	server unix:/tmp/backend3; #指定socket文件
    	#提示:server后面如果接域名,需要内网有DNS服务器或者在负载均衡器的hosts文件做域名解析。
    	server 172.25.254.223;
    	server 172.25.254.224:8080;
    	server backup1.example.com:8080 backup;
    	#备份服务器,等上面指定的服务器都不可访问的时候会启动,backup的用法和Haproxy中用法一样
    	server backup2.example.com:8080 backup;
    }
  • upstream参数

    复制代码
    server 10.0.10.8:80 	负载均衡后面的RS配置,可以是IP或域名,如果端口不写,默认是80端口。高并发场景下, IP可换成域名,通过 DNS做负载均衡。
    weigth=1 	代表服务器的权重,默认值是1。权重数字越大表示接受的请求比例越大。
    max_fails=3		Nginx尝试连接后端主机失败的次数,这个值是配合
    proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream	这三个参数来使用的。当nginx接收后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404、502、503、 Max_fails的默认值是1 ;企业场景下建议2-3次。如京东1次,蓝汛10次,根据业务需求去配置
    fail_timeout=10s	在max_fails定义的失败次数后,距离下次检查的间隔时间,默认是10s ;如果max_fails是5 ,它就检测5次,如果5次都是502,那么,它就会根据fail_timeout的值,等待10s再去检查,还是只检查一次,如果持续502,在不重新加载 Nginx配置的情况下,每隔10s都只检查一次。常规业务2~3秒比较合理,比如京东3秒,蓝汛3秒,可根据业务需求去配置。
    backup	热备配置(RS节点的高可用),当前面激活的RS都失败后会自动启用热备RS这标志看这个服务器作为备份服务器,若主服务器全部宕机了,就会向它转发请求。注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
    down 	这标志着服务器永远不可用,这个参数可配合ip_hash使用;类似与注释。

2.1 常用模块调度算法

  • 轮询(roundrobin):按顺序依次将请求分发到后端服务器,从第一台开始,到最后一台后再回到第一台,循环进行,不考虑服务器性能差异和负载情况,均等分配请求。
  • 加权轮询(weight):在轮询基础上,为各后端服务器设置权重,权重代表服务器处理请求的能力。权重越高,被分配到请求的概率越大,按权重比例分配请求,用于后端服务器性能不均衡场景。
  • IP 哈希(ip_hash):对客户端 IP 地址进行哈希运算,通过哈希值与后端服务器列表映射,使同一客户端的请求始终发往同一台后端服务器,以维持客户端会话状态。
  • 最少连接数(least_conn):将请求分配给当前连接数最少的后端服务器,实时监测服务器连接数,优先选择连接数少的服务器处理新请求,让负载更均衡,适合处理请求时间差异大的场景。
  • 基于响应时间的调度(fair):借助第三方模块实现,依据后端服务器的响应时间分配请求。响应时间短的服务器,接收新请求的概率高,能让客户端更快得到响应,适用于对响应时间要求高的应用。

2.3http_proxy_module模块

特性 详情
功能 用于将客户端请求转发到后端HTTP服务器,实现反向代理和负载均衡
指令
proxy_pass 指定后端服务器地址,可以是IP地址加端口,也可以是一个定义好的upstream组名。例如proxy_pass http://backend_server; ,其中backend_server可以是具体地址如192.168.1.100:8080,也可以是在upstream块中定义的服务器组。
proxy_set_header 设置转发到后端服务器的请求头。如proxy_set_header Host $host; ,将客户端请求中的Host头原封不动转发给后端服务器,还可自定义头信息,像proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;用于记录客户端真实IP。
proxy_connect_timeout 设置与后端服务器建立连接的超时时间。默认60秒,例如proxy_connect_timeout 30s; ,表示尝试连接后端服务器超过30秒未成功则连接失败。
proxy_read_timeout 设置从后端服务器读取响应的超时时间。默认60秒,即如果在这个时间内没有从后端服务器读取到任何数据,连接将被关闭,如proxy_read_timeout 90s;
proxy_send_timeout 设置向后端服务器发送请求的超时时间。默认60秒,若在该时间内没有成功将请求数据发送到后端服务器,连接将被关闭,如proxy_send_timeout 45s;
proxy_buffer_size 设置用于读取后端服务器响应头的缓冲区大小。默认与proxy_buffers中的一个缓冲区大小相同,可根据实际情况调整,如proxy_buffer_size 128k;
proxy_buffers 设置用于读取后端服务器响应正文的缓冲区数量和大小。例如proxy_buffers 4 256k;表示设置4个大小为256KB的缓冲区。
proxy_busy_buffers_size 设置处于繁忙状态(正在被读取或写入)的缓冲区最大大小。默认值是proxy_buffers中两个缓冲区的大小,如proxy_busy_buffers_size 512k;
proxy_temp_path 设置临时文件存储路径,用于存储在处理大文件上传或响应时产生的临时数据。例如proxy_temp_path /var/tmp/nginx_proxy;
工作机制 客户端向Nginx发起请求,Nginx根据配置的proxy_pass指令将请求转发到后端服务器。在转发过程中,可通过proxy_set_header等指令修改请求头信息。Nginx等待后端服务器响应,根据设置的各种超时指令控制连接和数据传输的时间。响应数据返回后,Nginx根据缓冲区相关指令处理响应数据,再返回给客户端。
应用场景 广泛应用于Web服务器集群,实现反向代理和负载均衡,隐藏后端服务器真实IP,提升安全性;还可用于缓存加速,将频繁访问的内容缓存到Nginx,减少后端服务器压力。
  • 示例1:将匹配URI为name的请求抛给http://127.0.0.1/remote/.

    复制代码
    location /name/ {
    	proxy_pass http://127.0.0.1/remote/;
    }
  • 示例2:将匹配URI为some/path的请求抛给http://127.0.0.1

    复制代码
    location /some/path/ {
    	proxy_pass http://127.0.0.1;
    }
  • 示例3:将匹配URI为name的请求应用指定的rewrite规则,然后抛给http://127.0.0.1

    复制代码
    location /name/ {
    	rewrite /name/( [^/]+ ) /username=$1 break;
    	proxy_pass http://127.0.0.1;
    }

2.4 nginx负载均衡配置:

  • web服务器配置如上

  • 配置nginx负载均衡器

    复制代码
    [root@Rocky ~]# /etc/nginx/conf.d
    [root@Rocky conf.d]# vim vhost.conf
    upstream www_server_pools {
            server 172.25.254.103;	#默认监听端口80
            server 172.25.254.104;
    }
    server {
            listen 80;
            server_name www.yunjisuan.com;
            location / {
                    proxy_pass http://www_server_pools;
                    proxy_set_header Host $host;
                    proxy_set_header X-Forwarded-For $remote_addr;
            }
    }
    server {
            listen 80;
            server_name bbs.yunjisuan.com;
            location / {
                    proxy_pass http://www_server_pools;
                    proxy_set_header Host $host;
                    proxy_set_header X-Forwarded-For $remote_addr;
            }
    }
    [root@Rocky conf.d]# nginx -t
    [root@Rocky conf.d]# nginx -s reload
  • 在客户端测试

    复制代码
    ## 配置host解析
    [root@Rocky ~]# vim /etc/hosts
    172.25.254.101 bbs.yunjisuan.com www.yunjisuan.com
    [root@Rocky ~]# for ((i=1;i<=4;i++)); do curl http://bbs.yunjisuan.com; done
    172.25.254.103 . bbs
    172.25.254.104 . bbs
    172.25.254.103 . bbs
    172.25.254.104 . bbs
    [root@Rocky ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
    172.25.254.103 . www
    172.25.254.104 . www
    172.25.254.103 . www
    172.25.254.104 . www
    ## 从上面的测试结果可以看出来。两个Web节点按照1:1的比例被访问。
    ## 下面宕掉任意一个Web节点,看看测试结果如何,测试如下
    ## 在172.25.254.103主机上停止nginx服务
    [root@Rocky conf.d]# systemctl stop nginx
    ## 继续测试
    [root@Rocky ~]# for ((i=1;i<=4;i++)); do curl http://www.yunjisuan.com; done
    172.25.254.104 . www
    172.25.254.104 . www
    172.25.254.104 . www
    172.25.254.104 . www
    [root@Rocky ~]# for ((i=1;i<=4;i++)); do curl http://bbs.yunjisuan.com; done
    172.25.254.104 . bbs
    172.25.254.104 . bbs
    172.25.254.104 . bbs
    172.25.254.104 . bbs
  • 由于添加proxy_set_header X-Forwarded-For $remote_addr,我们可以在web服务器的日志上查看真实访问ip

    复制代码
    [root@Rocky ~]# tail -3 /usr/share/nginx/html/www/logs/access_www.log
    172.25.254.101 - - [17/Mar/2025:17:34:08 +0800] "GET / HTTP/1.0" 200 21 "-" "curl/7.61.1" "172.25.254.102"
    172.25.254.101 - - [17/Mar/2025:17:34:08 +0800] "GET / HTTP/1.0" 200 21 "-" "curl/7.61.1" "172.25.254.102"
    172.25.254.101 - - [17/Mar/2025:17:34:08 +0800] "GET / HTTP/1.0" 200 21 "-" "curl/7.61.1" "172.25.254.102"
    [root@Rocky ~]# tail -3 /usr/share/nginx/html/bbs/logs/access_bbs.log
    172.25.254.101 - - [17/Mar/2025:17:34:15 +0800] "GET / HTTP/1.0" 200 21 "-" "curl/7.61.1" "172.25.254.102"
    172.25.254.101 - - [17/Mar/2025:17:34:15 +0800] "GET / HTTP/1.0" 200 21 "-" "curl/7.61.1" "172.25.254.102"
    172.25.254.101 - - [17/Mar/2025:17:34:15 +0800] "GET / HTTP/1.0" 200 21 "-" "curl/7.61.1" "172.25.254.102"
相关推荐
JZC_xiaozhong1 分钟前
单一主数据系统 vs. 统一主数据中心,哪种更优?
大数据·运维·企业数据管理·主数据管理·mdm管理·数据孤岛解决方案·数据集成与应用集成
一直走下去-明7 分钟前
docker简单使用
运维·docker·容器
三块钱079411 分钟前
ubuntu22.04 安装Jitsi meet 开源会议系统,代替腾讯会议
linux·运维·服务器·腾讯会议·会议系统·jitis meet
多多*41 分钟前
JavaEE企业级开发 延迟双删+版本号机制(乐观锁) 事务保证redis和mysql的数据一致性 示例
java·运维·数据库·redis·mysql·java-ee·wpf
浩特-ht1 小时前
Linux 下 FTP 工具的安装和使用方式详解:附服务器文件备份实战
linux·运维·服务器
kcarly1 小时前
超融合服务器与普通服务器的具体区别
运维·服务器·超融合
玩电脑的辣条哥1 小时前
AI-Sphere-Butler之Ubuntu服务器如何部署Nginx代理,并将HTTP升级成HTTPS,用于移动设备访问
服务器·nginx·ubuntu·http·https·aispherebutler
Zack No Bug1 小时前
Linux CentOS7 安装emqx详细教程
linux·运维·服务器·mqtt
MingDong5232 小时前
移动WiFi设备品牌推荐与选购指南
运维·服务器
下北泽天使3 小时前
linux的权限管理
linux·运维·服务器