在 Nodejs 搭建的 web 服务中, 一般不会让用户直接请求 Nodejs 起的服务, 常见的做法是用 nginx 作为前台的服务器, 然后把请求转发给 Nodejs server, 以实现负载均衡等需求.
image.png
关于 Nodejs 负载均衡, 在本人之前的文章 NodeJs 进程管理神器 pm2 使用记录就已经讲到过, 说的是用 Nodejs 进程管理模块 pm2 自动实现负载均衡, 这里再记录一下借助 nginx 实现负载均衡的方式.
这里要做的大概是这样的:
一个 nginx 作为前台的服务器
全部请求, 经过负载均衡, 尽可能均衡的分步到后面的 2 台 node 服务器
准备 node
首先启动两台 node, 分别监听 3000,3001 端口. 为了区分, helloworld 会带一个端口返回, 通知客户端, 以便区别是谁在提供服务.
node.js server
$cat 1.js
- require('http').createServer(function (request, response) {
- response.end('hello world\n'+process.argv[2]);
- }).listen(process.argv[2]);
- $node 1.js 3000
- $node 1.js 3001
验证 node 服务器启动
- $ curl localhost:3000
- hello world
- 3000
- $ curl localhost:3001
- hello world
- 3001
准备 nginx 服务器的配置.
要点是通过 upstream 指令把两个 node 服务器打成一个服务器池. 然后通过 location 指令, 要求全部根目录请求转发到这个池内. 池会对它之内的服务器做负载均衡.
nginx conf
- worker_processes 1;
- events {
- worker_connections 1024;
- }
- http {
- upstream node_server_pool {
- server localhost:3001 max_fails=1;
- server localhost:3000 max_fails=1;
- }
- server{
- listen 80;
- server_name localhost;
- location /
- {
- proxy_pass http://node_server_pool;
- }
- }
- }
模拟客户端访问
我用 curl 多次访问 nginx 服务器, 可以通过返回的字符串知道服务器. 你看, 真的可以负载均衡: 一会儿 helloworld 3000, 一会儿 helloworld 3001.
$ curl localhost
hello world
3000
$ curl localhost
hello world
3001
$ curl localhost
hello world
3001
$ curl localhost
hello world
3000
你看, ngnix 是公平的. 哪怕就一个客户的多次访问都会换着服务器来.
参考
node.js 成也异步, 败也异步, 评 node.js 的异步特性 | 江淼的 Blog - http://www.jiangmiao.org/blog/2491.html
Node.js + Nginx - What now? - Stack Overflow - http://stackoverflow.com/questions/5009324/node-js-nginx-what-now
为高负载网络优化 Nginx 和 Node.js - 技术翻译 - 开源中国社区 - http://www.oschina.net/translate/optimising-nginx-node-js-and-networking-for-heavy-workloads
让 node.js 充分利用多核服务器的性能, 运用 nginx 做反向代理和负载均衡 - snoopyxdy 的日志 - 网易博客 -
http://snoopyxdy.blog.163.com/blog/static/60117440201172954648952/
来源: http://www.jianshu.com/p/262306757f87