不能在一个子域上 运行 多个 NodeJs 服务器
Cannot run multiple NodeJs server on one subdomain
我正在尝试 运行 多个 NodeJs 服务器用于(官方)Kik Chatbots,具有来自我的网络服务器上一个子域的不同 webhook。
但是,我做不到。对于一个机器人来说,它工作得很好。这是我仅针对 one 工作 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/bot1
或 https://bots.mydomain.com/bot2
,没有任何作用了。我的意思是 webhook 不会将任何数据传递给 NodeJs 服务器。然而,他们 运行ning!我知道这一点是因为如果我导航到(例如)https://bots.mydomain.com
而机器人处于 离线 ,我显然会收到错误 502 Bad Gateway
但如果机器人是 online 我超时了(这意味着服务器确实在监听)。
我是不是遗漏了什么,或者 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
上启动机器人并向其发送消息。这是日志输出:
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"
有没有人知道如何修复它?
它可能不起作用,因为您的目标服务器获得了包含 /bot1
和 /bot2
前缀的路径,这可能是他们不希望的。
也许试试:
location /bot1 {
rewrite ^/bot1/(.*)$ / break;
proxy_pass http://localhost:8080/;
}
location /bot2 {
rewrite ^/bot2/(.*)$ / break;
proxy_pass http://localhost:8090/;
}
我认为您的问题在于 proxy_pass
, which removes the /bot1
and /bot2
prefixes once passed to upstream (replacing both with mere /
), so, each bot
in your nodejs 代码中的尾部斜线导致 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 design 根本做不到。
当您使用
初始化您的机器人时
let bot = new Bot({
username: "foo",
apiKey: "bar",
baseUrl: "https://bots.mydomain.com"
});
这个 baseUrl
本质上是一个 webhook,不能重复使用。它必须有点独特。
一种可能的解决方法是直接在 base-url.
中指定一个端口
我正在尝试 运行 多个 NodeJs 服务器用于(官方)Kik Chatbots,具有来自我的网络服务器上一个子域的不同 webhook。
但是,我做不到。对于一个机器人来说,它工作得很好。这是我仅针对 one 工作 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/bot1
或 https://bots.mydomain.com/bot2
,没有任何作用了。我的意思是 webhook 不会将任何数据传递给 NodeJs 服务器。然而,他们 运行ning!我知道这一点是因为如果我导航到(例如)https://bots.mydomain.com
而机器人处于 离线 ,我显然会收到错误 502 Bad Gateway
但如果机器人是 online 我超时了(这意味着服务器确实在监听)。
我是不是遗漏了什么,或者 Nginx 只是不允许目录有多个 webhook 或 proxy_passes?
解决方法是为每个机器人创建一个子域,这会起作用(我试过)。但我想为机器人使用子目录而不是子域。
编辑:
我注意到一个奇怪的行为:如果我为 /
赞:location / { proxy_pass http://localhost:8080; }
到端口 8080 并将 bot1 脚本中的 baseurl 设置为 bots.mydomain.com/bot1
,Bot-1 工作。
但我显然仍然无法让其他机器人也能正常工作,因为我使用的是根目录 (/)。
这是否意味着 Kik-API 的聆听方式有问题?
编辑 2:
我现在检查了 Nginx 日志,Kik Wrapper 似乎试图监听一个不存在的目录。我执行了以下操作:在端口 8080
上启动机器人并向其发送消息。这是日志输出:
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"
有没有人知道如何修复它?
它可能不起作用,因为您的目标服务器获得了包含 /bot1
和 /bot2
前缀的路径,这可能是他们不希望的。
也许试试:
location /bot1 {
rewrite ^/bot1/(.*)$ / break;
proxy_pass http://localhost:8080/;
}
location /bot2 {
rewrite ^/bot2/(.*)$ / break;
proxy_pass http://localhost:8090/;
}
我认为您的问题在于 proxy_pass
, which removes the /bot1
and /bot2
prefixes once passed to upstream (replacing both with mere /
), so, each bot
in your nodejs 代码中的尾部斜线导致 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 design 根本做不到。
当您使用
初始化您的机器人时let bot = new Bot({
username: "foo",
apiKey: "bar",
baseUrl: "https://bots.mydomain.com"
});
这个 baseUrl
本质上是一个 webhook,不能重复使用。它必须有点独特。
一种可能的解决方法是直接在 base-url.