如何devise一个分布式的node.js web服务器
Supose我需要实现一个Web应用程序,将有大量的并发用户。 我决定使用node.js,因为它扩展得非常好,性能良好,开源社区等等。为了避免瓶颈,我可以在同一个事件循环中使用用户,我决定使用一个簇进程利用多核CPU。 此外,我有3台机器(main + 2),因为我需要使用Cassandra来处理大数据。 真棒,这意味着我有3 * n node.js进程,其中n是CPU的核心数(机器是相同的)。
好吧,然后我开始研究,我以下面的模式结束:
- Nginx监听端口80,只用于静态内容(img,css,js等)。
将dynamicstream量转发给haproxy。 我知道如何configurationnginx,但我仍然需要看看haproxy,所以我会说,haproxy正在监听端口4000. Nginx和haproxy安装在主机(入口点)。 - 3台机器之间的Haproxy负载平衡。 它将stream量转发到端口4001,即node.js进程正在侦听4001。
- 每个node.js都有一个包含n个进程的集群,监听4001。
如果我是正确的,单个http请求将被转发到单个node.js进程。
创build一个会话是很正常的,对吧? 一个会话只是一个地图,而这个地图是一个Object,而这个Object住在一个node.js进程中。 Haproxy将configuration一个循环调度程序,所以同一个用户可以被转发到不同的node.js进程。 如何跨所有node.js进程共享相同的会话对象? 我如何共享一个全局对象(这包括在同一台机器(node.js集群)和整个networking中)? 我应该如何devise一个带有node.js的分布式Web应用程序? 有没有任何模块,缓解同步任务?
您可以使用memcache或redis来存储会话对象。 在重新启动节点进程的情况下非常有用(如果会话数据存储在进程的内存中,将会丢失)。
你也可以检查pm2function列表,也许其中一些会对你有用。
构build微服务架构将具有良好的可扩展性。
正如Ivan指出的那样,您将会话对象存储在memcache或redis甚至Couchbase(memcache存储桶)中。 我还想补充一点,如果你想build立一个可扩展的系统,你的目标应该是build立一个可以线性扩展的系统,以便根据需求增加吞吐量。 我的意思是,您应该能够随时(最好是在高峰期)将更多的主机添加到您的基础架构中的不同层,以处理需求。
所以你必须非常小心你select的技术和你在开发过程中做出的devise决定。
Supose我需要实现一个Web应用程序,将有大量的并发用户。
我想补充的另一件事,如果你不能测量它,你不能pipe理它。 一个好的开始会定义什么“大量的并发用户”对你来说意味着什么? 是Facebook或WhatsApptypes的音量/并发? 通过与您的利益相关者(如果有的话)合作,首先定义这些内容,然后您就可以开始制定devise决策和采摘技术。
在build立一个可扩展的系统时,一个好的试金石testing就是问自己:“是否有单点故障? 如果是,那么你的系统不会扩展。
另一个用户build议; 使用Redis是完全可以接受的解决scheme。
它的内幕是使用服务来存储会话对象,并让中间件处理所有其他事情。 如前所述,在节点进程重启,崩溃等情况下,它是有用的。将会话数据存储在节点进程中存在风险。 使用微服务(如Redis)的好处之一就是减less了这些风险。
假设您使用Express
作为中间件,则可以使用称为Session store
东西。 有很多模块可以利用这个function。
一个这样的模块是connect-redis
安装和平常一样轻松:
npm install connect-redis express-session
那么你会这样使用它:
var session = require('express-session') var RedisStore = require('connect-redis')(session) app.use(session({ store: new RedisStore(options), secret: 'keyboard cat' }))
现在,您使用会话对象,就像通常那样。 ( req.session
)
例子:
设置会话信息(例如,来自POST表单):
req.session.email = req.body.email
检索会话信息:
console.log( req.session.email )