这是《nestjs搭建通用业务框架》系列的第6篇,本篇带领大家升级nestjs中默认的web服务器Express,改成高性能的 fastify。
前言
本篇主要的目的,是搭建一个高性能的web服务器,便于后续开展通用业务(鉴权)的开发。
深入fastify
以下列出的是 Fastify 已经实现的主要功能及原理:
- 高性能: 据我们所知,Fastify 是这一领域中最快的 web 框架之一,另外,取决于代码的复杂性,Fastify 最多可以处理每秒 3 万次的请求。 
- 可扩展: Fastify 通过其提供的钩子(hook)、插件和装饰器(decorator)提供完整的可扩展性。 
- 基于 Schema: 即使这不是强制性的,我们仍建议使用 JSON Schema 来做路由(route)验证及输出内容的序列化,Fastify 在内部将 schema 编译为高效的函数并执行。 
- 日志: 日志是非常重要且代价高昂的。我们选择了最好的日志记录程序来尽量消除这一成本,这就是 Pino! 
- 对开发人员友好: 框架的使用很友好,帮助开发人员处理日常工作,并且不牺牲性能和安全性。 
- 支持 TypeScript : 我们努力维护一个 TypeScript 类型声明文件,以便支持不断成长的 TypeScript 社区。 
改良性能
在阅读与实践本部分的时候,一定要清晰的清楚自己的目标:提升接口的性能。如果,在已经成型的nest(Express)项目中,如果要进行Express -> Fastify的操作,一定要注意Express的中间件与Fastify可能不兼容,会导致切换失败。所以,在最初设计框架的时候就应该考虑到两个框架的优缺点,来进行选择。
| 框架 | 优点 | 缺点 | 
|---|---|---|
| Express | 文档丰富,生态丰富 | 性能相对较差,笨重 | 
| Fastify | 性能优,轻量 | 学习与使用成本 | 
总结:Fastify对于初学者来说,学习成本与Express一致,所以建立直接上手。Express对于熟悉http模块的同学来说,上手成本低。对于性能有要求的场景,Fastify是大家不二的选择。
在nest中默认会使用Express框架,作为web服务器的底层服务。为了提升性能的需求,nest提供了其他库的兼容性,例如Fastify
Fastify的性能是优于Express的,见下表:
测试环境: EX41S-SSD, Intel Core i7, 4Ghz, 64GB RAM, 4C/8T, SSD.
方法:autocannon -c 100 -d 40 -p 10 localhost:3000 * 2, taking the second average
| 框架 | 版本 | 是否有路由功能? | 请求/秒 | 
|---|---|---|---|
| Express | 4.17.1 | ✓ | 15,978 | 
| hapi | 19.1.0 | ✓ | 45,815 | 
| Restify | 8.5.1 | ✓ | 49,279 | 
| Koa | 2.13.0 | ✗ | 54,848 | 
| Fastify | 3.0.0 | ✓ | 78,956 | 
| - | |||
| http.Server | 12.18.2 | ✗ | 70,380 | 
数据测试库fastify/benchmarks
集成步骤:
- 安装依赖 - @nestjs/platform-fastify- 1 - npm i --save @nestjs/platform-fastify 
- 配置适配器 - 安装 fastify 后,我们可以使用 - FastifyAdapter,修改- src/main.ts文件- 1 2 3 4 5 6 7 8 9 10 11 - import { NestFactory } from '@nestjs/core'; import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; import { ApplicationModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create<NestFastifyApplication>(ApplicationModule, new FastifyAdapter()); // 默认情况下,`Fastify`仅在 `localhost 127.0.0.1` 接口上监听 // 改成 0.0.0.0 接受其他主机上的连接 await app.listen(3000, '0.0.0.0'); } bootstrap();
- 运行 - npm run start:dev,打开- localhost:3000验证服务是否OK。
看Hello world,或者打印出来如下信息:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [下午8:43:23] File change detected. Starting incremental compilation...
[下午8:43:23] Found 0 errors. Watching for file changes.
[Nest] 4682   - 2021/03/24 下午8:43:24   [NestFactory] Starting Nest application...
[Nest] 4682   - 2021/03/24 下午8:43:24   [InstanceLoader] DatabaseModule dependencies initialized +44ms
[Nest] 4682   - 2021/03/24 下午8:43:24   [InstanceLoader] TypeOrmModule dependencies initialized +1ms
[Nest] 4682   - 2021/03/24 下午8:43:24   [InstanceLoader] ConfigHostModule dependencies initialized +0ms
[Nest] 4682   - 2021/03/24 下午8:43:24   [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 4682   - 2021/03/24 下午8:43:24   [InstanceLoader] ConfigModule dependencies initialized +1ms
[Nest] 4682   - 2021/03/24 下午8:43:24   [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 4682   - 2021/03/24 下午8:43:24   [InstanceLoader] ConfigModule dependencies initialized +0ms
query: START TRANSACTION
query: SELECT * FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = 'nest-common' AND `TABLE_NAME` = 'typeorm_metadata'
query: COMMIT
[Nest] 4682   - 2021/03/24 下午8:43:25   [InstanceLoader] TypeOrmCoreModule dependencies initialized +118ms
[Nest] 4682   - 2021/03/24 下午8:43:25   [RoutesResolver] AppController {}: +8ms
[Nest] 4682   - 2021/03/24 下午8:43:25   [RouterExplorer] Mapped {, GET} route +3ms
[Nest] 4682   - 2021/03/24 下午8:43:25   [NestApplication] Nest application successfully started +3ms | 
就OK了。
关于路径别名
我们常见的用法,比如:@代表src
在nest项目中配置路径别名比较简单,可以在tsconfig.json中添加paths属性:
| 1 2 3 4 5 6 7 8 9 10 11 12 | {
  "compilerOptions": {
    // ....
    // 添加如下内容
    "paths": {
      "@/*": [
        "src/*"
      ],
    }
  },
  // ...
} | 
然后,重新使用npm run start:dev进行测试即可。
后面,项目目录再深,也好写文件路径了,再也不用看到../../../无穷无尽的关联路径了。
共同学习,写下你的评论
评论加载中...
作者其他优质文章
 
                 
             
			 
					 
					