如何使用Restify在同一端口上运行多个Node应用程序?

时间:2016-03-21 18:44:10

标签: javascript node.js express restify pm2

我需要在同一个端口上运行多个Node应用程序。我发现我可以使用一个端口运行多个节点应用程序,这要归功于这个问题Running multiple Node (Express) apps on same port但它可能不适合我。除非我在某处做错了,否则我会使用Restify。

我已经使用使用Restify构建的PM2在一个端口上运行" app1" 。我已经制作了另一个应用" app2" 。路径是这样的:

/var/www/app1
/var/www/app2

每个应用都有这样的共同路线:

app.get('/', func...);
app.get('/about', func...);
app.post('/foo', func...);
app.post('/bar', func...);

我已将" app1" 的最后一行代码设置为:exports.app = app而不是app.listen(8080, function() { ... });

app

var app = restify.createServer({
    name: 'app1'
});

" app2" 也一样......

我的main.js文件(保存在/var/www/中)也建立在Restify上:

main
 .use('/app`', require('./app1/index').app)
.listen(8080);

其中main

var main = restify.createServer({
    name: 'main'
});

但是当我输入node main.js(我还没有尝试使用PM2)时,我收到了这样的错误:

/var/www/node_modules/restify/node_modules/assert-plus/assert.js:45
                    throw new assert.AssertionError({
                          ^
AssertionError: handler (function) is required
    at process (/var/www/node_modules/restify/lib/server.js:76:24)
    at argumentsToChain (/var/www/node_modules/restify/lib/server.js:84:13)
    at Server.use (/var/www/node_modules/restify/lib/server.js:625:6)
    at Object.<anonymous> (/var/www/main.js:47:8)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)

注意: 我已关闭在PM2下运行的所有应用。任何端口上都没有运行节点应用程序。

1 个答案:

答案 0 :(得分:1)

有效地执行此操作的唯一方法是运行配置为响应单个端口上的请求的HTTP代理,并根据URL模式将其传递给在其他端口上运行的服务器,其中的一个简单示例可以在{ {3}}

从本质上讲,您公开可见的代理服务器在端口80上运行,您运行其他服务器来处理特定请求。

因此,例如,如果您运行三个HTTP服务器,一个作为转发代理,两个用于特定功能,以便:

  • 端口80上的代理
  • 端口8080上的server2,用于匹配正则表达式的请求:/^\/first(?:\/.*)?$/
  • 端口8081上的
  • server3,用于匹配正则表达式的请求:/^\/second(?:\/.*)?$/

其中唯一具有公共连接的服务器是您的代理。

当代理收到/first/first/index.html的请求时,它会将请求转发给server2,后者返回一个结果文档,然后代理将该文档发送回原始请求者。

当收到/second/foo/bar/page.html的请求时,它会执行相同的操作,但使用server3来生成结果。

A HTTP Proxy Server in 20 Lines of node.js Code是此策略的一种实现,它使用http-proxy插件根据网址格式处理和转发请求。

更新

为了清楚起见,我们假设上面的proxyserver2server3表示单个节点HTTP服务器实例在单个IP地址上侦听但在同一台计算机上分离的端口。

示例:

var http = require('http'),
    httpProxy = require('http-proxy'),
    HttpProxyRules = require('http-proxy-rules');

// Set up proxy rules instance
//   where 
//     any request for /hostname/app1 will be proxy-ed via SERVER2
//     any request for /hostname/app2 will be proxy-ed via SERVER3
var proxyRules = new HttpProxyRules({
  rules: {
    '.*/app1/': 'http://localhost:8080',  // TO SERVER2
    '.*/app2/': 'http://localhost:8081'   // TO SERVER3
  }
});

// Create reverse proxy instance
var proxy = httpProxy.createProxy();

// Create http server on hostname:80 that leverages reverse 
// proxy instance and proxy rules to proxy requests to 
// different one of two target servers
http.createServer(function(req, res) { // PROXY 

  // a match method is exposed on the proxy rules instance
  // to test a request to see if it matches against one 
  // of the specified rules
  var target = proxyRules.match(req);

  if (target) {
    return proxy.web(req, res, {
      target: target
    });
  }

  res.writeHead(500, { 'Content-Type': 'text/plain' });
  res.end('No rule found for this request');

}).listen(80);

// create a new HTTP server on localhost:8080 to process
// requests sent from the proxy
http.createServer(function (req, res) { // SERVER2
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  var headers=JSON.stringify(req.headers,true,2);
  res.write('request successfully proxy-ed to SERVER2!' + '\n' + headers);
  res.end();
}).listen(8080,'localhost');

// create a new HTTP server on localhost:8081 to process
// requests sent from the proxy
http.createServer(function (req, res) { // SERVER3
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  var headers=JSON.stringify(req.headers,true,2);
  res.write('request successfully proxy-ed to SERVER3!' + '\n' + headers);
  res.end();
}).listen(8081,'localhost');

使用此设置:

  • 只有代理服务器可在端口80上外部使用
  • 在端口8080&amp;上运行的服务器8081在本地计算机上仅
  • 在主机名:80上接收的与/app1路径(和后代)匹配的请求将由localhost:8080上运行的服务器代理
  • 在主机名:80上收到的与/app2路径(和后代)匹配的请求将由localhost:8081
  • 上运行的服务器提供服务