Skip to content

inlym/life-helper-backend

Repository files navigation

life-helper-backend

「我的个人助手」主要用于为用户提供一些日常使用的小工具,包含天气查询、日程管理、事项提醒等功能。

相关仓库

服务端

仓库(当前仓库)地址: life-helper-backend

技术栈: Node.js + Nest.js + TypeScript + Typeorm + MySQL + Redis + Docker

小程序端

仓库地址: life-helper-miniprogram

技术栈: 原生小程序 + 自定义的一套框架加强工具

Web 端

仓库地址: life-helper-frontend

技术栈: Angular + TypeScript + Sass + RxJS + Swagger + Webpack

Web 地址: 我的个人助手

项目架构

以下是当前项目的技术架构,可供读者参考。

本地开发环境

本地开发环境主要用于新功能开发的前期阶段,就在当前开发的电脑部署环境,MySQLRedis 等服务也是自建的。

测试环境

本地开发到了较为成熟的阶段,会将代码进行提交在测试环境部署,测试环境用的是一台低配具有公网 IP 的阿里云服务器,MySQLRedis 等资源购买的是阿里云的服务。

预发布环境

预发布环境处理运行代码的服务器以外,其他服务直接连生产环境的资源,用于临上线前的最后一道测试。

生产环境

基本原则

  1. 尽量使用阿里云封装好的服务,缺点是贵,但有点是免运维,比自己部署稳定的多。例如:API 网关、负载均衡等中间件。
  2. 使用阿里云云效(Codeup)进行自动化部署,尽量避免手工上线。

技术架构

网关层
  1. 服务端 URL: https://api.lifehelper.com.cn
  2. 使用阿里云 API 网关 承接 HTTP 请求,不将内部服务器直接暴露在公网上。
  3. 使用阿里云 API 网关 自带的 摘要签名认证 对 HTTP 请求进行基本鉴权,保证只有我方客户端发起的 HTTP 请求才进行转发,其他非法请求全部进行拦截。
  4. 将合法请求转发至阿里云 负载均衡
  5. API 网关 后的所有服务,均部署在阿里云 专有网络 VPC ,与公网不互通。
转发层
  1. 合法请求由 API 网关 转发至 负载均衡 服务,再由 负载均衡 转发至服务器组上。
  2. 服务器组按照配置情况使用 加权轮询 调度算法进行请求分配。
服务器组
  1. 尽量遵循 “低配多台” 的原则配置服务器,即:低配置的多台服务器的综合性能优于同价格的高配置服务器。
Web 端
  1. Web 端 URL: https://www.lifehelper.com.cn
  2. 使用 CDN + OSS 的架构承接 Web 端服务。关于如何让 OSS 支持单页应用请看这篇文章 —— 《如何让 OSS 支持单页应用》
使用到的阿里云服务
  1. API 网关
  2. 负载均衡
  3. 专有网络
  4. 云服务器
  5. MySQL
  6. Redis
  7. 表格存储
  8. 日志服务
  9. CDN
  10. 对象存储
  11. 短信服务
  12. DNS 解析

最佳实践

模块

根模块(root module)

  1. 根模块全局只有一个,路径 src/app.module.ts
  2. 根模块负责引入特性模块和配置全局中间件。

特性模块(feature module)

  1. 按照对应功能划分模块,以模块为单位进行封装,该模块称为 “特性模块”。
  2. 特性模块放在 src/modules/ 目录下,每个模块一个同名目录。
  3. 该功能对应的 controllerservicemodelinterface 等文件等放置在该特性模块内,无需再建二级目录。
  4. 不要在特性模块的控制器(controller)中直接使用共享模块的服务,而应该自建一个服务,在该服务内使用共享模块的服务,哪怕只有一行代码也要这样做。
  5. 每个 *.controller.ts 均对应一个同名 *.dto.ts 文件,该文件下均使用类(class)进行定义。
  6. 特性模块之间不允许相互引用,只允许引用共享模块。

共享模块(shared module)

  1. 将可能被多个特性模块用到的服务以及涉及第三方 API 的服务剥离出来,统一放置在共享模块下。
  2. 共享模块目录 src/shared/
  3. 共享模块中的每个服务均需要完整测试用例。
  4. 共享模块仅被需要的特性模块引入,不要引入根模块。
  5. 共享模块内不得建立 *.controller.ts*.dto.ts 文件。

特性模块目录结构

  1. 以特性模块的 业务名 作为目录名称,一律使用 小写 英文字符,使用短横线(-)分隔,所有该业务相关文件均放置于该目录下。
  2. 业务模块内应至少包含一个控制器,以及和控制器同名的 DTO 文件(*.controller.ts*.dto.ts 文件一一对应)。
  3. 比较大的子模块应新建子目录。

目录示例(假设业务名为 my-feature):

my-feature/
│
├── my-feature.service.ts          # 主要
│
├── my-feature-a.controller.ts       # 控制器,每个业务模块至少对应一个控制器
├── my-feature-a.dto.ts              # DTO 文件,与同名控制器一一对应
│
├── my-feature-b.controller.ts       # 控制器,每个业务模块至少对应一个控制器
├── my-feature-b.dto.ts              # DTO 文件,与同名控制器一一对应
│
├── ...
│
├── feature-one/
│   ├── feature-one.service.ts
│   ├── feature-one.interface.ts
│   ├── feature-one.entity.ts
│   └── feature-one.model.ts
│
├── feature-two/
│   ├── feature-two.service.ts
│   ├── feature-two.interface.ts
│   ├── feature-two.entity.ts
│   └── feature-two.model.ts
│
└── ...