部署
我的部署选择是按子堆栈使用舰队
我部署在 SmartOS 上,并让舰队中心和无人机作为服务运行,这些服务会自动重启。
我正在开发调度程序,它是车队的前端。Dispatcher 将允许您将所有存储库保存在中央位置,例如 github 或 bitbucket,然后从中央 git 服务器部署最新代码
负载均衡
有关设置 http 和 https 服务器的信息,请在此处查看我的答案。在我的应用程序中,http 服务器实际上是另一个 node-http-proxy 服务器。在这个设置中,我的应用程序可以包含许多在海港注册的小服务
路由http服务器
var http = require('http')
var https = require('https')
var httpProxy = require('http-proxy');
var seaport = require('seaport');
var fs = require('fs')
var inspect = require('eyespect').inspector();
var express = require('express')
function router(data, cb) {
var app = express()
var config = data.config
var logger = data.logger
var appPort = config.get('application:port');
var routerConfig = config.get('router')
var seaHost = config.get('seaport:host')
var seaPort = config.get('seaport:port')
var ports = seaport.connect(seaPort, seaHost)
var proxy = new httpProxy.RoutingProxy();
app.use(express.methodOverride());
app.use(app.router)
var server = http.createServer(app)
app.all('/api/:service/*', function (req, res) {
var service = req.params.service
var ps = ports.query(service);
if (!ps || ps.length === 0) {
ps = null
unavailable(req, res, service, logger);
service = null
return
}
var item = ps[0]
// remove /api/service/ from start of the url
var newURL = req.url.replace(/^\/api\/.*?\//, '/')
logger.debug('proxying to api service', {
role: router,
service: service,
url: req.url,
newURL: newURL
})
req.url = newURL
proxy.proxyRequest(req, res, {
host: item.host,
port: item.port
});
item = null
})
var pong = 'PONG'
app.get('/ping', function (req, res) {
res.send(pong)
})
app.get('/services', function (req, res) {
return showServices(req, res, ports)
})
app.all('/*', function (req, res) {
var service = 'web'
var ps = ports.query(service);
if (!ps || ps.length === 0) {
unavailable(req, res, service, logger);
service = null
ps = null
return
}
proxy.proxyRequest(req, res, {
host: ps[0].host,
port: ps[0].port
});
ps = null
})
var serverPort = routerConfig.port
server.listen(serverPort, function (err, reply) {
if (err) { return cb(err); }
logger.debug('router application online', {
type: 'router',
port: serverPort
});
var output = {
port: serverPort,
server: server
}
cb(null, output)
});
}
function showServices(req, res, ports) {
var ps = ports.query();
var data = {
message: 'Current services registered',
services: ps
}
res.writeHead(200)
return res.end(JSON.stringify(data))
}
function isServicesURL(url) {
var pattern = /^\/services/i;
return pattern.test(url)
}
function unavailable(req, res, service, logger ) {
var resData = {
error: 'service unavailable',
message: 'no servers are available to serve your request',
url: req.url,
role: 'router'
service: service
};
logger.debug('router service unavailable', {
role: 'router',
responseData: resData
})
res.writeHead(500);
return res.end(JSON.stringify(resData));
}
module.exports = router;
spinUpRouter.js这是由舰队实际产生的节点进程
var inspect = require('eyespect').inspector()
var assert = require('assert')
var fs = require('fs')
var routerLib = require('./index.js');
var optimist = require('optimist');
var nconf = require('nconf')
var argv = optimist.demand(['config']).argv;
var configFilePath = argv.config
assert.ok(fs.existsSync(configFilePath), 'config file not found at path: ' + configFilePath);
var config = nconf.argv().env().file({file: configFilePath});
var logger = require('loggly-console-logger')
var routerData = {
config: config,
logger: logger
}
logger.debug('spinning up router', {
type: 'router',
configFilePath: configFilePath
})
routerLib(routerData, function (err, server) {
inspect('router online')
})
日志记录
我使用winston来管理我的日志。更具体地说,我使用控制台和Loggly传输。我做了这么多,我把它包装成一个模块loggly-console-logger