一次小型App后台架构设计与实现

背景

前段时间在学校为了赚点零花钱,主导设计和落地了一个小型项目,现在花点时间整理总结了一下后台部分的设计。限于篇幅不涉及具体代码,方法论和怎么做我觉得更重要。如果你现在也面临着小项目功能不算复杂、钱少、人手不足、时间紧的情况,那么希望这篇总结能给你带来启发和帮助。整个期间,遵循了几条基本原则:

  1. 使用顺手和开发效率高的语言,成熟的框架。php我不熟,略过。Java适合大型项目比较规范成熟,但开发起来太慢,略过。人生苦短,这里就选了Python 2.7,后台框架用的Flask最新版本。
  2. 尽量多使用成熟的第三方服务。因为人手少钱也不多,时间紧,使用第三方服务不管从功能完善性、安全性等角度来说,都是性价比最高的选择。比如支付模块,我们使用了ping++等。
  3. 能具备一定的扩展和伸缩性。如果使用者增多导致各种延时,能尽快地扩展后台性能。这就要求在最开始设计阶段要考虑到一定的扩展性能需求。但需在一定的限度内,不能过于把事情考虑复杂,不然就没法落地了。所以在某一定限度的性能扩展要支持,超过这个限度,我们可以假设那个时候整个系统已经被重构了。毕竟给多少钱,做多少事。
  4. 后台要注意安全性和逻辑性检查。后台开发应当有一种意识: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。

  1. 认领成功某功能后,从master分支创建新分支,切换到新分支进行相应功能开发;
  2. 新功能调试完成没有问题后,写下对应的测试用例保证功能,在全部测试用例通过后;
  3. 更新master分支代码,在新分支下merge master分支,解决可能的冲突;
  4. 切换到master分支,在master分支下merge新分支;
  5. 最后将master分支push。

开发服务器上跑着master分支的稳定代码,可供所有人调用和调试,可以自动化来部署:

  1. Coding上设置每次push都给开发服务器某端口发送消息;
  2. 在开发服务器上开个服务监听该端口,收到push的消息就执行一次update_and_run.sh脚本。脚本在服务器上自动pull最新代码,然后安装依赖插件,再重新运行后台。

总结

  1. 因为各种原因项目方有点坑,后台现在并没有按上面的设计来搞,所以当前就是在一台云主机上部署了所有。Nginx做反向代理到本地端口,Gunicorn在本地端口监听,mysql和redis都在本地。不过对于自用或者使用者不多的系统来说,也够了。
  2. 设计和实现了一把后台。在构思整个后台功能阶段,其实就是设计整个app的功能时,体会到了做产品经理的不容易。包括数据库设计这块,需要什么样的数据?怎么存?怎么操作?怎么来实现后台逻辑和功能?这一系列问题都需要一定的计算机基础和整体把控,还是蛮有趣蛮有挑战性的,每一次都能学到很多新东西。
  3. 对后台开发这块这次负责的比较多,还是挺有意思的。后台看不见,没前端那么风骚,但承载了所有功能,是整个软件的核心。而且后台想要做得好,还是蛮难的。各种并发、重复请求处理、安全性处理、逻辑判断、数据库操作优化等等,需要耗费大量的精力去做。特别是高并发这块,好的系统怎么设计和优化?像微信这样的随便就是上亿、上千万的请求,可不是加点服务器就能解决得好的,觉得好牛逼。刚好微信也在广州,希望自己以后多看多学吧,加油~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,565评论 25 707
  • 22年12月更新:个人网站关停,如果仍旧对旧教程有兴趣参考 Github 的markdown内容[https://...
    tangyefei阅读 35,127评论 22 257
  • 石榴树,南方最爱的树种。 吃石榴是一件最打发时间的事情,要一颗颗摘下,洗干净,要一颗颗细细的品尝,囫囵吞枣会失去一...
    迷鹿小魔女阅读 1,156评论 0 1
  • 小溪从山中而来,由三股汩汩涌出的泉水汇集而成。至于泉水从哪一年涌出,无人知晓,是一个遥远的谜。 小溪在森林...
    念清思雨阅读 1,068评论 2 2