node.js 多核集群模块或单核多节点实例

node.js cluster module on multi-core or multiple node instances on single core

我正在构建一个 node.js 后端 运行ning .12.7。此后端每秒将处理数千个 HTTP POSTS,每个 POST 需要先进行身份验证。

实现每个 POST 身份验证的最快方法是在针对第一次尝试对用户进行身份验证后生成一个会话密钥,所有后续尝试都将使用存储在数组中的此会话密钥进行身份验证在记忆中。会话密钥将在 10 分钟后过期。

由于数组查找是同步的(需要 5 到 40 毫秒),我将需要增加处理连接的实例或工作程序的数量。

我正在考虑的两个选项是:

  1. 运行 单核机器上的多个节点实例,并将负载平衡设置为粘性,以便每次客户端发送 POST 时,它都会转到同一台服务器。这是为了确保我能够根据存储在内存中的会话密钥对客户端进行身份验证。
  2. 使用集群模块在多核机器上启动工作器。这样做的好处是它可能更容易维护,因为我不需要 运行 多个单个实例。

当我在 nodejs.org 上查找集群时 - 它说 "Stability: 2 - Unstable"。我正在阅读此内容,因为它尚未准备好生产。但是看博客好像大家都推荐用Cluster。

有人在生产环境中实现过Cluster吗?还有其他我应该看看的选择吗?

提前致谢

您可能会考虑使用 HMAC,就像 Amazon 对 S3 所做的那样。这使您能够验证请求是否已获得授权,而无需保留 sessions 进行验证。

基本上,您获取所有请求数据并将其与只有授权方和服务器知道的密钥一起散列。然后,您获取此散列并将其与您的请求一起发送。服务器获取此数据,re-hashes,如果匹配,则允许请求。例如,这是原始请求:

POST /something
X-Key: thekey

现在我们将所有这些与秘密一起散列,并将其作为另一个 header:

X-Hash: sha1('POST /something' + 'X-Key: thekey' + secret);

现在可以明文发送请求,并且无法恢复秘密,因为哈希函数是 one-way。服务器将接收该数据和 re-hash 使用它查找 thekey 的秘密。如果计算出的哈希与 X-Hash 的值相匹配,那么它就知道只有拥有授权密钥和秘密的人才能发出(或签署)此请求,我们应该继续。

这个计划有一个很大的缺陷……它允许重播攻击。有两种方法可以解决这个问题。最简单且通常 effective-enough 的方法是在请求中添加到期日期。

POST /something?expires=2015-09-01T11:45:00Z

由于每个签名请求都有自己的哈希值,因此无法简单地更改过期日期而不会使请求无效。然后只能重播请求,直到过期为止。

一种更可靠但更难实施的防止重放攻击的方法是使用随机数。基本上,您向请求添加一些数据,然后将其存储在数据集中并承诺不再使用。理想情况下,它是一个随机数。

POST /something?nonce=oijwioj3wdlkjfoj234234ojwefoij

如果有人试图重放此请求,您的服务器会通过检查随机数数据库发现此随机数已被使用,然后拒绝该请求。

这就是 HMAC。现在,您可能注意到这并不能直接解决您的问题,因为您至少需要一种方法来查找 key/secret。在这里您可以发挥创意。

您可以基于另一个密钥以编程方式生成密钥。也许最初分发这个 session 密钥的服务器有某种主密钥,它可以从中派生出其他密钥和秘密。也许通过用我们的主密钥散列客户端在 X-Key 中指定的密钥,我们得到 secret。这意味着如果您需要撤销,您将不得不更改主密钥(因此所有 keys/secrets),但这在您的情况下可能是可以接受的。也许我们会在每个请求中轮换密钥并有一个到期日期。有很多方法可以处理这种情况,但这取决于您的具体要求。

重点是构建一个完全不需要查找来验证请求是否已授权的系统。如果请求包含足够的信息,这是可能的。您真正需要的只是一个只能由授权方计算的请求签名。我想您会发现这非常适用于您的问题。