Node.js 应用开发实战 - 高级前端开发工程师 - 拉勾教育
目前 Node.js 最常被用作前端工程化,导致大家误解为 Node.js 只适合作前端工程化工具,而忽视了其作为后端服务的特性。导致很少在后端研发中考虑使用 Node.js,认为没有任何优势,比如适用场景较少、性能较差等。为了消除这种误解,本讲将介绍 Node.js 的特性,以及适合哪些后端应用场景。
服务分类
我们常听说的服务有 RESTful 和 RPC,但这都是架构设计规范。我们也可以从另外一个角度来分析后台服务,如图 1 所示。
图 1 后台服务分类
以上分类并不能代表所有的服务,但是各个系统都或多或少包含这些服务。有些大型系统可能会比这复杂;有些小型系统可能没有这么多模块系统。
下面我们看下每个模块主要的工作是什么:
- 网关,处理请求转发和一些通用的逻辑,例如我们常见的 Nginx;
- 业务网关,处理业务相关的逻辑,比如一些通用的协议转化、通用的鉴权处理,以及其他统一的业务安全处理等;
- 运营系统,负责我们日常的运营活动或者运营系统;
- 业务系统,负责我们核心的业务功能的系统;
- 中台服务,负责一些通用 App 类的服务,比如配置下发、消息系统及用户反馈系统等;
- 各类基础层,这些就是比较单一的核心后台服务,例如用户模块,这就需要根据不同业务设计不同的核心底层服务;
- 左侧的数据缓存和数据存储,则是相应的数据类的服务。
在这些分层中,我们需要寻找网络 I/O 较多,但是 CPU 计算较少、业务复杂度高的服务,基于这点我们可以分析出 Node.js 应用在业务网关、中台服务及运营系统几个方面。接下来我们就分别从系统的业务场景及系统特性来分析为什么 Node.js 更合适。
业务网关
我们都了解 Nginx 作为负载均衡转发层,负责负载分发,那么业务网关又是什么呢?
可以这样考虑,比如我们后台管理系统有鉴权模块,以往都是在管理后台服务中增加一个鉴权的类,然后在统一路由处增加鉴权判断。而现在不仅仅是这个管理系统需要使用这个鉴权类,多个管理系统都需要这个鉴权类,这时你会考虑复制这个类到其他项目,又或者设计一个专门的服务来做鉴权,图 2 是一个转变的过程效果图。
图 2 业务网关的作用对比效果图
从上图我们可以看到,其实每个项目的鉴权都是相似的,没有必要在每个项目中维护一份通用的鉴权服务。因此可以提炼一层叫作业务网关,专门处理业务相关的通用逻辑,包括鉴权模块。
接下来我们就从一个实际的例子 OPEN API 的业务网关来介绍下这类服务场景。
业务场景
OPEN API 一般会有一个统一的 token 鉴权,通过 token 鉴权后还需要判断第三方的 appid 是否有接口权限,其次判断接口是否到达了请求频率上限。为了服务安全,我们也可以做一些降级处理,在服务过载时,可以根据优先级抛弃一些请求,具体可以查看图 3。
接下来我们从技术层面来看为什么 Node.js 更适合此类应用场景。
服务特性
根据图 2 的场景应用,我们专注看下 Nginx 后面的业务网关处理层,它的业务场景如图 4 所示。
这 3 个功能都是基于缓存来处理业务逻辑的,大部分都是网络 I/O ,并未涉及 CPU 密集型逻辑,这也是 Node.js 的优势,其次异步驱动的方案能够处理更高的并发。根据第 01 讲的内容,Node.js 的代码核心是不阻塞主线程处理,而这类业务网关都是轻 CPU 运算服务。因此在这类场景的技术选型中,可以考虑使用 Node.js 作为服务端语言。
中台服务
在 Web 或者 App 应用中都存在一些通用服务,以往都是独立接口、独立开发。随着公司应用越来越多,需要将一些通用的业务服务进行集中,这也是中台的概念。而这部分业务场景往往也是网络 I/O 高、并发较大、业务关联性高、数据库读写压力相对较小。下面我们就来分析下这种业务场景。
业务场景
为了避免资源浪费、人力浪费,我们可以使用如图 5 所示的中台服务系统:
- 前端配置系统是在服务端根据客户端的版本、设备、地区和语言,下发不同的配置(JSON 或者文件包);
- 反馈系统,即用户可以在任何平台,调用反馈接口,并将反馈内容写入队列,并落地到系统中进行综合分析;
- 推送系统用于管理消息的推送、用户红点和消息数的拉取,以及消息列表的管理;
- 系统工具用于处理用户端日志捞取、用户端信息调试上报、性能定位问题分析提取等。
以上是多个中台系统的业务说明,我们再来具体看看每个系统的特性,从特性来分析为什么 Node.js 适合作为服务端语言。
服务特性
在中台系统的设计中,系统着重关注:网络 I/O、并发、通用性及业务复杂度,一般情况下不涉及复杂的 CPU 运算。这里我们以上面列举的系统来做分析,如表 1 所示。
在上述系统对比中,可以分析出 Node.js 作为中台服务,要求是:
- 通用性必须好;
- 低 CPU 计算;
- 网络 I/O 高或者低都行;
- 并发高或者低都行。
因为这样的服务在 Node.js 主线程中,可以快速处理各类业务场景,不会存在阻塞的情况,因此这类场景也适合使用 Node.js 作为服务端语言。
其他相关
运营系统
在各类互联网项目中,经常用运营活动来做项目推广,而这类运营系统往往逻辑复杂,同时需要根据业务场景进行多次迭代、不断优化。往往这些活动并发很高,但是可以不涉及底层数据库的读写,而更多的是缓存数据的处理。比如我们常见的一些投票活动、排行榜活动等,如图 6 所示。
运营系统这块我们会在《18 | 系统的实践设计(下):完成一个通用投票系统》中详细介绍,并且进行这类系统的实践开发。
不适合场景
前一讲介绍了事件循环原理,在原理中突出的是不能阻塞主线程,而一些密集型 CPU 运算的服务则非常不适合使用 Node.js 来处理。比如:
- 图片处理,比如图片的裁剪、图片的缩放,这些非常损耗 CPU 计算,应该用其他进程来处理;
- 大字符串、大数组类处理,当涉及这些数据时,应该考虑如何通过切割来处理,或者在其他进程异步处理;
- 大文件读写处理,有时会使用 Node.js 服务来处理 Excel,但是遇到 Excel 过大时,会导致 Node.js 内存溢出,因为 V8 内存上限是 1.4 G。
可能还有更多场景,这里只是列举了很小的一部分,总之两个关键因素:大内存和CPU 密集,这样的场景都不适合使用 Node.js 来提供服务。
总结
本讲中介绍的各类系统,都遵循了我们《01 | 事件循环:高性能到底是如何做到的?》所介绍的 Node.js 事件循环原理,减少或者避免在 Node.js 主线程中被阻塞,或者进行一些 CPU 密集型计算。遵循了这个原理后,就可以拓展出一些业务复杂度高、业务迭代快的功能,或者一些通用性服务。
在学完本讲后,你可以了解 Node.js 适合哪些应用场景,并在实际工作中可以尝试使用或者推荐团队来尝试,有任何心得或者问题,都欢迎在评论区与我交流。
下一讲,我们将介绍一个 Node.js 作为后端服务的例子,到时见。
《大前端高薪训练营》
对标阿里 P7 技术需求 + 每月大厂内推,6 个月助你斩获名企高薪 Offer。点击链接,快来领取!