Nginx 常用功能,反向代理笔记

前言

本文是runoob教程的搬运,稍微修改了原文中的一些错误拼写的问题,顺便对一些概念进行了更详细的解释,欢迎批评指正!


Nginx常用功能

  1. Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。

    这里我给来2张图,对正向代理与反向代理做个诠释,具体细节,大家可以翻阅下资料。

    Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。

  2. 负载均衡

    Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为轮询,加权轮询,Ip hash。扩展策略,就天马行空,只有你想不到的没有他做不到的啦,你可以参照所有的负载均衡算法,给他一一找出来做下实现。

    上3个图,理解这三种负载均衡算法的实现

    Ip hash算法,对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。

  3. Nginx配置文件结构

    如果你下载好啦,你的安装文件,不妨打开conf文件夹的nginx.conf文件,Nginx服务器的基础配置,默认的配置也存放在此。

    在 nginx.conf 的注释符号为: #

    nginx 文件结构:

    ...              #全局块
    
    events {         #events块
       ...
    }
    
    http      #http块
    {
        ...   #http全局块
        server        #server块
        { 
            ...       #server全局块
            location [PATTERN]   #location块
            {
                ...
            }
            location [PATTERN] 
            {
                ...
            }
        }
        server
        {
          ...
        }
        ...     #http全局块
    }
    
    • 全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
    • events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
    • http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
    • server块:配置虚拟主机的相关参数,一个http中可以有多个server。
    • location块:配置请求的路由,以及各种页面的处理情况。

    下面给大家上一个配置文件,作为理解。

    ########### 每个指令必须有分号结束。#################
    #user administrator administrators;  #配置用户或者组,默认为nobody nobody。
    #worker_processes 2;  #允许生成的进程数,默认为1
    #pid /nginx/pid/nginx.pid;   #指定nginx进程运行文件存放地址
    error_log log/error.log debug;  #制定日志路径,级别。这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg
    events {
        accept_mutex on;   #设置网路连接序列化,防止惊群现象发生,默认为on
        multi_accept on;  #设置一个进程是否同时接受多个网络连接,默认为off
        #use epoll;      #事件驱动模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
        worker_connections  1024;    #最大连接数,默认为512
    }
    http {
        include       mime.types;   #文件扩展名与文件类型映射表
        default_type  application/octet-stream; #默认文件类型,默认为text/plain
        #access_log off; #取消服务日志    
        log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定义格式
        access_log log/access.log myFormat;  #combined为日志格式的默认值
        sendfile on;   #允许sendfile方式传输文件,默认为off,可以在http块,server块,location块。
        sendfile_max_chunk 100k;  #每个进程每次调用传输数量不能大于设定的值,默认为0,即不设上限。
        keepalive_timeout 65;  #连接超时时间,默认为75s,可以在http,server,location块。
    
        upstream mysvr {   
          server 127.0.0.1:7878;
          server 192.168.10.121:3333 backup;  #热备
        }
        error_page 404 https://www.baidu.com; #错误页
        server {
            keepalive_requests 120; #单连接请求上限次数。
            listen       4545;   #监听端口
            server_name  127.0.0.1;   #监听地址       
            location  ~*^.+$ {       #请求的url过滤,正则匹配,~为区分大小写,~*为不区分大小写。
               #root path;  #根目录
               #index vv.txt;  #设置默认页
               proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表
               deny 127.0.0.1;  #拒绝的ip
               allow 172.18.5.54; #允许的ip           
            } 
        }
    }
    

    上面是nginx的基本配置,需要注意的有以下几点:

    • 几个常见配置项:

      • $remote_addr 与 $http_x_forwarded_for 用以记录客户端的ip地址;

      • $remote_user :用来记录客户端用户名称;

      • $time_local : 用来记录访问时间与时区;

      • $request : 用来记录请求的url与http协议;

      • $status : 用来记录请求状态;成功是200;

      • $body_bytes_s ent :记录发送给客户端文件主体内容大小;

      • $http_referer :用来记录从那个页面链接访问过来的;

      • $http_user_agent :记录客户端浏览器的相关信息;

    • 惊群现象:一个网路连接到来,多个睡眠的进程被同时叫醒,但只有一个进程能获得链接,这样会影响系统性能。

    • 每个指令必须有分号结束。

Nginx 反向代理与负载均衡详解

  1. 设置 404 页面导向地址
error_page 404 https://www.runnob.com; #错误页
proxy_intercept_errors on;    #如果被代理服务器返回的状态码为400或者大于400,设置的error_page配置起作用。默认为off。
  1. 如果我们的代理只允许接受get,post请求方法的一种
proxy_method get;    #支持客户端的请求方法。post/get;
  1. 设置支持的http协议版本
proxy_http_version 1.0 ; #Nginx服务器提供代理服务的http协议版本1.0,1.1,默认设置为1.0版本
  1. 如果你的nginx服务器给2台web服务器做代理,负载均衡算法采用轮询,那么当你的一台机器web程序iis关闭,也就是说web不能访问,那么nginx服务器分发请求还是会给这台不能访问的web服务器,如果这里的响应连接时间过长,就会导致客户端的页面一直在等待响应,对用户来说体验就打打折扣,这里我们怎么避免这样的情况发生呢。这里我配张图来说明下问题。

    如果负载均衡中其中web2发生这样的情况,nginx首先会去web1请求,但是nginx在配置不当的情况下会继续分发请求道web2,然后等待web2响应,直到我们的响应时间超时,才会把请求重新分发给web1,这里的响应时间如果过长,用户等待的时间就会越长。

    下面的配置是解决方案之一。

    proxy_connect_timeout 1;   #nginx服务器与被代理的服务器建立连接的超时时间,默认60秒
    proxy_read_timeout 1; #nginx服务器向被代理服务器组发出read请求后,等待响应的超时间,默认为60秒。
    proxy_send_timeout 1; #nginx服务器向被代理服务器组发出write请求后,等待响应的超时间,默认为60秒。
    proxy_ignore_client_abort on;  #客户端断网时,nginx服务器是否中断对被代理服务器的请求。默认为off。
    

    下面是对每个配置项的具体解释:

    proxy_connect_timeout 1;
    

    这个指令设置了Nginx与被代理服务器建立连接的超时时间,单位是秒。在你的例子中设置为1秒。这意味着如果Nginx在1秒内未能成功与后端服务器建立连接,它就会放弃尝试,并可能返回一个错误给客户端。默认值通常是60秒,所以这个设置显著缩短了等待时间,适合于对响应速度要求较高的场景。

    proxy_read_timeout 1;
    

    此指令定义了Nginx等待从后端服务器读取响应的超时时间,单位也是秒。在这个例子中设置为1秒。这表示一旦Nginx发送请求到后端服务器后,它会等待最多1秒钟来接收响应。如果在这段时间内没有收到任何数据,连接将被关闭。通常情况下,默认值是60秒,这样低的设置可能会导致一些正常的但响应较慢的操作失败。

    proxy_send_timeout 1;
    

    它指定了Nginx向后端服务器发送请求的超时时间,同样以秒为单位。这里设置为1秒。这个超时是在已经建立了连接之后,Nginx尝试发送请求到后端服务器的时间限制。如果在这个时间内无法完成请求的发送,连接将会被关闭。默认值同样是60秒。

    proxy_ignore_client_abort on;
    

    当设置为on时,即使客户端中断了请求(例如断网或主动取消),Nginx也会继续尝试完成对后端服务器的请求,而不是立即终止它。这对于某些需要确保操作完整性的应用场景非常有用。默认情况下,这个选项是off,即如果客户端中断请求,Nginx也会尝试中断对后端服务器的请求。

    综上所述,这些配置主要用于优化Nginx作为反向代理时的性能和可靠性,特别是当你希望快速响应用户请求或处理高并发量的情况下。不过需要注意的是,过于严格的超时设置(如这里的1秒)可能会导致正常请求因为短暂延迟而失败,因此应该根据实际情况调整这些参数。

  2. proxy_next_upstream指令,这个指令是Nginx中用于定义在遇到特定错误或异常情况时,如何将请求转发给upstream组中的下一个服务器的重要配置。这个指令允许你指定在哪些情况下尝试下一个服务器,从而提高系统的可靠性和容错能力。

    • proxy_next_upstream指令详解
      • timeout:当与后端服务器建立连接、发送请求或读取响应时发生超时时,Nginx会尝试将请求传递给upstream组中的下一个服务器。这对应于你在问题中提到的几种超时情况(如proxy_connect_timeout、proxy_read_timeout等)。
      • error:在建立连接、发送请求到被代理服务器或读取响应信息时如果发生错误(例如网络错误),Nginx会尝试将请求转发给下一个服务器。
      • invalid_header:如果从被代理服务器收到的响应头无效或无法解析,Nginx会尝试将请求转发给下一个服务器。
      • http_500 | http_502 | http_503 | http_504:这些选项分别对应于被代理服务器返回的HTTP状态码500(内部服务器错误)、502(错误网关)、503(服务不可用)和504(网关超时)。如果后端服务器返回了这些状态码之一,Nginx会尝试将请求转发给upstream组中的下一个服务器。
      • http_404:虽然不太常见于proxy_next_upstream中使用,但如果指定了,当后端服务器返回404(未找到)状态码时,Nginx也会尝试将请求转发给下一个服务器。
      • off:这个值不是一种错误条件,而是表示禁用此功能。如果设置为off,那么无论发生什么类型的错误,Nginx都不会尝试转发请求到下一个服务器。
  3. 如果你想通过http获取客户的真实ip而不是获取代理服务器的ip地址,那么要做如下的设置。

    proxy_set_header Host $host; #只要用户在浏览器中访问的域名绑定了 VIP VIP 下面有RS;则就用$host ;host是访问URL中的域名和端口  www.taobao.com:80
    proxy_set_header X-Real-IP $remote_addr;  #把源IP 【$remote_addr,建立HTTP连接header里面的信息】赋值给X-Real-IP;这样在代码中 $X-Real-IP来获取 源IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来,用 【,】隔开;代码中用 echo $x-forwarded-for |awk -F, '{print $1}' 来作为源IP
    

    这些指令用于配置Nginx作为反向代理时如何设置HTTP请求头,以便将客户端的真实信息传递给后端服务器。以下是对每个指令的详细解释:

    1. proxy_set_header Host $host;

      • 作用:这个指令设置了HTTP请求头中的Host字段。
      • 解释:
        • $host变量包含的是用户在浏览器中访问的域名和端口(如果没有指定端口,则使用默认端口,如HTTP为80,HTTPS为443)。
        • 当Nginx作为反向代理时,它会将原始请求中的Host头部信息传递给后端服务器。这样,后端服务器可以看到客户端实际请求的域名,而不是代理服务器的地址。
        • 例如,如果用户访问http://www.taobao.com:80,那么$host的值就是www.taobao.com。
    2. proxy_set_header X-Real-IP $remote_addr;

      • 作用:这个指令设置了自定义的HTTP请求头X-Real-IP。

      • 解释:

        • $remote_addr变量表示客户端的IP地址,即发起请求的实际用户的IP地址。

        • 这个指令将客户端的真实IP地址通过X-Real-IP头部传递给后端服务器。这样,即使请求经过了Nginx代理,后端服务器仍然可以获取到客户端的真实IP地址。后端应用代码中,可以通过读取X-Real-IP头部来获取客户端的真实IP地址。例如,在PHP中可以使用$_SERVER['HTTP_X_REAL_IP']

    3. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      • 作用:这个指令设置了标准的HTTP请求头X-Forwarded-For。

      • 解释:

        • $proxy_add_x_forwarded_for变量是一个特殊的变量,它会在现有的X-Forwarded-For头部基础上添加当前客户端的IP地址(即$remote_addr),并用逗号分隔。

        • 如果请求中已经存在X-Forwarded-For头部(通常是由于之前经过其他代理服务器),则新值会追加到现有值之后。否则,它会简单地设置为客户端的IP地址。

        • 这样做的目的是记录请求经过的所有代理服务器的IP地址以及客户端的真实IP地址。这对于需要追踪请求路径的应用非常有用。

Nginx 负载均衡详解

在文章Nginx 配置详解中我说啦nginx有哪些中负载均衡算法。这一结我就给如何操作配置的给大家做详细说明下。

首先给大家说下upstream这个配置的,这个配置是写一组被代理的服务器地址,然后配置负载均衡的算法。这里的被代理服务器地址有两种写法。

upstream mysvr {     server 192.168.10.121:3333;
    server 192.168.10.122:3333;
}
server {
    ....
    location  ~*^.+$ {                 proxy_pass  http://mysvr;  #请求转向mysvr 定义的服务器列表         }
}

然后,就来点实战的东西。

1、热备:如果你有2台服务器,当一台服务器发生事故时,才启用第二台服务器给提供服务。服务器处理请求的顺序:AAAAAA突然A挂啦,BBBBBBBBBBBBBB.....

upstream mysvr {     
server 127.0.0.1:7878;     
server 192.168.10.121:3333 backup;  #热备     }

2、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB....

upstream mysvr {     
    server 127.0.0.1:7878;
    server 192.168.10.121:3333;       
}

3、加权轮询:跟据配置的权重的大小而分发给不同服务器不同数量的请求。如果不设置,则默认为1。下面服务器的请求顺序为:ABBABBABBABBABB....

upstream mysvr {     
    server 127.0.0.1:7878 weight=1;
    server 192.168.10.121:3333 weight=2;
}

4、ip_hash:nginx会让相同的客户端ip请求相同的服务器。

upstream mysvr {     
    server 127.0.0.1:7878;     
    server 192.168.10.121:3333;
    ip_hash;
}

5、如果你对上面4种均衡算法不是很理解,可以查看Nginx 配置详解,可能会更加容易理解点。

到这里你是不是感觉nginx的负载均衡配置特别简单与强大,那么还没完,咱们继续哈,这里扯下蛋。

关于nginx负载均衡配置的几个状态参数讲解。

  • down,表示当前的server暂时不参与负载均衡。

  • backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。

  • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。

  • fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

upstream mysvr {     
    server 127.0.0.1:7878 weight=2 max_fails=2 fail_timeout=2;
    server 192.168.10.121:3333 weight=1 max_fails=2 fail_timeout=1;    
}

posted @ 2025-03-10 15:07  玉米面手雷王  阅读(141)  评论(0)    收藏  举报