Skip to content
On this page

设计篇-技术选型


前言

通过上一章的学习,我们了解了网关系统,并且针对要做的功能做了项目架构设计与需求拆解。

那在一个项目正式开发之前,我们还需要做一个技术调研,从开发框架、使用的工具、数据库等等进行一系列的预研,避免在业务开发过程中出现因为技术原因导致完成不了需求的局面。

例如团队中所有并没有 Java 开发,构建工具使用了基于 JavaJenkins,这个时候想对 Jenkins 有一些技术改造要求无法顺利完成。

本章我们就一起对开发框架数据库的类型做简单的对比与选择。

对于工程中所使用的环境以及中间件配置,感谢后端大佬和耳朵专门写了一篇介绍的文章配合一下,内容非常全面,需要的同学可以点击查看【环境与中间件配置

技术选型

开发框架选型

市面上常见的网关系统及框架有如下几种。

只是举了一些常见的框架,并未全部列出,还有很多其他优秀的框架可以自行找寻

  • Nginx+Lua:Open Resty、Abtesting Gateway。
  • Java:Spring Cloud Gateway。
  • Go:Janus、Grpc-Gateway。
  • Node.js:Express Gateway、MicroGateway。

上述都是业内成熟的框架以及方案,并且网关系统作为独立于业务的技术中间层,并不存在开发语言与框架的限制,所以可以根据自己团队的实际技术栈选择适合自己团队的网关框架。

但对于前端来说,使用其他语言的成本不低。同时为了更好地理解业务需求,我们并不打算使用市面已经开源或者成熟的框架去搭建一个网关系统,而是使用 NodeJS 来从头搭建一个网关系统。

既然选择了 NodeJS 开发系统,服务端的开发框架也有很多比如老牌的 ExpressKoa 等,我们选择基于它俩封装的上层框架 EggNestJs 进行简单对比。

EggNestJs 对比

首先,我们先看看两家的 Slogan

  • Egg: 为企业级框架和应用而生。
  • NestJS: 用于构建高效、可伸缩的服务端应用程序的渐进式 Node.js 框架。

Slogan 上我们可以看出, Egg更关注企业的维度,NestJS 更注重项目这个维度。

接下来是它们的学习体验。首先是 Egg

  1. 文档体验非常棒,毕竟是阿里开源,国人开发的框架,中文文档内容很丰富,使用过程中出现问题,可以很方便地找到对应的内容。
  2. 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习与协同成本。
  3. 使用的总人数虽然不比 NestJS,但胜在国人多,遇到问题可以咨询的人也会多一些。

接着是 NestJS

  1. 中文文档大部分的内容是中文直译,有些内容没有翻译完整或者翻译意境不对。另外,中文版本的内容也会落后英文版本很多,文档资料使用、学习起来会比较麻烦。
  2. 使用总人数虽然比 Egg 更多一些,但是在国内使用的人数不及 Egg,所以很多问题解答中文版本会少于 Egg

技术分析

Egg

  1. Egg 的底层框架是基于 Koa 开发,在性能与开发体验上会比 Express 更优越。
  2. 可选用 JS 以及 TS 开发,两者都是基于 Classify 开发,对刚接触服务端开发的前端更友好。
  3. 约定优于配置,减少开发负担、学习以及协作成本。
  4. 高度可扩展的插件机制,可以方便定制插件。
  5. 内置集群:使用 Cluster,自带进程守护、多进程以及进程间通讯等功能。

NestJS

  1. NestJS 的底层框架是基于 Express 开发的。
  2. 除了 Express 之外,NestJS 也支持使用 Fastify 作为底层框架。因为 NestJS 的设计理念本身就是一个框架适配器,其主要功能是代理中间件和处理器到适当的特定库应用中,从而达到框架的独立性。
  3. TS 编程并结合了 OOP(面向对象编程),FP(函数式编程)和 FRP(函数式响应编程)的元素,学习成本会高于 Egg,对新手前端友好度不高,再加上文档缺陷,劝退概率倍增。
  4. 模块加载方面使用 IoC 模式:模块容器 - 依赖注入(通过装饰器和元数据实现),开发效率以及维护性会更高。
  5. 整个框架的配套功能非常完善例如:鉴权、文档、微服务、CLI 工具等。

综合对比

NestJS 提供了更多的选择,更加自由以及更偏向后端开发的体验,而 Egg 作为深度定制过的框架,自定义的程度会弱于 NestJS,在团队初期快速开发业务的时候非常适合。

上述对比并不代表两个框架一定有个高下之分,针对于团队、项目的不同时期,开发人员的能力、喜好,哪一种框架能发挥最大价值,它就是当前对你来说最好的框架。

此外,使用 Egg 来对比 NestJS 并不是非常合适,两者的设计模式上有差别,理论上应该用另一款 IoC 框架 Midway 来对比,不过在 DevOps 小册中我们使用 Egg 作为开发框架,所以这本小册优先使用了 Egg 作为选型对比。

数据库选型

数据库部分,我们主要对比 MySQLMongoDB

典型的关系型数据库有事务回滚,它支持单点、集群部署架构,成熟度非常高。它作为开源数据库拥有非常全的文档与社区资源,出现问题能快速获得对应的帮助,后端首推数据库之一。

但是对于复杂读写操作,需要组合索引查询多表,对性能消耗不小,需要做读写分离或者表结构拆解,对业务架构设计要求比较高。

MongoDB 是非关系型数据库、nosql 的代表作。它可以通过副本集、分片实现高可用,在集群架构拥有十分高的扩展性,但要实现这种高可用对运维的要求比较高。

MongoDB 数据处理方式 是基于内存的,将热数据存在物理内存中,从而达到高速读写。由于性能出色,一般用在博客、内管管理等大数据存储的系统中较为合适。

总的来说,这两种数据库各有千秋,我们要根据不同的项目需求来选择合适的数据库。

在之前的架构设计中,我们一共需要开发 3 个系统,其中物料系统除了需要保存物料的版本信息之外,还需要存储 HTML 这种内容数据,所以在物料系统中使用 MongoDB 无疑是非常好的选择常规的项目如用户中心,针对于权限的管理非常复杂,所以选择 MySQL 使用多表关联来存储数据更为合适。

但是用户中心使用 MySQL 作为数据库的话,用户登录信息这种共用的数据就不可能保存在每个 pod,而且频繁的读取 MySQL 也不太实际。这个时候就需要使用 Redis 来做统一缓存,弥补关系型数据的缺陷。Redis 是一个高性能的 key-value 数据库,一般常用于业务数据缓存的操作。

写在最后

本章主要针对项目需求对技术选型做了一些介绍,对于 EggNestJS 的篇幅介绍较多,毕竟小册主要还是围绕 NestJS 展开的,其他工具详细的介绍与使用会在对应的篇幅再拓展。

此外,一个团队对技术的选择除了适配业务需求,也要考虑团队的整体水平与技术栈。例如,在团队后端的开发语言使用的是 Go,那么 CICD 工具选择 Jenkins 显然不是最优的选择,要考虑到使用与后期维护的问题。同样如果团队水平梯度不高的情况下,没有必要一定强上 NestJS,可以优先选用 Egg 这种对前端体验友好的框架,后期过度升级到 Midway 也是合理的技术规划。

如果你有什么疑问,欢迎在评论区提出或者加群沟通。 👏