如果你的server的cpu是多核的,或者你想你的nodejs后端更加的健壮,下面演示的使用http-proxy代理法或许对你有用,这种方法的基本思路就是多个node进程跑在不同的端口,而用户访问的是一个专门负责逐次指向多个node进程的代理服务进程(这个进程我们先用一个http-proxy来写,如何用nginx实现,容某谷歌谷歌,成功后再补上)。 如果这些进程跑在一台机器上,好处就是充分利用多核cpu,当然跑在局域网的不同机器的自然是为了减小访问压力,其实这样做也能提供更稳定的服务,一个进程down掉了,还有其他进程;
第一步:安装http-proxy 模块
//我用的时1.7.0的,如果是0.8版本的写法不一样,请参考其readme
npm install http-proxy
这个http-proxy不仅可以做HTTP和HTTPS的代理,还可以做websocket代理!
第二步:写个简单HTTP服务:app.js
var http = require('http');
http.createServer(function(req,res){
res.end('来自 '+ process.argv[2] +'端口的app的回应\n');
}).listen(process.argv[2] )
接下来,我们分别在8081,8082,8083端口上运行三个nodejs进程:
node app.js 8081 &
node app.js 8082 &
node app.js 8083 &
// 结尾处的& 代表着:以后台任务模式运行该程序,以下指令或许对你有用(我没在win机器上试过)
//显示所有后台进程:jobs
//把最近创建的后台任务变成普通进程:fg
//把普通进程变成后台任务:CTRL+z
第三步:talk is cheap, show me the code!
创建一个server.js来作为我们的代理服务器
var httpProxy = require('http-proxy'),//https://www.npmjs.org/package/http-proxy
http = require('http');
// localhost换成本地网络的其他机器即可实现多机器的负载均衡
var servers = [
'http://localhost:8081',
'http://localhost:8082',
'http://localhost:8083',
];
var proxy = httpProxy.createProxyServer({});
//自定义我们的代理服务器的逻辑
var proxyServer = http.createServer(function(req,res){
//获取第一个server
var target = servers.shift();
//将HTTP请求传递给目标node进程
proxy.web(req,res,{target: target });
//将第一个server放在末尾,以实现循环地指向不同进程
servers.push(target);
});
proxyServer.listen(8080);
proxy.on('error', function(err, req, res) {
res.send('some err happend....'+err);
});
/*
websocket代理!! 服务器如果接受到一个‘upgrade’事件,
则表明这个链接请求是websocket请求
!!!attention!!!
websocket的代理我还没有测试过
更多细节:http://stackoverflow.com/questions/15266702/proxying-websockets-with-tcp-load-balancer-without-sticky-sessions
*/
proxyServer.on('upgrade', function (req, socket, head) {
var target = servers.shift();// remove first array and set that removed as target;
proxy.ws(req, socket, head,{target:target.replace('http','ws')});
servers.push(target);
});
ok,接下来我们就可以来测试以下了,首先运行这个代理服务器:
node server.js
//然后我们可以在另一个命令行窗口用curl测试,或者在浏览器中访问:localhost:8080
curl -X GET localhost:8080
我们可以看到响应来自不同的进程,我们的简单的负载均衡代理服务器就是这么容易的实现了!
结论
你甚至可以这样做,用nginx 代理某个域名到这个辅助负载均衡的代理服务器,然后用forever 来运行你的app.js, 这样更能保证你的app的稳定性。
值得注意的一点是,session或者记录用户什么的放在内存的话这样多个进程之间不能交流会出现问题,所以建议将session等记录用户的数据放到redis,mongo,memcached或其他东西里面;以后等我遇到数据库性能瓶颈了我们再来讨论如何做mongodb的负载均衡的两个built-in的方法吧,take care and happy coding, bye!