不能在一个子域上运行多个 NodeJs 服务器



我正在尝试为(官方)Kik聊天机器人运行多个NodeJs服务器,这些服务器具有来自我的网络服务器上一个子域的不同网络钩子。

但是,我无法做到这一点。对于一个机器人来说,它工作得很好。这是我仅针对一个工作 NodeJs 服务器的设置:

假设所有网络钩子都位于 https://bots.mydomain.com

应用.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,不再起作用了。我的意思是网络钩子不会将任何数据传递给 NodeJs 服务器。然而,他们正在奔跑!我知道这一点,因为如果我在机器人离线时导航到(例如)https://bots.mydomain.com,我显然会收到错误502 Bad Gateway但如果机器人在线,我会超时(这意味着服务器确实在侦听)。

我是否遗漏了某些内容,或者 Nginx 只是不允许目录的多个网络钩子或proxy_passes?

解决方法是为每个机器人创建一个子域,这将起作用(我试过了)。但我想为机器人使用子目录而不是子域。

编辑

我注意到一个奇怪的行为:如果我为/设置proxy_pass

喜欢:location / { proxy_pass http://localhost:8080; }

到端口 8080 并将 bot1 脚本中的 baseurl 设置为bots.mydomain.com/bot1,Bot-1 有效。

但我显然仍然无法让其他机器人正常工作,因为我使用的是根 (/)。

这是否意味着Kik-API的监听方式存在问题?

编辑2

我现在检查了Nginx日志,似乎Kik包装器试图监听不存在的目录。我做了以下操作:在端口8080上启动机器人并向其发送消息。这是日志输出:

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"

有没有人知道如何解决它?

我认为您的问题在于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

如果有人遇到这个问题:

Kik的API设计是不可能的。

使用 初始化机器人时

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

baseUrl本质上是一个 Webhook,不能重复使用。它必须有点独特。
一种可能的解决方法是直接在基 url 中指定端口。

它可能不会被唤醒,因为您的目标服务器获得的路径包含/bot1/bot2前缀,而它们可能没有预料到。

也许尝试:

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

相关内容

  • 没有找到相关文章

最新更新