编程技术分享平台

网站首页 > 技术教程 正文

Nginx 备忘录 - 04. 反向代理与负载均衡

xnh888 2024-09-12 22:44:27 技术教程 26 ℃ 0 评论

一、什么是反向代理

通常的代理服务器,用于代理内部网络对 Internet 的连接请求,客户机将本来要直接发送到 Web 服务器的 Http 请求,先发送到代理服务器,由代理服务器在 Internet 上寻找 Web服务器并转发请求。普通的 Web 代理服务器不支持外部对内部网络的访问请求。

当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理。反向代理方式是指以代理服务器来接受 Internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 Internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。

二、配置反向代理

http {
  server {
    listen 80;
    server_name www.liwy-nginx.com;

    location / {
      # 配置要代理的服务器
      proxy_pass http://192.168.2.13;
      
      # 配置了代理 root与index就无意义了
      #root html;
      #index index.html index.htm;
    }
  }
}

通过 proxy_pass 设置代理服务器的协议与地址

Syntax:  proxy_pass URL;
Default: —
Context: location, if in location, limit_except

1. 如果 URL 中指定了 URI ,当请求传递给服务器时,与 location 匹配的请求 URI 部分将被该 proxy_pass 指定的 URI 替换:

location /name/ {
    proxy_pass http://192.168.2.13/remote/;
}
  • 请求的URL:http://www.liwy-nginx.com/name/param/get1
  • 转发的请求:http://192.168.2.13/remote/param/get1

2. 如果没有指定 URI,则原始请求的 URI 将完整的传递给服务器:

location /some/path/ {
    proxy_pass http://127.0.0.2;
}
  • 请求的URL:http://www.liwy-nginx.com/some/path/get1
  • 转发的请求:http://192.168.2.13/some/path/get1

三、配置负载均衡

http {
  # 定义服务器组 liwy_server
  upstream liwy_server {
    server 192.168.2.13:8081;
    server 192.168.2.13:8082;
  }

  server {
    listen 80;
    server_name www.liwy-nginx.com;

    location / {
      # 代理到指定的服务器组
      proxy_pass http://liwy_server;
    }
  }
}

我们可以在 upstream 模块中配置不同的负载均衡策略,常见的负载均衡策略如下:

1. 轮询策略

默认情况下使用轮询策略,将请求按顺序分发到服务器组,这种方式适用于无状态请求。如果 server 服务器 down 掉,能自动剔除。

# 简单的轮询策略
upstream liwy_server {
  server 192.168.2.10:80;
  server 192.168.2.11:80;
}

# 增加权重
upstream liwy_server {
  server 192.168.2.10:80 weight=7;
  server 192.168.2.11:80 weight=2 backup;
  server 192.168.2.12:80 weight=1 down;
}
  • weight :默认为 1,值越大则权重越大。
  • down :标记服务器不可用,即不参加负载。
  • backup :标记服务器为备用服务器,当主服务器不可用时,它才启用处理请求。
  • fail_timeout :与 max_fails 配合使用。在 fail_timeout 时间内,与服务器通信的尝试失败次数达到 max_fails,则认为服务器不可用;默认为 10 秒。
  • max_fails :与 fail_timeout 配合使用。表示在 fail_timeout 的时间内失败的尝试次数;默认为 1。

2. IP 哈希

根据客户端 IP 进行定向转发。

# IP 哈希策略
upstream liwy_server {
  ip_hash;
  server 192.168.2.10:80;
  server 192.168.2.11:80;
}
  • 此策略适合有状态服务,比如 session。

3. 最少连接

将新请求发送到当前客户端连接数最少的服务器。

# 最少连接策略
upstream liwy_server {
  least_conn;
  server 192.168.2.10:80;
  server 192.168.2.11:80;
}
  • 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。

4. 指定参数哈希

# 根据 URI 哈希
upstream liwy_server {
  hash $request_uri;
  server 192.168.2.10:80;
  server 192.168.2.11:80;
}

5. 最短时间

将新请求发送到响应时间最快的服务器。(第三方模块:nginx-upstream-fair)

upstream liwy_server {
  fair;
  server 192.168.2.10:80;
  server 192.168.2.11:80;
}

四、获取用户真实IP

未使用反向代理时,我们可以直接使用 remote_addr 来获取客户端 IP;但经过反向代理后,由于在客户端和后端服务器之间增加了 Nginx 代理层,因此后端服务器无法直接拿到客户端 IP,通过 remote_addr 拿到的将是后端服务器上层 Nginx 代理的 IP 地址。

首先我们先了解几个概念:

  • remote_addr:如果中间没有代理,就是客户端的真实IP,如果有代理,这就是上层代理的 IP;该值无法修改。
  • X-Forwarded-For:一个 HTTP 扩展头,格式为 X-Forwarded-For: clientIP, proxy1IP, proxy2IP
  • X-Real-IP:自定义的 HTTP 头,用于把客户端真实 IP 一层层传递下去。

我们可以通过这些 HTTP 头将用户真实 IP 传递到后端服务。

方案一,通过设置 X-Real-IP 层层传递:

# 首层代理中设置 X-Real-IP
proxy_set_header X-Real-IP $remote_addr;
# 非首层代理中将 X-Real-IP 传递下去
proxy_set_header X-Real-IP $http_x_real_ip; 

方案二,通过设置 X-Forwarded-For 请求头:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

$proxy_add_x_forwarded_for 变量由 X-Forwarded-For 头内容与 $remote_addr 组成,他们之间以逗号分隔。

每一层都增加该配置,这样逐层传递下去,X-Forwarded-For 中存储的就是请求经过的所有机器IP了,其中第一个就是客户真实IP。

需要注意的是,客户端是可以篡改 X-Forwarded-For 的值的,因此客端IP很容易被伪造,因此一般我们会在首层代理中使用 $remote_addr 来设置下 X-Forwarded-For 的值。

# 首层使用 $remote_addr 设置下 X-Forwarded-For,防篡改
proxy_set_header X-Forwarded-For $remote_addr;

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表