Nginx 反向代理

通过 Nginx 代理,可以为项目配置域名,解决跨域问题,将请求转发到国外服务器等。在这里总结几个使用场景。

Nginx 安装

推荐宝塔安装和配置 Nginx,比较简单。
判断 Nginx 是否安装完成

1
2
3
4
5
# 检查Nginx状态
service nginx status
# 查看nginx版本
nginx -v

手动安装 Nginx
Ubuntu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 安装
sudo apt-get update
sudo apt-get install nginx

# 配置文件一般位于 `/etc/nginx/nginx.conf` 或 `/usr/local/nginx/conf/nginx.conf`
vim /etc/nginx/sites-available/default

# 添加一个 server block,其中server_name 为域名 proxy_pass 中指定项目的端口
server {
listen 80;
server_name flyrr.cc;
location / {
proxy_pass http://localhost:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

# 重启
sudo service nginx restart

CentOS

1
2
3
4
5
6
7
# 安装
sudo yum install nginx
# 修改配置文件
sudo nano /etc/nginx/nginx.conf
# 重启
sudo systemctl restart nginx

配置说明

在 nginx 中,有 http 块、server 块和 location 块,用于配置不同的内容。

  • http 块是 nginx 配置文件的最外层块,用于配置全局的参数,例如 worker_processes、events 等。在 http 块中,可以定义多个 server 块。
  • server 块用于配置虚拟主机,即一个 IP 地址下可以有多个域名,每个域名对应一个 server 块。在 server 块中,可以定义多个 location 块。
  • location 块用于配置请求的处理方式,例如是否启用缓存、是否启用反向代理等。在 location 块中,可以定义多个指令,例如 proxy_pass、root 等。

在 nginx 中,反向代理服务器可以指定 proxy_pass,将请求转发到上游服务器(目标地址),并将上游服务器的响应返回给客户端。

反向代理

解决跨域问题

跨域是指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 JavaScript 施加的安全限制。同源策略要求两个页面具有相同的协议、主机和端口,否则就会出现跨域。在实际开发中,如果我们需要从一个域名的网页去请求另一个域名的资源,就会发生跨域问题。比如,从 http://www.baidu.com/index.htmlhttp://www.google.com 发送一个 ajax 请求,就是跨域操作。
例如在实际开发中,我们的前端代码运行在 http://localhost:3000 上,而我们的后端代码运行在 http://localhost:5000 上。在这种情况下,我们需要通过跨域请求来访问后端 API。又比如,我们需要访问一个第三方 API,该 API 运行在不同的域名或不同的端口上。在这种情况下,浏览器会发出跨域请求,而服务器会拒绝该请求。为了解决这个问题,我们可以使用 Nginx 反向代理,避免跨域请求。

绑定域名

使用 proxy_pass 指令,通过域名访问服务器上的指定端口:
以 Flask 为例,为服务器上 Flask 项目的接口绑定一个二级域名 api.flyrr.cc,先在 DNS 服务商处将 api.flyrr.cc 的 A 记录解析到服务器 IP 地址。

将以 /api/ 开头的请求转发到 api 蓝图相关的视图函数路由:

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name api.flyrr.cc;

location /api/ {
proxy_pass http://127.0.0.1:5000/api;
}
}

或者转发所有路由

1
2
3
4
5
6
7
8
server {
listen 80;
server_name api.flyrr.cc;

location / {
proxy_pass http://127.0.0.1:5000/;
}
}

访问国外域名或接口

在香港服务器上配置 Nginx,将请求转发到谷歌服务器上,然后将响应返回给客户端。这样,客户端就可以通过香港服务器访问谷歌了。
以请求 openai 为例,首先要有一个可访问外网的服务器(比如香港)。
在宝塔创建一个网站(在宝塔中创建一个站点,实际上是在 nginx 配置文件中添加了一个 server 块),绑定域名或二级域名。修改网站的配置文件。

1
2
3
4
5
6
7
8
# 在server块中添加location,proxy_pass为目标域名
location / {
proxy_pass https://api.openai.com;
}

# 如若希望目标网站获得的请求IP是代理服务器的IP,而不是真实IP(防封号),在server添加
set_real_ip_from `香港服务器IP`;

例如:

1
2
3
4
5
6
7
8
9
location / {
proxy_pass https://api.openai.com/; # 反向代理到https://api.openai.com/这个地址
proxy_ssl_server_name on; # 开启代理SSL服务器名称验证,确保SSL连接的安全性
proxy_set_header Host api.openai.com; # 设置代理请求头中的Host字段为api.openai.com
chunked_transfer_encoding off; # 禁用分块编码传输,避免可能的代理问题
proxy_buffering off; # 禁用代理缓存,避免数据传输延迟
proxy_cache off; # 禁用代理缓存,确保实时获取最新的数据
#proxy_set_header X-Forwarded-For $remote_addr; # 将客户端真实IP添加到代理请求头中的X-Forwarded-For字段中,用于记录客户端真实IP
}

使用代理服务器请求 openai 接口容易 504 超时(无法在规定的时间内从上游服务器获得响应)

nginx 配置的默认超时时间是 60 秒,可以在代理服务器中增加上游服务器的超时时间提高容错率,在 Nginx 配置文件中添加 proxy_connect_timeoutproxy_send_timeoutproxy_read_timeout 这三个参数,并适当增加。配置文件通常在 /usr/local/nginx/conf/nginx.conf/etc/nginx/nginx.conf。或者从宝塔配置。

如果要在整个服务器上增加超时时间,可以将这些参数添加到 http 块中。如果要对特定的虚拟主机或网站设置超时时间,可以将这些参数添加到 server 块中。如果要对特定的 URL 或路径设置超时时间,可以将这些参数添加到 location 块中。

  • proxy_connect_timeout:与上游服务器建立连接的超时时间。
  • proxy_send_timeout:向上游服务器发送请求的超时时间。
  • proxy_read_timeout:从上游服务器读取响应的超时时间。单位都是秒
    如果超时,nginx 将会关闭与上游服务器的连接,并返回一个错误响应(504)。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    server {
    listen 80;
    server_name yourdomain.com;
    location / {
    proxy_pass https://www.google.com;
    proxy_connect_timeout 600;
    proxy_send_timeout 600;
    proxy_read_timeout 600;
    }
    }