如何设计分布式node.js Web服务器

时间:2012-11-13 02:59:19

标签: node.js scalability distributed multicore

Supose我需要实现一个具有大量并发用户的Web应用程序。我决定使用node.js,因为它扩展得非常好,它具有良好的性能,开源社区等等。然后,为了避免瓶颈,因为我可以在同一个事件循环中拥有大量用户,我决定使用一个群集进程利用多核CPU。此外,我有3台机器(主+ 2),因为我需要用Cassandra操纵大数据。太棒了,这意味着我有3 * n个node.js进程,其中n是cpu的核心数(机器是相同的)。

好的,然后我开始研究,我以下面的模式结束:

  • Nginx在端口80上侦听并仅用于提供静态内容(img,css,js等)。
    将动态流量转发到haproxy。我知道如何配置nginx但我还是要看看haproxy,所以我会说haproxy正在侦听端口4000。 Nginx和haproxy安装在主机(入口点)。
  • 3台机器之间的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应用程序?是否有任何模块可以简化同步任务?

3 个答案:

答案 0 :(得分:1)

您可以使用memcache或redis存储会话对象。它在重启节点进程的情况下非常有用(如果会话数据存储在进程'内存中,它将丢失)。

此外,您可以检查pm2功能列表,其中一些功能列表对您有用。

构建微服务架构将实现良好的可扩展性。

答案 1 :(得分:1)

正如Ivan所指出的,您将会话对象存储在memcache或redis甚至Couchbase(memcache存储桶)中。我还想补充一点,如果你想构建一个可扩展的系统,你的目标应该是以一种可以线性扩展以根据需求增加吞吐量的方式构建系统。我的意思是,您应该能够在任何时候(最好是在峰值期间)将更多主机添加到基础架构中的不同层以处理需求。

因此,您必须非常小心您选择的技术以及您在开发过程中做出的设计决策。

  

Supose我需要实现一个具有大量并发用户的Web应用程序。

我想添加的另一件事是,如果你无法衡量它,你就无法管理它。一个良好的开端将定义什么"大量的并发用户"对你意味着什么?是facebook还是whatsApp类型的卷/并发?首先通过与利益相关者(如果有的话)合作来定义这些,然后您就可以开始做出设计决策和选择技术了。

在构建可扩展系统的同时,一个很好的试金石就是问问自己,"是否存在单点故障?"如果是,则您的系统不会扩展。

答案 2 :(得分:0)

正如另一位用户建议的那样;使用Redis是解决此问题的完全可接受的解决方案。

它的缺点是使用该服务存储会话对象,并让中间件处理其他所有事情。如前所述,它在节点进程重新启动,崩溃等情况下非常有用。在会话进程中存储会话数据会带来风险。使用微服务(如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 )