V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
swordne
V2EX  ›  问与答

求教一个 nginx 的动态端口转发写法

  •  
  •   swordne · 311 天前 · 1772 次点击
    这是一个创建于 311 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有一个需求:
    a.b.com/10111/xxxxx
    a.b.com/10112/xxxxx
    a.b.com/10113/xxxxx

    nginx 需要根据里面的 10111/10112/10113 对应转发到:
    0.0.0.0:10111/0.0.0.0:10112/0.0.0.0:10113 上面,对应的 hyperf 服务。
    需要将 pathinfo 里的端口号获取然后自动转发到本机的端口里,nginx 能够实现么?

    因为多人测试共用一台服务器,每次新建项目都要手动配置,很麻烦,如果能够从 nginx 原生实现那么就不用单独去弄个管理器了。

    恳请大佬们赐教。T.T
    12 条回复    2023-06-21 17:43:32 +08:00
    taofoo
        1
    taofoo  
       311 天前
    如果就这几个端口的话,location 就可以
    nitmali
        2
    nitmali  
       311 天前
    location ^~ /10111/
    LLaMA2
        3
    LLaMA2  
       311 天前
    location 中有路径,匹配到转发不同的端口,和楼上说的一样
    swordne
        4
    swordne  
    OP
       311 天前
    @taofoo #1 不是,以后会有很多。想找个方法让 nginx 根据路由上的端口号自动转发到对应的本地,这样就可以让组内的小伙伴自由的起服务,我就不去动 nginx 配置了。
    swordne
        5
    swordne  
    OP
       311 天前
    @nitmali #2 端口号是可变、随机的。
    xiaokanhongchen
        6
    xiaokanhongchen  
       311 天前 via Android
    chatgpt 帮你实现了,转:
    是的,Nginx 可以实现这样的需求。您可以使用 Nginx 的反向代理和重写规则来实现将请求转发到相应的 Hyperf 服务的功能。

    首先,您需要在 Nginx 的配置文件中设置反向代理规则,并根据请求的路径重写 URL 。以下是一个示例配置:
    ```
    server {
    listen 80;
    server_name a.b.com;

    location / {
    rewrite ^/(\d+)/(.*)$ /$2 break;
    proxy_pass http://0.0.0.0:$1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    }
    }
    ```
    在这个配置中,正则表达式^/(\d+)/(.*)$会匹配类似于 /10111/xxxxx 的 URL 路径,并将 10111 提取出来作为参数。然后,rewrite 指令将路径重写为 /$2 ,其中$2 是匹配到的第二个组(即 xxxxx 部分)。接下来,proxy_pass 指令将请求代理到 http://0.0.0.0:$1 ,其中$1 是第一个组(即提取的端口号)。最后,proxy_set_header 指令设置一些代理请求的头部信息。

    请根据您的实际环境进行适当的修改,包括监听的端口号、服务器名称和 Hyperf 服务的地址。完成配置后,重新加载 Nginx 配置并启动服务,Nginx 将根据请求中的端口号将请求转发到相应的 Hyperf 服务上。
    xiaokanhongchen
        7
    xiaokanhongchen  
       311 天前 via Android
    自己试试,稍微改改就行
    swordne
        8
    swordne  
    OP
       311 天前
    @xiaokanhongchen #7 我来试试,之前也搜过这种答案,貌似不行,看看是不是有哪里不一样。
    XiFanL1
        9
    XiFanL1  
       311 天前
    完全动态的话会不会有安全风险,一些仅对内网开放端口是不是也可以通过这种方式访问
    swordne
        10
    swordne  
    OP
       311 天前
    @XiFanL1 #9 不好,1 是测试服务器,2 是开放的全部是 hyperf 的项目转发端口,3 是其实主要是省事,要不天天去服务器上弄太麻烦了,也有安全隐患。
    xixibb
        11
    xixibb  
       311 天前
    @xiaokanhongchen #6 哥,真的假的,GPT 这么牛逼了吗?
    swordne
        12
    swordne  
    OP
       311 天前
    已经可以了
    location /api/ {

    set $uri_parts '';
    if ($uri ~ "^/(?<uri_part1>[^/]+)/(?<uri_part2>[^/]+)/(?<param>.*)$") {
    set $uri_parts $uri_part1,$uri_part2;
    }

    proxy_pass http://0.0.0.0:$uri_part2/$param;
    }

    这样配置就可以完成转发了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   873 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 21:34 · PVG 05:34 · LAX 14:34 · JFK 17:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.