《架构师》2019年11月
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

设计

很多朋友可能会问,我为什么要把设计放在编写代码与完成测试之后?好吧,设计在实际流程中可能比较靠前,但如果没有在当前环境中进行编码与测试,我个人很难设计出一套能够与特定环境完美适配的系统。在设计系统时,我们需要考虑很多问题,包括:

· 资源使用量是多少?

· 存在多少用户?预计用户会以怎样的速度增长?(这将直接决定未来存在多少数据库行)

· 未来可能出现的陷阱是什么?

我需要把这些转化成一份名为“要求汇总”的清单。目前我还没有积累到充分的相关经验,根据计划,明年我的工作内容就是着力解决这方面问题。

这个过程有点违背敏捷原则——在开始实施之前,我们能够做出多少设计判断?这是个权衡问题,我们需要选择在怎样的时间点上做什么。我们什么时候该深入剖析,又该在什么时候退后一步进行规划?

当然,这里收集到的要求不需要也不可能真正全面。我认为把开发的过程纳入设计考量也是完全可行的,例如:

· 本地开发将如何运作?

· 我们如何打包及部署?

· 我们如何进行端到端测试?

· 我们如何对这项新服务进行压力测试?

· 我们如何管理保密信息?

· 我们如何实现CI/CD集成?

我们最近为BNEF开发出一套新的搜索系统,这方面工作也给了我们很大的启发。我们必须设计出本地开发流程、思考DPKG方法(打包与部署),同时确保敏感信息不致外泄。

那么,为什么把保密信息引入生产环境可能引发问题?

1.我们不能将其直接添加到代码当中,否则任何人都能够直接查看。

2.是否应该将其作为环境变量,如同12因素应用所要求的那样?这确实是个好办法,但我们该如何实现?(在每次机器启动时都访问生产设备以填充环境变量,绝对是个痛苦的过程。)

3.将其部署为保密文件?那么该文件来自哪里?又该如何填充?

最后,整个过程当然不可能手动实现。

总而言之,我们使用了具有角色访问控制机制的数据库(只有我们的机器以及我们自己能够与该数据库通信)。我们的代码会在启动时从该数据库处获取保密信息。这部分信息能够在开发、beta测试以及生产环境之间顺畅复制,且各自保留在对应的数据库当中。

这里要再提一句,AWS等各家云服务供应商提供的具体方案可能有所区别。大家不用为保密信息费多少心。获取角色账户、在UI当中输入保密信息,而后即可确保代码在需要时获取其内容。这些服务能够显著简化整个流程,但之前的探索也并没有白费——我很高兴自己能够真正理解并欣赏这种简洁的解决方案。

在设计当中考虑维护要求

设计系统令人兴奋,但维护呢?恐怕就没什么成就感可言了。

在维护系统的过程中,我想到了这样一个问题:我们为什么要进行系统降级,又该如何实现系统降级?

第一部分的答案是,因为总有人不爱丢弃陈旧的部分,而是添加新的部分。厚古而薄今,至少我自己就有这样的毛病。

至于第二部分,答案是我们在进行系统设计时提出的终极目标,后续可能不再适用。在系统的发展当中,其很可能会以与设计假设相冲突的方式进行使用,这意味着我们当初做出的一切预期需求都不再有效。这时候我们就需要后退一步,层层剥离那些不再适用的部分。

目前,我至少知道三种能够降低降级率的办法。

1.保证业务逻辑与基础设施彼此分离:一般来说,需要降级的往往基础设施部分——例如使用量增加、框架过时、出现零日漏洞等等。

2.围绕维护需求设计流程。对新代码与旧代码采用同样的更新手段,从而防止新旧之间出现差异,确保代码整体保持“现代”特性。

3.始终坚持去掉一切不需要的/陈旧的代码。