findxc / blog

88 stars 5 forks source link

测试了一下 NGINX proxy_pass 的用法 #82

Open findxc opened 1 year ago

findxc commented 1 year ago

NGINX 中的 proxy_pass 可以转发请求,文档见 https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

直接看测试结果

# 请求路径不变,直接转发, /api/a/b --> /api/a/b
location /api/ {
    proxy_pass http://fake-service.com:3000;
}

# 请求路径中的 /api/ 会被替换为空字符串, /api/a/b --> /a/b
location /api/ {
    proxy_pass http://fake-service.com:3000/;
}

# 请求路径中的 /api/ 会被替换为 /xxx/ , /api/a/b --> /xxx/a/b
location /api/ {
    proxy_pass http://fake-service.com:3000/xxx/;
}

本地测试环境搭建

因为 proxy_pass 文档上示例和解释较少,就想着干脆自己本地测试一下算了,跑一个后端服务,再跑一个 NGINX 就行了。

先参考 https://expressjs.com/en/starter/hello-world.html 用 express 启动一个后端服务。

// 文件名为 app.js ,然后 node app.js 即可启动
const express = require('express')
const app = express()
const port = 3000

// 匹配任意 GET 请求,会返回请求路径
app.get('*', function (req, res) {
  res.send({ text: 'hello world', path: req.url })
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

启动成功后访问 http://localhost:3000/api/a/b 会显示 path 为 /api/a/b

然后用 docker compose 来启动 NGINX ,需要本地先安装好 docker ,然后新建 docker-compose.yml ,内容如下:

# docker-compose.yml
services:
  web:
    container_name: my-nginx
    image: nginx:1.23.3
    ports:
      - 8080:80
    volumes:
      - ./conf.d:/etc/nginx/conf.d

再新建文件夹 conf.d ,在文件夹中新建文件 default.conf ,内容如下:

# conf.d/default.conf
server {
    listen      80;

    # /api1/a/b --> /api1/a/b
    location /api1/ {
        # 当希望访问宿主机上服务时,就用 host.docker.internal
        # 文档见 https://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms
        # We recommend that you connect to the special DNS name host.docker.internal which resolves to the internal IP address used by the host.
        # 我们刚才本地启动的 express 服务就是在 3000 端口上
        proxy_pass http://host.docker.internal:3000;
    }

    # /api2/a/b --> /a/b
    location /api2/ {
        proxy_pass http://host.docker.internal:3000/;
    }

    # /api3/a/b --> /xxx/a/b
    location /api3/ {
        proxy_pass http://host.docker.internal:3000/xxx/;
    }
}

执行 docker compose up -d 启动 NGINX ,然后访问 http://localhost:8080/api1/a/bhttp://localhost:8080/api2/a/bhttp://localhost:8080/api3/a/b 可以看到不同返回值。

PS:如果修改了 conf.d/default.conf 文件,需要执行 docker restart my-nginx 来让配置生效。如果要停止 NGINX 服务,执行 docker compose down

补充:NGINX 配置文件中怎么使用环境变量

实际使用时,需要转发的地址一般是定义在环境变量中的,参考 https://github.com/docker-library/docs/tree/master/nginx#using-environment-variables-in-nginx-configuration-new-in-119 处理即可。