记从0到一周内快速上线的项目
介绍
最近一周多肝了一个排疫系统,从 0 到正式上线,包括了小程序 + 三个移动端用户模块 + 两个后台管理系统,实在是肝疼。项目的开发就两个人从刀耕火种开始orz。在系统层面,整个项目保证了业务的可用性,并且包含了基本可用的服务监控,日志记录等功能,同时支持业务量继续增大时的水平横向扩展,还手写了个简陋的自动化部署脚本来实现蓝绿发布。不得不说,就算是个人开发,没有完善的基础设施,靠着各种云上的基础服务也能基本做到快速迭代上线了,该有的功能都有了。
最近一周手忙脚乱,就记录一下整个项目的开发和收获吧,如何在有限的时间内尽可能的提升开发速度,以及如何快速低成本的方法保证线上服务的稳定性。
技术选型
开发共计两个人,为了快速开发,肯定就选最熟悉的一套技术栈就完事了,JS 一把梭。前端直接用了 Vue + element-ui,同时做了一些优化来直接适配移动端,后端服务采用 Node.js + Mongodb + Redis 进行快速开发。简单的理解需求就是两个管理后台来输入数据,如通过 excel 导入或直接新增,并且管理各种用户数据。而移动端则基于这些数据为特定人群提供定制化的服务,此外需求还会随着时间不断变化,因此该项目无论是前端还是后端都有较大的工作量。
项目架构
项目给配了 SLB,后端给了两台 ECS,没有 CDN,没有 OSS。为了方便项目快速开发迭代,我们考虑直接把完整的前后端应用都在 ECS 上部一套,并且写了个自动化部署的脚本,在保证所有后端服务无状态的情况下,可以在用户量增大时方便的进行水平扩容。
SLB
所有请求走 SLB 做四层负载均衡到达 ECS。同时 SLB 来处理 https 协议的解析和 http 重定向到 https。此外,利用 SLB 的健康检查机制,可以在没有其他基础设施的情况下,很方便的实现平滑的蓝绿发布。
ECS
每台 ECS 都部署完整的前后端服务。通过 Nginx 代理静态资源,同时对 Node.js 服务做反向代理。简单的 node 进程性能的监控直接用 pm2 monitor 来查看了,同时接入了阿里云 SLS 日志服务,收集了每台 ECS 上的 nginx 日志,同时在 Node.js 项目中对关键性操作记录进行日志打点。
实现了自动化的部署脚本,来配置每台 ECS 的依赖环境,拉取 git 代码,自动部署服务。
MongoDB 集群
多节点副本集保证服务的高可用,同时写了个定时脚本,每天定时备份 MongoDB 数据。
Redis 集群
主要做热点数据的缓存,以及 Node.js 服务集群间的状态同步,比如手机验证码服务,定时任务,回调任务等。
系统架构图
业务快速开发
作为一个排疫系统,开发时间紧迫,而且政策还老是变,太难了。
前端
VUE + Element-ui 可以很方便的开发管理后台的项目。但是项目的管理员也会有用手机操作管理后台的需求,因此我们对 Element-ui 做了一些移动端的优化。此外,基于 VUE,可以快速的实现一些业务功能,而整个系统没有非常复杂的前端业务逻辑,因此可以保证一定的开发速度。
小程序
显而易见,小程序如果再单独做一套原生的,一周肯定来不及,所以直接内嵌 WebVIew 做了个首页导航页面来实现。
后端
直接用了我比较熟悉的 Node.js。之前我也有写过一个基于 KOA 的轮子 koa-swagger-decorator(https://github.com/Cody2333/koa-swagger-decorator) 集成了接口参数校验和 swagger 接口文档生成。
不得不说这个库非常适合这种需要光速开发的项目,同时还能提供实时同步的接口文档,大大提升了开发的效率。采用 MongoDB 主要也是因为它的方便,没什么复杂事务的需求,业务中的字段还会不断增删改,修改起来方便了很多。
Node.js 服务水平扩容
文件上传下载
实现水平扩容核心就是保证服务的无状态。项目没有提供 OSS 数据存储,本身也只有上传导出 excel 的文件功能,因此基于 stream 的上传下载文件就能满足需求。
下载流时序图
定时任务
分布式集群的 Node.js 服务需要依赖外部的服务来做各个进程间的状态同步。对于集群部署的 Node.js 应用,我们需要保证每次只有一个进程执行一次定时任务即可,防止定时任务的重复执行。最简单的解决方法就是引入 Redis 的分布式锁(redlock)来保证只有一个进程来执行定时任务。
线上发布流程
项目不仅上线的很匆忙,功能需求还会变,所以基本上每天都得发布多个版本。所以要简单解决这几个问题:
线上服务的平滑升级
由于有两台 ECS 全量部署了我们的服务,所以我们可以来做蓝绿部署,先下线一台 ECS 部署新服务,部署完成后再加入 SLB,保证线上服务在发布升级的时候不会中断。
部署流程图
我采用了最方便的方法,利用 SLB 的健康检查接口来做平滑的升级部署。如果直接停掉一台服务器,那么 SLB 依然需要多次的健康检查判断才会摘除下线服务器,这会导致有一部分流量的请求产生 502 错误。此外,就算没有新的流量,我们依然要等待现有连接的请求处理完再优雅的下线服务。因此,先将健康检查接口返回错误,等待一段时间后再停服务就算是一种简单的实现了。
线上服务监控
项目的服务商给了服务器,但没有给控制台的权限,所以就只做了一些简单的监控,这部分还很不完善。 Node 应用就用了 PM2 自带的 monitor 来监控。主要接了阿里云的 SLS 来做日志的收集和分析,保证出现异常的时候能快速定位问题。
- PM2 Monitor
- SLS 日志
- TODO
存在的问题
- 缓存问题。因为发版很快,功能变化频繁,而微信浏览器和小程序 webview 中的缓存比较顽固,这个短时间没找到很好的解法,只能尽量保证服务升级时对于原有业务的兼容性,保证后端服务可回滚可灰度。
- 浏览器兼容性问题。依然时间所限,也没有那么多设备测试,只能提个问题解决一个。
最后
随便想到什么就写了点东西。感谢队友。