前言

最近与友人AtmosphereMao一同接了一微信小程序的活,途中出现了一些小小意外,故以此总结经验。

整活场景

开发的项目为XX报名系统,用于解决招生录取问题。

最初先是完成后端的基本功能开发(5月18日);前端是在后端基本完成后(5月27日左右)开始开发。

直至今天(6月17日),项目经过了多番整改,终于趋于完成。

技术使用

  • 后台

    • ThinkCMF(基于ThinkPHP的内容管理框架)
  • 前台(小程序)

    • WePY(腾讯开发的小程序组件化开发框架)

初版需求

以下是最初理解的需求,显然很简单。

  • 后台

    • 基本的CRUD功能
    • 根据不同的类别进行数据统计
    • 针对不同类别的报名开关
  • 前台(API)

    • 录入报名数据
    • 查询报名信息
    • 查询录取信息

由于本人只负责后端实现,故前台只提供API。

无尽整改

按照前面所展示的初版需求,理论上几天就能完成基本功能;但显然现实不会按预想的来。

首先,得到的需求是不清晰的,客户也不知道具体要如何实现。

所以就出现了做完功能之后,让客户查阅后再根据意见修改,导致开发流程断断续续的情况。

后面追加的3个需求,更是使程序复杂程度直线上升。(从简单的CRUD项目变成复杂的文档处理项目)

追加:录取通知书

最初是以文件上传的形式实现,如上传图片/文档。

但是后来客户不满意,需要支持模版,例如根据docx,自动给每个学生生成录取通知书。

  • 但如果从追加需求的时候,就明确需要支持模版,那前面做的上传功能就不会白忙活了。

同时录取通知书需要导出为pdf格式,当时图方便直接就在docx生成完成后接入了pdf转换功能;然而,此处设计不当为后面并发崩溃埋下了祸根。

追加:批量导出/导入数据

干就完了,像这种追加的高强度体力活需求,只能要求增加报酬。

追加:报名表下载

报名表为xls格式,与录取通知书一致,需要根据模版生成pdf。

  • 由于没有轮子,需要自行实现excel模版替换功能。

Bug:并发情况下崩溃

如前文所言,报名表以及录取通知书需要导出PDF。

最初的实现是用户访问文档API时,直接生成相应文档并导出PDF再返回给用户。

然而在大量并发的情况下,LibreOffice进程会直接被打到崩溃,再起不能。

  • 同时发出200个请求,只能成功生成2个文件。

这里可能会有个疑问,为什么需要LibreOffice;原因很简单,PHP原生支持的dompdf/mpdf过于篮子,无法正常使用,只能通过PHP->Python(unoconv)->LibreOffice的外挂方式实现PDF转换。

所以当时我发文diss了一把PHP。

为了解决这个问题,肝了一通宵终于解决,同时程序的复杂程度又进一步的提升了。

Bug:数据编辑/删除不完全

  • 这个问题是因为没有使用事务。这是没认真学数据库的后果。

Bug:生僻字无法录入

[10501]SQLSTATE[HY000]: General error: 1366 Incorrect string value: '\xF0\xA3\x84\x83\xE8\x83...' for column 'xxx' at row 1
  • 这个问题是MySQL的毒瘤utf8导致的,换成utf8mb4就好了。

解决方案

将用户请求以及文档下载分开处理。

用户请求文档则添加一个任务到数据库,后台使用专门的进程逐个任务进行处理。

  • 使用ThinkPHP的Command控制器配合Shell实现。

这下子成功扛下了200+的请求,怪一开始没设计好。

整改:细枝末节

由于客户也没提供样板/设计图;所以像这类整改,多到3页纸都写不完。(已经无力吐槽)

  • 这真是一段艰辛的时光。
    • 改n个地方,增加n*m个Bug
    • 根据需求改完又改,一改再改
    • 客户自己没搞清楚逻辑,提出错误的整改内容
    • ...

前端对接

由于前端由友人AtmosphereMao完成,我是比较放心的,一般情况下能接活便是有着十足的把握。

API文档以及测试,我们采用友人XuQing之前跟我提到的EOLINKER,该工具相当好用,非常便于团队协作;可谓是国产Postman

有了这工具,我们对接的情况可谓是顺风顺水,没什么难度。

Deadline意外

然而这个项目的前端需求也并不省心,同样是一改再改;改得多了嘛,就容易出现纰漏。(字段极多)

终于,在临近deadline的时候发生了严重意外,修改完前端工程后忘记commit/push就下线了。

  • 此时,客户更改了需求内容,在代码仓库中的程序仍是旧版本。

尽管需求更改的内容很简单,只是改个文本,但之前也有一连串的需求改动,由于无法获得最新的代码,所以不熟悉wepy框架的我自然是无法更新前端工程的。

幸运的是,最后赶在deadline之前发布了正式版。

总结

最终,这个面包车硬生生做成了坦克。

  • 客户的需求是多变的,在需求不清晰的情况下要衡量好是按自己的想法实现或是与客户详细沟通再实现
    • 否则就会出现做了白做的问题 ,但是沟通成本高啊
  • 在团队协作项目中,一定要做好版本管理,代码修改完,马上commit & push是最基本的要求。
    • 否则在意外情况下无法联系时,团队其他技术人员无法及时补锅。
  • 保持通讯环境畅通,在接近deadline时不要出现人间蒸发的情况。

可优化项

  • 针对每个API编写相关测试代码,不完整测试可能会导致Bug越改越多。
    • 难怪EOLINKER测试功能收费;听说业内公司,一般开发和测试人数一比一。
  • 学习业内对于并发高负载任务的解决方案,目前的方案过于Hack,泛用性不足。
    • 这种场景,好像是要用消息队列来着
  • 学习更多前端相关知识,否则无法给前端补锅。
    • 去做前端咯