背景
前段时间在学校为了赚点零花钱,主导设计和落地了一个小型项目,现在花点时间整理总结了一下后台部分的设计。限于篇幅不涉及具体代码,方法论和怎么做我觉得更重要。如果你现在也面临着小项目功能不算复杂、钱少、人手不足、时间紧的情况,那么希望这篇总结能给你带来启发和帮助。整个期间,遵循了几条基本原则:
- 使用顺手和开发效率高的语言,成熟的框架。php我不熟,略过。Java适合大型项目比较规范成熟,但开发起来太慢,略过。人生苦短,这里就选了Python 2.7,后台框架用的Flask最新版本。
- 尽量多使用成熟的第三方服务。因为人手少钱也不多,时间紧,使用第三方服务不管从功能完善性、安全性等角度来说,都是性价比最高的选择。比如支付模块,我们使用了ping++等。
- 能具备一定的扩展和伸缩性。如果使用者增多导致各种延时,能尽快地扩展后台性能。这就要求在最开始设计阶段要考虑到一定的扩展性能需求。但需在一定的限度内,不能过于把事情考虑复杂,不然就没法落地了。所以在某一定限度的性能扩展要支持,超过这个限度,我们可以假设那个时候整个系统已经被重构了。毕竟给多少钱,做多少事。
- 后台要注意安全性和逻辑性检查。后台开发应当有一种意识:app端就是一个显示模块,各种必需的判断和异常处理后台都应该存在,一切以后台处理为准。要多使用白名单模式,符合我格式的请求才处理;其它一概不管。这里也要有一定的度,执迷于各种复杂检查会拖慢项目进度,无法按时交付。数据库操作要尤其注意,一定要使用绑定参数来查询,防止sql注入攻击。
后台架构设计
后台设计后台全部依赖腾讯云,下面逐一进行下介绍:
- 云负载均衡。把所有app端打来的请求均匀地转发给后面自己配置的云主机。同时,经过调研可以设置app端和云负载均衡间的通信走https,而云负载均衡处理后再转发给后方的云主机是http请求。这里解决了数据传输过程中的安全问题,而且没有增加复杂性。
- Cloud Virtual Machine(云主机)。每个云主机上面部署了后台程序来真正处理请求。
- 云主机上整个后台的部署使用了:Nginx+Supervisor+Gunicorn+Gevent。Nginx做一些请求处理、缓存等,将请求转发给绑定到本地127.0.0.1地址上的Gunicorn。Gunicorn是支持wsgi协议的http server,默认使用同步阻塞的网络模型,那么这里会替换为Gevent异步模式,提升并发处理能力。Flask 程序就是一个wsgi应用,被Gunicorn托管。Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。我们使用Supervisor来启动Gunicorn。
- 云数据库MySQL。腾讯云租用的高可用MySQL集群,flask中配置好地址就ok。
- 云缓存Redis。腾讯云租用的Redis缓存,flask中配置好地址就ok。
这样的设计简单、稳定、高效,并提供了一定的扩展能力。假如一段时间之后,后台撑不住了各种延时,那么完全copy一台云主机(几分钟在管理界面就能购买一台云主机,然后通过脚本来部署完成),再在负载均衡中配置好转发就能立即提升后台的处理能力。如果数据库和缓存的性能有瓶颈,系统会自动报警,这时需要的可能就是在管理界面里花钱提升性能就好。毕竟在这种小中型项目中,没有什么问题是不能通过提升一倍服务器性能来解决的,如果有,那么就再提升一倍。
Flask应用结构
|-app
|-api_1_0 # 1.0版本
|-__init__.py
|-common.py # 具体的各种处理逻辑类
...
|-models.py # 数据库对应类定义
|-errors.py # 一些异常错误定义
|-__init__.py
|-logs # 日志
|-tests # 测试用例都在里面
|-test*.py
|-env # 虚拟环境
|-requirements.txt # 后台依赖的所有组件,便于在其它电脑生成相同的环境
|-config.py # 定义几套配置,开发环境、测试环境、生产环境,每套环境按需设置数据库地址啊等等
|-manage.py # 用于启动程序、进入shell调试模式、测试等等
|-README.md # 一定要把一些重要设计或者逻辑给记录下来,否则一段时间后就忘了,也方便其他人了解
|-update_and_run.sh # 后台更新脚本。在服务器上自动pull最新代码,安装依赖插件,再重新运行后台
开发过程中几点体会可以分享下:
- git很方便,这是编程必需技能,不会的一定得学一下。
- Flask很灵活自由,能随自己的需要随意选择插件,对新手来说可能会觉得不太友好。数据库操作我们用的Flask-SQLAlchemy插件,就是SQLAlchemy基础上的一个简单封装。ORM真的巨好用,能自动帮我们按参数查询,又将查询出来的结果自动转换为对象等。但是在一些复杂操作各种join时,我觉得反而复杂了,因为还要去深究它自己那套规则。所以我基本上是一些简单操作时用ORM来做,但一些复杂的操作就写sql语句来直接执行。而且我没有在代码中定义mysql表结构,是自己写sql语句来建表的,然后在flask中直接映射mysql数据库中已存在的表。我感觉这样更爽一点,但是这个全凭个人习惯、爱好来自主选择了。
- Unicode编码是个坑。flask内部处理的数据都是unicode编码,网上可调自动转utf8,但我没有成功,有个设置项但启动失败了。所以在数据格式转换上有点坑,都得encode('utf-8')一下。
- 最好多写下测试用例。每个接口基本要有个测试用例保证正常功能,每次开发完一个功能,都跑一次全部测试用例。没问题再合并到master分支,这样能最大程度防止影响到其它接口的代码,带来错误。而且用例只写一次,性价比还是蛮高的。
开发流程
可以简单说下我们合作开发的流程,git服务我们使用了国内的Coding。
- 认领成功某功能后,从master分支创建新分支,切换到新分支进行相应功能开发;
- 新功能调试完成没有问题后,写下对应的测试用例保证功能,在全部测试用例通过后;
- 更新master分支代码,在新分支下merge master分支,解决可能的冲突;
- 切换到master分支,在master分支下merge新分支;
- 最后将master分支push。
开发服务器上跑着master分支的稳定代码,可供所有人调用和调试,可以自动化来部署:
- Coding上设置每次push都给开发服务器某端口发送消息;
- 在开发服务器上开个服务监听该端口,收到push的消息就执行一次update_and_run.sh脚本。脚本在服务器上自动pull最新代码,然后安装依赖插件,再重新运行后台。
总结
- 因为各种原因项目方有点坑,后台现在并没有按上面的设计来搞,所以当前就是在一台云主机上部署了所有。Nginx做反向代理到本地端口,Gunicorn在本地端口监听,mysql和redis都在本地。不过对于自用或者使用者不多的系统来说,也够了。
- 设计和实现了一把后台。在构思整个后台功能阶段,其实就是设计整个app的功能时,体会到了做产品经理的不容易。包括数据库设计这块,需要什么样的数据?怎么存?怎么操作?怎么来实现后台逻辑和功能?这一系列问题都需要一定的计算机基础和整体把控,还是蛮有趣蛮有挑战性的,每一次都能学到很多新东西。
- 对后台开发这块这次负责的比较多,还是挺有意思的。后台看不见,没前端那么风骚,但承载了所有功能,是整个软件的核心。而且后台想要做得好,还是蛮难的。各种并发、重复请求处理、安全性处理、逻辑判断、数据库操作优化等等,需要耗费大量的精力去做。特别是高并发这块,好的系统怎么设计和优化?像微信这样的随便就是上亿、上千万的请求,可不是加点服务器就能解决得好的,觉得好牛逼。刚好微信也在广州,希望自己以后多看多学吧,加油~
网友评论