Nginx:12---反向代理之(代理模块,代理单个上游服务器)

一、反向代理介绍

 

  • 反向代理应该是 Nginx 做的最多的一件事了,什么是反向代理呢,反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器, 并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器
  • 简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已

上游服务器

  • 上游服务器是 Nginx 代理连接的服务器,它可以是不同的物理机器,也可以是虚 拟机,但是并不是必须如此
  • 上游服务器可以是一个在本地机器上监听 UNIX 域套接字的 机器,也可能是 TCP 监昕的众多不同机器中的其中一员。它可能是拥有处理不同请求的多种模块的 Apache 服务器,或者是一个Rack 中间件服务器,为 Ruby 应用程序提供 HTTP 接口, Nginx 可以为它们配置代理
  • 上游服务器类型:
    • 单个上游服务器:本文介绍
    • 多个上游服务器:一般做复杂均衡,后面文章介绍
    • 非HTTP型上游服务器:后面文章介绍

二、代理模块

  • 下面列出了在代理模块中常用的命令

常用指令的值

location / {
    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 lOm;

    client_body_buffer_size 128k;
    proxy_connect_timeout 30 ;

    proxy_send_timeout 15 ;

    proxy_read_timeout 15;

    proxy_send_lowat 12000;

    proxy_buffer_size 4k;

    proxy_buffers 32 4k;

    proxy_busy_buffers_size 64k;

    proxy_temp_file_write_size 64k; 
}
  • 解释如下:
    • 因为在大多数情况下没有必要重写location 头,将 proxy_redirect 令设置为 off
    • 设置了 Host 头,因此上游服务器能够将请求映射到一个虚拟服务器,否则就使用 用户输入的 URL 中的主机部分
    • X-Real-IP 头和 X-Forwarded-For 头有相似的目的,都用于转发连接客户端 IP 地址 到上游服务器得到信息
    • $remote_addr 变量在 X-Real-IP 头内使用,就是 Nginx 接受客户端请求的田地址
    • $proxy_ add_ x _forwarded_ for 量包含在 X-Forwarded-For 头中,它来源于客户端 请求,跟随有$remote_addr变量
    • client_ max_ body_ size 指令,不是严格的代理模块指令。之所以在这里提到它,是 因为它与代理配置相关。如果这个值设置得太低,将不能上传文件到上游服务器 上。在设置这个指令的时候,需要注意的是通过 web 窗体上传的文件大小,通常要大于它在文件系统中的大小
    • 在建立与上游服务器初始连接的过程中, proxy connect_ timeout 指令表明了 Nginx 将会等待的时间长度
    • proxy _read_ timeout和proxy_send timeout 指令定义了 Nginx 上游服务器连接成功的两次操作等待的时间
    • proxy_ send _lowat 指令只在 FreeBSD 系统下有效,并且在该协议下传输数据之前 指定套接字发送缓冲应该容纳的字节数
    • proxy_ buffer_size、proxy_ buffer和proxy_busy_buffers_size令会在后面详细讨论。总而言之,这些缓冲控制了 Nginx 如何快速地响应用户的请求
    • proxy_ temp_ file_ write_ size 指令控制 worker 程阻塞后台数据的时间。值越大,处理阻塞的时间越长

三、代理上游服务器(proxy_pass指令)

  • 代理到上游服务器的配置中,最重要的是proxy_pass指令
  • 该指令有一个参数,URL请求将会被转换,带有URI部分的proxy_pass指令将会使用该URI替换request_uri部分
  • 例如:
    • 如果下面访问/some/path/,那么将访问www.example.com/link/
    • 如果下面访问/some/path/page.html,那么将访问www.example.com/link/page.html
http {
    server {
        location /uri {
            proxy_pass http://localhost:8080/newuri;
        }
    }
}

代理的两个例外情况

  • 例外1:
    • 如果location定义了一个正则表达式,那么在URI部分没有转换发生
    • 例如,下面的/local将被直接传递到上游服务器,而不会如期地转换为/foreign
location ~ ^/local {
    proxy_pass http://localgost:8080/foreign;
}
  • 例外2:
    • 如果在location内有rewrite规则改变了URI,那么Nginx使用这个URI处理请求,不再发生转换
    • 例如,下面URI传递到上游服务器的将会是/index.php?page=<match>,这个<match>来自于括号中捕获的参数,而不是预期的/index,如proxy_pass指令指示的URI部分
location / {
    # 在rewrite指令中,break标记用于立即停止rewrite模块的所有指令
    rewrite /(.*)$ /index.php?page=$1 break;

    proxy_pass http://localgost:8080/index;
}

四、传递请求标头(proxy_set_header指令)

  • 在使用代理服务器时,客户端不能直接连接到上游服务器。因此,上游服务器不能从客户端直接获取信息,那么此时可以使用proxy_set_header指令
  • proxy_set_header指令:该指令可以用来修改请求报文首部行中的字段的值,并且传递给上游服务器
  • 该指令可以在一个或多个位置(location)指定。它也可以在特定的server上下文或http块中指定
  • 例如:
    • 默认情况下,Nginx会重新定义代理请求报文中的“Host”和“Connection”两个头字段值,将“Host”设置为$proxy_host变量,“Connection”设置为关闭
    • 另外,Nginx还会消除值为空字符串的头字段
    • 那么,此时我们就可以使用proxy_set_header指令来重新修改头字段值,并传递给上游服务器
  • 演示案例:
    • 下面修改Host字段的值
    • 客户端IP地址会通过X-Real-IP头和X-Forwarded-For头来实现,其中X-Forwarded-For考虑到客户端的请求头,如果存在,那么从客户端请求来的IP地址将会添加到X-Forwarded-For中,并且使用逗号分隔
location /some/path/ {
    # Host字段的值用$host变量代替
    proxy_set_header Host $host;

    # X-Real-IP字段的值用$rempte_addr变量代替
    proxy_set_header X-Real-IP $rempte_addr;

    # X-Forwarded-For字段的值用&proxy_add_x_forwarded_for变量代替
    proxy_set_header X-Forwarded-For &proxy_add_x_forwarded_for;

    proxy_pass http://localhost:8000;
}
  • 演示案例:如果你的上游服务器需要一个非标准的头,例如Client-IP,那么可以通过下满的方式实现
location /some/path/ {
    proxy_set_header Client-IP $remote_addr;
}
  • 演示案例:为了防止头域被传递给代理服务器,可以将其设置为空字符串。例如:
location /some/path/ {
    proxy_set_header Accept-Encoding "";
    proxy_pass http://localhost:8000;
}

五、配置缓冲区

  • 默认情况下,Nginx缓存来自代理服务器的响应。 响应存储在内部缓冲区中,并且不会发送到客户端,直到收到整个响应。 缓冲有助于通过慢客户端优化性能,如果响应从Nginx同步传递到客户端,这可能会浪费代理服务器时间。 然而,当启用缓冲时,Nginx允许代理服务器快速处理响应,而Nginx存储响应时间与客户端需要下载的时间一样长
  • proxy_buffering指令:负责启用和禁用缓冲。 默认情况下,它被设置为开启且缓冲已启用
  • proxy_buffers指令:控制分配给请求的缓冲区的大小和数量。 来自代理服务器的响应的第一部分存储在单独的缓冲区中,其大小由 proxy_buffer_size指令设置。 这部分通常包含一个比较小的响应头,并且可以比其余的响应的缓冲区小
  • 在下面的示例中,缓冲区的默认数量增加,并且响应的第一部分的缓冲区的大小小于默认值
location /some/path/ {
    proxy_buffers 16 4k;
    proxy_buffer_size 2k;
    proxy_pass http://localhost:8000;
}
  • 如果缓存被禁用,则在从代理服务器接收缓冲时,响应将同步发送到客户端。 对于需要尽 快开始接收响应的快速交互式客户端,此行为可能是可取的。
  • 要禁用特定位置的缓冲,请在 location 块中将 proxy_buffering 伪指令设置为 off, 如下所示:
location /some/path/ {
    proxy_buffering off;
    proxy_pass http://localhost:8000;
}
  • 在这种情况下,Nginx只使用由 proxy_buffer_size 配置的缓冲区来存储响应的当前部分

六、选择传出IP地址

  • 如果你的代理服务器有多个网络接口,有时你可能需要选择特定的源IP地址才能连接到代理服务器或上游
  • proxy_bind指令:如果Nginx后端的代理服务器只配置为接受来自特定IP网络或IP地址范围的连接,在这种情况下,这个配置选项就很有用

演示案例

  • 下面指定必要网络接口的IP地址:
# 只接受127.0.0.1的连接请求
location /app1/ {
    proxy_bind 127.0.0.1;

    proxy_pass http://example.com/app1/;
}

# 只接受127.0.0.2的连接请求
location /app2/ {
    proxy_bind 127.0.0.2;

    proxy_pass http://example.com/app2/;
}
  • IP地址也可以用变量指定。例如,下面$server_addr变量传递接受请求的网络接口的IP地址
location /app3/ {
    proxy_bind $server_addr;

    proxy_pass http://example.com/app3/;
}

七、带有cookie的遗留应用程序

  • 你可能会发现,自己需要在一个共同的端点 务器后放置多个遗留应用程序。在它们是唯一应用程序的情况下,这些遗留应用程序是直接与客户端对话的。它们在自己的域设置了 cookies,并且假设它们总是通过/URL到达。如果在这些服务器之前放置一个新的端点,这些假设将不再成立。下面的配置将重写 cookie的域和路径,以便匹配新的应用 端点
server {
    server_name app.example.com;

    location /legacyl {
        proxy_cookie domain legacyl.example.com app.example.com;

        # 注意:这个$uri变量的值已经包含了一个开始的斜线(/),因此在这里就没有必要再次重复使用它了
        proxy_cookie_path $uri /legacy1$uri;

        proxy_redirect default;

        proxy_pass http://legacy1.example.com/;
    }

    location /legacy2 {
        proxy_cookie_domain legacy2.example.org app.example.com;

        proxy_cookie_path $uri /legacy2$uri ;

        proxy_redirect default;

        proxy_pass http://legacy2.example.org/;
    }

    location / {
        proxy_pass http://localhost:8080;
    }
}

八、处理错误

error_page指令

  • error_page指令在前面的文章中已经介绍过了,语法可以参阅:https://blog.csdn.net/qq_41453285/article/details/106321984
  • 当服务器有错误发生时,我们可以将请求转发到上游服务器,此时上游服务器充当着后备(fallback)服务器的角色,以便在其他服务器不能提供请求时再提供请求
  • 演示案例如下:
http {
    upstream app {
        server 127.0.0.1:9000;
        server 127.0.0.1:9001;
        server 127.0.0.1:9002;
    }

    server {
        location / {
            # 当有500、502、503、504错误发生时,跳转到fallback 块
            error_page 500 502 503 504 = @fallback;
            proxy_pass http:/app;
        }

        location @fallback {
            proxy_pass http://127.0.0.1:8080;
        }
    } 
}

proxy_intercept_errors指令

  • 如果启用该指令,Nginx将会显示配置的error_page错误,而不是来自于上游服务器的直接响应
server {
    proxy_intercept_errors on;

    error_page 400 403 404 /40x.html;

    location = /40x.html {
        root share/example/nginx/html;
    }
} 

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值