Netflix,Reddit,Walmart和Ebay等公司在其上部署的应用程序就证明了Node.js已经在全球范围内成功运作。 但是,在扩展时会遇到一系列问题。 从可伸缩性的角度来看,在单个代码库上工作的人,因此从云中的垂直和水平伸缩性的角度来看。 除了我在Reddit和Netflix等公司工作时在Node.js扩展方面的个人经验之外,我还与Microsoft Azure的一些专家进行了交谈,并为您提供了一些在公司扩展Node.js的技巧。
编写优质的Node.js
越早开始在代码中使用linters,格式化和类型检查工具,效果越好。
由于可能需要大量的重构,因此在项目中间引入这些内容可能会很棘手,它还会污染您的git历史记录,但是最终这些工具将帮助您使代码可读。
如果您仍然不使用它们,请立即将视线转向
ESLint和
Prettier 。 ESLint将保护您的代码免受不良模式的侵害,Prettier将帮助您在请求请求之前自动格式化代码。
一个更重要的解决方案是将Flow或TypeScript之类的工具添加到您的代码库中。 这些工具使您可以捕获更多细微的错误,例如使用数字参数而不是字符串调用函数或在对象而不是数组上调用
.filter方法。 尽管复杂且需要培训您的团队,但这些工具仍应引起您的注意:它们可以使用Intellisense加快开发速度,并通过类型保护防止运行时错误。
编写测试
测试一直是开发人员的难题。 有些人坚信测试驱动的开发,而其他人则很少编写测试。 但是有一个中间立场:
- 定义关键模块并为其编写全面的单元测试。 要特别注意“快乐旅程”:可能发生错误的极端情况和方案。 对于其他模块,编写一个或两个单元测试,涵盖“快乐的道路”以及您可能发现的常见情况
- 最低UI测试 。 UI不断变化,花很多时间对经常变化的代码进行测试通常是不切实际的。
- 编写测试以检测错误 。 每当您发现并修复代码中的错误时,就编写一个单元测试,将来会捕获此错误。
- 编写一些集成测试 ,以确保所有部分相互匹配。
- 编写更少的端到端测试 。 涵盖站点上的关键路径,例如,如果您要创建一个电子商务站点,则可能值得编写一个测试以进入该站点,将其添加到购物篮中并检查产品列表。 这些测试的维护成本很高,因此请考虑保留一小部分可以激发您进行维护的测试。
编写测试的起点是自信地部署新代码的能力。 编写如此多的测试,不少于您自己的感受,但请尝试编写不超过上面的列表。
无状态设计
编写可伸缩Node.js的关键是您的服务器不必存储某人或某物的状态。 这将防止水平缩放。 将状态移到另一个应用程序并在其他地方解决问题(例如Redis,Etcd等)。 您应该事先考虑一下。 如果您之前没有做过,那么将很难解开。 如果您决定将整体式服务分解为微服务,也将有所帮助。
统计信息:用于开发-Node.js,用于生产-CDN
我希望公司如何看到此错误中的错误。 通过Web应用程序(尤其是通过webpack-dev-server或Parsel的dev服务器之类的服务)为您的静态资产提供服务是一种很棒的开发人员体验,因为它缩短了编写代码时的引入周期。 但是,永远不要通过Node.js提供静态服务。 它必须通过CDN(例如Azure CDN)单独运送。
由于CDN分散程度更高,因此在物理上更接近最终用户,并且CDN服务器针对小型资源进行了高度优化,因此Node.js的静态收益会不必要地变慢。 使用Node维护静态数据的代价也过高,因为Node.js服务器时间比CDN服务器时间昂贵得多。
尽早开始部署,更频繁地部署
我不认识您,但是当我第一次对某个内容进行解密时,它永远不会起作用。 这通常是因为我忘记了发送正确的私钥或将路径硬编码到本地主机。 在本地远程工作的小问题拒绝这样做。 这些问题可能会累积,如果很早就发现这些问题,很容易就可以解决,否则可能会变成一大堆无法理解的错误,而这些错误根本无法正常捕获。
顺便说一句,
Visual Studio Code允许您解决此类问题 。 它允许您一键将应用程序直接部署到Azure。 这是一种非常简单的方法,可以验证在部署到另一个环境中没有问题。
一次部署2台服务器
这个建议来自我来之不易的知识和令人心痛的海洋。 该建议的实质是两个服务器和十个服务器的部署之间几乎没有差异,而十个服务器和一百个服务器的部署之间没有太大差异。 但是,部署一台服务器和两台服务器之间仅存在巨大差异。
与部署无状态服务器的问题类似(从两台服务器开始),您可以快速克服水平扩展问题,以便在流量激增时可以进行扩展。
不要害怕线条
现代数据库无需您的帮助即可自行完成一定数量的读写操作。 在测试想法时,请随时依赖数据库来处理中小型工作负载。
过早的缩放比杀死您更可能杀死您。 但是,在某个时候,您的应用程序将增长,您将无法将所有内容也都写入数据库,从而面临读写带宽问题。 对于某些具有轻量级记录的应用程序,或者如果您选择诸如Cassandra之类的数据库,该数据库可以自行处理大量数据,则稍后将出现问题,而对于其他应用程序则将更早。
如果您有或将要遇到这样的问题,则可以选择一些技术,以进一步发展。 这些技术之一可能是消息队列。 目前的实际标准是Apache Kafka,它允许您组织主题中的消息,然后使用应用程序订阅该主题。 因此,例如,您可以在应用程序中累积消息,侦听某个主题,然后将数据批量写入数据库中,以使它不会一直阻塞。
此外,Kafka可以在Azure上轻松运行 。
微服务扩展
随着应用程序的增长,自然的逻辑划分开始出现。 该应用程序的一部分可以处理付款,而另一部分将为您的前端提供API。 进行逻辑划分时,请考虑将它们分开作为微服务。 但是要小心,因为引入微服务也非常复杂。 但这是值得的。 因此,例如,每个微服务可以有自己的指标。 通过评估它们,您可以独立缩放它们。
使用容器
您的应用程序可能在本地运行良好,但是尝试进行部署时可能会遇到严重问题。 诸如Docker和Kubernetes之类的工具将为您工作,以避免出现此问题。 您可以将Docker想象成Linux或Windows的一个小型实例(容器),您可以在其中运行应用程序。 和Kubernetes作为将您所有容器连接到云中的工具。
Kubernetes可能是一个复杂的野兽,但可以解决一个复杂的问题。 如果您是经验不足的DevOps巫师,则可能会遇到困难,因此我建议从
Draft开始。 如果您对Java项目的
Yeoman熟悉,则可以将Draft评估为类似的工具,但对于Kubernetes项目,可以将其评估为:一种为项目创建线框的工具。 从那里,您可以使用
Helm工具安装需要构建的其他架构部分(例如nginx,更多Node.js,MongoDB,Kafka服务器等),就像Kubernetes的
npm一样。
一旦您了解了Kubernetes生态系统,从现在开始,在云中进行部署将成为孩子们的游戏。
收集指标
如果您不知道如何回答“我的应用程序如何工作?”问题,那么您将遇到问题或很快就会遇到问题。 毕竟,随着时间的推移,各种指标将帮助您不断改善应用程序的状态。 从未来成本的角度,以及从改善响应时间的角度来看,从用户便利性的角度来看。 您绝对应该跟踪指标,例如慢速路径,页面浏览,会话时间以及对您的业务很重要的其他关键指标。
有很多方法可以收集这些指标。 New Relic和AppDynamics等服务将为您提供有关如何改进应用程序的宝贵信息。
如果您使用Azure,Application Insights也可以满足此需求,并且可以轻松插入CI / CD等其他工具。
CI / CD可以让您免于沉重的痛苦
您在FTP期间破坏了部署几次并关闭服务器几分钟了? 就是我 您永远不要相信自己部署生产代码。 如何使用Visual Studio Code做到这一点很酷,但主要是出于开发或演示目的。 准备好创建生产级系统时,应该使用持续集成和持续部署(通常缩写为CI / CD-持续集成和持续部署)。
持续集成是软件开发的一种实践,它包括每天将工作副本合并到一个通用的开发主分支中,并执行频繁的项目自动组装以快速识别潜在缺陷并解决集成问题。
连续部署需要考虑通过CI的代码,执行构建,容器化或打包它们的必要步骤,并将其发送到服务器。 良好的做法是测试多个级别。 您可能首先要去内部开发服务器在低风险环境中查看它。 您可以先进行测试,然后再将其发送到QA环境,您的QA工程师或可能的外部服务人员将确认一切正常。 从那里,您可以切换到一个中间环境,在该中间环境中,您的应用程序仍仅是内部的,但可以使用生产数据和设置运行,因此您可以在直接将其发送到生产之前,在生产环境中对其进行测试。 您还可以选择一小组服务器来检查新代码:仅将一小部分实际流量定向到这些服务器,以确保与实际用户一起使用时不会中断。 如果出现故障,您知道在哪里寻找问题。 如果没有,您可以从一小群用户转移到所有人。
许多开源供应商和项目都满足这些需求。 Jenkins,Travis和CircleCI是CI的不错选择。 Azure有自己的CI / CD服务,称为Azure Pipelines,使用起来非常直观,并且再次可以轻松地连接到集成的Azure生态系统。
保守秘密
任何应用程序不可避免地都有一些秘密。 它可以是凭据,数据库等中的密钥和秘密行。 如果他们交到错误的人手中,那将是非常糟糕的。 但是,它们是运行应用程序所必需的。 那我们该怎么办? 通常在开发中,我们将使用诸如
dotenv之类的工具将配置文件保存在本地,并能够通过Node.js中的process.env读取它。 这对开发人员来说很棒,但对生产来说却很糟糕。
相反,使用某种秘密管理工具很有用。 幸运的是,
Kubernetes具有内置系统 ,并且非常易于使用。 您在容器端提供Kubernetes机密,然后将它们提供给您的应用程序,这是使攻击大大复杂化的环境。
另一个值得您注意的工具是Azure
Key Vault 。 即使Microsoft无法读取您的密钥(只有您可以解密它们),Key Vault的优点还是什么?Azure会跟踪您的日志并跟踪您对密钥的任何可疑使用,以提醒您任何妥协。
结论
与其他平台一样,Node.js也需要扩展。 并且,与任何其他平台一样,它具有自己的任务和缩放的特殊性,这是值得了解的,在设计大型项目时应将其考虑在内。
原始文章:“扩展Node.js的11条技巧”(
En )。
我建议在评论中分享一些有关扩展Node.js的技巧。 听到会很有趣。