Skip to content
标签
欢迎扫码关注公众号

Nginx 根据请求参数转发

今天在测试的时候有个需求:想根据 URL 中 query 参数访问不同的环境,另外页面发起的请求也可以根据 Header 中的参数反向代理到不同的环境的服务。

下面是基于 Docker compose 的示例。

示例代码

目录结构

my-project/
├── docker-compose.yml
├── nginx/
│   ├── nginx.conf
│   └── conf.d/
│       └── default.conf
├── backend-8080/
│   └── index.html
└── backend-8084/
    └── index.html
└── backend-test/
    └── index.html

docker-compose.yml

yaml
version: '3.8'

services:
  nginx:
    image: nginx:stable-alpine3.17-slim
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d/:/etc/nginx/conf.d/:ro
    depends_on:
      - backend-8080
      - backend-8084
      - backend-test

  backend-8080:
    image: nginx:stable-alpine3.17-slim
    volumes:
      - ./backend-8080/index.html:/usr/share/nginx/html/index.html:ro
    # 端口 8080 不需要暴露到主机,仅用于内部服务间通信(如果需要调试可以保留)
    # ports:
    #   - "8080:80"

  backend-8084:
    image: nginx:stable-alpine3.17-slim
    volumes:
      - ./backend-8084/index.html:/usr/share/nginx/html/index.html:ro
    # 端口 8084 不需要暴露到主机,仅用于内部服务间通信(如果需要调试可以保留)
    # ports:
    #   - "8084:80"

  backend-test:
    image: nginx:stable-alpine3.17-slim
    volumes:
      - ./backend-test/index.html:/usr/share/nginx/html/index.html:ro
    # 端口 8085 不需要暴露到主机,仅用于内部服务间通信(如果需要调试可以保留)
    # ports:
    #   - "8085:80"

nginx.conf

这个是 nginx 默认的配置文件,一般不需要修改。

nginx
user nginx;
worker_processes auto;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

conf.d/default.conf

这个是具体的转发配置,主要是通过 $arg_{query-key} 获取请求参数,通过 $http_{header-key} 获取请求头。

注意:并发量大的可能会对性能有一定的影响。

nginx
server {
    listen 80;

    location / {
        if ($arg_skuId = "1001") {
            proxy_pass http://backend-8084;
            break;
        }
        if ($arg_skuId = "1002") {
            return 302 http://www.liujiajia.me$is_args$args;
        }
        if ($http_x_env = "test") {
            proxy_pass http://backend-test;
            break;
        }

        proxy_pass http://backend-8080;
    }
}

另外两个 HTML 页面就随便写点文字,区分一下就可以了。

相关命令

启动:

bash
docker compose up -d

重启:

bash
docker compose restart

下面是可以通过 VS Code 插件 REST Client 测试用的示例:

http
### 8080
GET http://localhost/?a=1&b=2&skuId=1000

### 8084
GET http://localhost/?a=1&b=2&skuId=1001

### 302
GET http://localhost/?a=1&b=2&skuId=1002

### test
GET http://localhost/?a=1&b=2&skuId=1000
x-env: test