Supose我需要实现一个具有大量并发用户的web应用程序。我决定使用node.js,因为它的扩展性很好,性能很好,开源社区等等。然后,为了避免瓶颈,因为我可能在同一事件循环中有大量用户,我决定使用一组进程来利用多核CPU。此外,我有3台机器(main+2),因为我需要用Cassandra处理大数据。太棒了,这意味着我有3*n个node.js进程,其中n是cpu的内核数量(机器是相同的)。
好的,然后我开始一项研究,并以以下模式结束:
- Nginx在端口80上侦听,仅用于提供静态内容(img、css、js等)
将动态流量转发到haproxy。我知道如何配置nginx,但我仍然需要查看haproxy,所以我会说haproxy正在监听端口4000。Nginx和haproxy安装在主机(入口点)中 - 三台机器之间的Haproxy负载平衡。它将流量转发到端口4001,即node.js进程正在侦听4001
- 每个node.js都有一个由n个进程组成的集群,监听4001
如果我是正确的,那么单个http请求将被转发到单个node.js进程。
创建会话很正常,对吧?会话只是一个映射,这个映射是一个Object,这个Object位于node.js进程中。Haproxy将配置一个循环调度程序,因此同一用户可以转发到不同的node.js进程。如何在所有node.js进程中共享同一个会话对象?如何共享全局对象(包括在同一台机器(node.js集群)中并通过网络共享)?我应该如何使用node.js设计分布式web应用程序?是否有任何模块可以简化同步任务?
您可以使用memcache或redis来存储会话对象。它在重新启动节点进程的情况下非常有用(如果会话数据存储在进程的内存中,它将丢失)。
此外,您还可以查看pm2特性列表,其中一些特性可能对您有用。
构建微服务体系结构将具有良好的可扩展性。
正如Ivan所指出的,您可以将会话对象存储在memcache或redis甚至Couchbase(memcache bucket)中。我还想补充一点,如果您想构建一个可扩展的系统,您的目标应该是以一种可以线性扩展的方式构建系统,以根据需求增加吞吐量。我的意思是,您应该能够在任何时候(最好是在高峰期)将更多的主机添加到基础架构中的不同层,以处理需求。
因此,在开发过程中,你必须非常小心地选择什么技术和做出设计决策。
Supose我需要实现一个具有大量并发用户的web应用程序。
我想补充的另一件事是,如果你不能衡量它,你就无法管理它。定义"大量并发用户"对你意味着什么是一个好的开始?这是facebook还是whatsApp类型的卷/并发?首先通过与利益相关者(如果有的话)合作来定义这些,然后你就可以开始做出设计决策和选择技术了。
在构建可扩展系统时,一个很好的试金石是问自己,"是否存在单点故障?"如果是,那么你的系统就无法扩展。
按照另一位用户的建议;使用Redis是完全可以接受的解决方案。
它的底层是使用服务来存储会话对象,并让中间件处理其他一切。如前所述,它在节点进程重新启动、崩溃等情况下很有用。将会话数据存储在节点进程中会带来风险。使用Micro服务(如Redis)的好处之一是降低了这些风险。
假设您将Express
用于中间件,则可以使用一种称为Session store
的东西。有很多模块利用了这一功能。
其中一个模块是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 )