nginx 无法在一个子域上运行多个NodeJ服务器

cbwuti44  于 2023-03-01  发布在  Nginx
关注(0)|答案(3)|浏览(153)

我正在尝试运行多个NodeJs服务器(官方)Kik聊天机器人与不同的webhook从一个子域在我的网络服务器。
然而,我不能这样做。对于一个机器人来说,它工作得很好。这是我对一个工作的NodeJs服务器的设置:
假设所有webhook都位于https://bots.mydomain.com
app.js:

'use strict';
let util = require('util');
let http = require('http');
let request = require('request');
let Bot = require('@kikinteractive/kik');
let bot = new Bot({
    username: "foo",
    apiKey:   "bar",
    baseUrl:  "https://bots.mydomain.com"
});
bot.updateBotConfiguration();

// ... code ...

let server = http.createServer(bot.incoming()).listen(process.env.PORT || 8080);

所以Nodejs服务器基本上是监听8080端口的,所以我对https://bots.mydomain.com站点的nginx配置如下所示:

server {
    root /var/www/bots.mydomain.com/public_html;
    index index.php index.html index.htm;
    server_name bots.mydomain.com;
    location / { proxy_pass http://localhost:8080/; } # Port 8080
}

到目前为止一切顺利。这一切都很好!但问题来了:
如果我尝试运行多个NodeJs服务器,通过在public_html文件夹中创建目录,比如/bot1/bot2,并像这样修改我的nginx配置:

server {
    root /var/www/bots.mydomain.com/public_html;
    index index.php index.html index.htm;
    server_name bots.mydomain.com;
    location /bot1 { proxy_pass http://localhost:8080/; } # Port 8080
    location /bot2 { proxy_pass http://localhost:8090/; } # Port 8090
}

最后设置第二个服务器监听端口8090而不是8080,当然,将基本URL设置为https://bots.mydomain.com/bot1https://bots.mydomain.com/bot2,什么都不起作用。我的意思是,webhook不向NodeJs服务器传递任何数据。不管怎么跑!我知道这一点是因为如果我导航到(例如)当机器人离线时,我显然收到错误502 Bad Gateway,但如果机器人是在线我得到一个超时(这意味着服务器确实在侦听)。
我错过了什么或Nginx只是不允许多个webhook或proxy_passes的目录?
一个变通的方法是为每个机器人创建一个子域,这是可行的(我试过了),但是我想为机器人使用子目录而不是子域。

    • 编辑**:

我注意到一个奇怪的行为:如果我为/设置一个proxy_pass
例如:location / { proxy_pass http://localhost:8080; }
连接到端口8080并将bot1脚本中的baseurl设置为bots.mydomain.com/bot1,Bot-1将正常工作。
但显然我仍然无法让其他机器人也工作,因为我使用的是根(/)。
这是否意味着Kik-API的监听方式有问题?

    • 编辑2**:

我现在检查了Nginx日志,似乎Kik Wrapper试图监听一个不存在的目录。我做了以下操作:在端口8080上启动bot并发送消息。这是日志输出:
https://pastebin.com/7G6TViHM

2017/04/13 09:07:05 [error] 15614#15614: *1 open() "/var/www/bots.mydomain.com/public_html/incoming" failed (2: No such file or directory), client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "POST /incoming HTTP/1.1", host: "bots.mydomain.com"
2017/04/13 09:07:13 [error] 15614#15614: *1 open() "/var/www/bots.mydomain.com/public_html/incoming" failed (2: No such file or directory), client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "POST /incoming HTTP/1.1", host: "bots.mydomain.com"

但我仍然不知道如何修复这个问题。作为测试,我在public_html中创建了目录incoming。这在日志中返回了以下内容:

2017/04/13 09:32:41 [error] 15614#15614: *10 directory index of "/var/www/bots.mydomain.com/public_html/incoming/" is forbidden, client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "GET /incoming/ HTTP/1.1", host: "bots.mydomain.com"

有人知道怎么修吗?

p1iqtdky

p1iqtdky1#

我认为您的问题在于proxy_pass中的尾部斜杠,它删除了传递到上游的/bot1/bot2前缀(仅用/替换这两个前缀),因此,nodejs代码中的每个bot都有一个不匹配的baseUrl设置(正如您提到的,您确实适当地更改了这些设置以匹配外部URL)。

-location /bot1 { proxy_pass http://localhost:8080/; } # Port 8080
-location /bot2 { proxy_pass http://localhost:8090/; } # Port 8090
+location /bot1 { proxy_pass http://localhost:8080; } # Port 8080
+location /bot2 { proxy_pass http://localhost:8090; } # Port 8090
pgx2nnw8

pgx2nnw82#

如果有人遇到这个问题:
Kik的API设计不可能做到这一点。
当您使用初始化机器人时

let bot = new Bot({
    username: "foo",
    apiKey:   "bar",
    baseUrl:  "https://bots.mydomain.com"
});

这个baseUrl本质上是一个webhook,不能被重用。2它必须是唯一的。
一种可能的解决方法是直接在base-url中指定端口。

d6kp6zgx

d6kp6zgx3#

它可能不起作用,因为您的目标服务器获得的路径包含/bot1/bot2前缀,这可能是它们所不期望的。
不妨试试:

location /bot1 {
    rewrite ^/bot1/(.*)$ /$1 break;
    proxy_pass http://localhost:8080/;

}
location /bot2 {
    rewrite ^/bot2/(.*)$ /$1 break;
    proxy_pass http://localhost:8090/;
}

相关问题