设计
很多朋友可能会问,我为什么要把设计放在编写代码与完成测试之后?好吧,设计在实际流程中可能比较靠前,但如果没有在当前环境中进行编码与测试,我个人很难设计出一套能够与特定环境完美适配的系统。在设计系统时,我们需要考虑很多问题,包括:
· 资源使用量是多少?
· 存在多少用户?预计用户会以怎样的速度增长?(这将直接决定未来存在多少数据库行)
· 未来可能出现的陷阱是什么?
我需要把这些转化成一份名为“要求汇总”的清单。目前我还没有积累到充分的相关经验,根据计划,明年我的工作内容就是着力解决这方面问题。
这个过程有点违背敏捷原则——在开始实施之前,我们能够做出多少设计判断?这是个权衡问题,我们需要选择在怎样的时间点上做什么。我们什么时候该深入剖析,又该在什么时候退后一步进行规划?
当然,这里收集到的要求不需要也不可能真正全面。我认为把开发的过程纳入设计考量也是完全可行的,例如:
· 本地开发将如何运作?
· 我们如何打包及部署?
· 我们如何进行端到端测试?
· 我们如何对这项新服务进行压力测试?
· 我们如何管理保密信息?
· 我们如何实现CI/CD集成?
我们最近为BNEF开发出一套新的搜索系统,这方面工作也给了我们很大的启发。我们必须设计出本地开发流程、思考DPKG方法(打包与部署),同时确保敏感信息不致外泄。
那么,为什么把保密信息引入生产环境可能引发问题?
1.我们不能将其直接添加到代码当中,否则任何人都能够直接查看。
2.是否应该将其作为环境变量,如同12因素应用所要求的那样?这确实是个好办法,但我们该如何实现?(在每次机器启动时都访问生产设备以填充环境变量,绝对是个痛苦的过程。)
3.将其部署为保密文件?那么该文件来自哪里?又该如何填充?
最后,整个过程当然不可能手动实现。
总而言之,我们使用了具有角色访问控制机制的数据库(只有我们的机器以及我们自己能够与该数据库通信)。我们的代码会在启动时从该数据库处获取保密信息。这部分信息能够在开发、beta测试以及生产环境之间顺畅复制,且各自保留在对应的数据库当中。
这里要再提一句,AWS等各家云服务供应商提供的具体方案可能有所区别。大家不用为保密信息费多少心。获取角色账户、在UI当中输入保密信息,而后即可确保代码在需要时获取其内容。这些服务能够显著简化整个流程,但之前的探索也并没有白费——我很高兴自己能够真正理解并欣赏这种简洁的解决方案。
在设计当中考虑维护要求
设计系统令人兴奋,但维护呢?恐怕就没什么成就感可言了。
在维护系统的过程中,我想到了这样一个问题:我们为什么要进行系统降级,又该如何实现系统降级?
第一部分的答案是,因为总有人不爱丢弃陈旧的部分,而是添加新的部分。厚古而薄今,至少我自己就有这样的毛病。
至于第二部分,答案是我们在进行系统设计时提出的终极目标,后续可能不再适用。在系统的发展当中,其很可能会以与设计假设相冲突的方式进行使用,这意味着我们当初做出的一切预期需求都不再有效。这时候我们就需要后退一步,层层剥离那些不再适用的部分。
目前,我至少知道三种能够降低降级率的办法。
1.保证业务逻辑与基础设施彼此分离:一般来说,需要降级的往往基础设施部分——例如使用量增加、框架过时、出现零日漏洞等等。
2.围绕维护需求设计流程。对新代码与旧代码采用同样的更新手段,从而防止新旧之间出现差异,确保代码整体保持“现代”特性。
3.始终坚持去掉一切不需要的/陈旧的代码。