2020-01-12
首先遵循Dry原则,意思就是don’t repeat yourself,不要自己做重复的事情。
意识形态要正确:那就是软件是由开发者控制的。开发者需要控制软件,而不是反过来,让管理者、产生负责人控制软件。 唯一能控制软件的人就是编写它们的人。
对软件所做的任何变更都应该是简洁快速的,并且是将系统从一个稳定点移动到另一个稳定点。宁可少完成一些内容,但要保证完成的部分质量优秀。一旦部署的内容中有错误,就会影响到生产数据,修复起来代价极高。最糟的情况下,甚至必需重置多年来的数据,这样十分浪费时间。
项目中每引入一个不确定因素都是赌博。选择新编程语言是赌博,使用新框架是赌博,采用新的应用部署方式是赌博,了解哪些作法是在冒险,哪些是软件的稳定因素,这是我们控制风险时需要知道的。我们不排斥尝试新事物,但我们一定要控制好风险的范围。
每个项目都会有“在这个项目中我们不会解决的问题”列表,列表中的很多东西似乎很有诱惑力,但限定范围会帮助我们明确需求重点,使项目稳定可控。定义好哪些是当下要解决的,哪些是未来需要解决的,并将这些内容放在以后的项目列表中。
任何建立在已有系统顶层的项目都需要过渡方案。我们如何逐渐从现有的点过渡到新的系统?大规模部署往往伴随有很多风险,在稳定的环境中,不要冒这种风险。了解数据源是怎样更新的,如何从一个数据源过渡到另一个。开发者必须总能掌控这些问题。
系统是为了生产力而构建,也就是说,系统并不是玩具,不能只完成自己那一份,就丢到生产环境不用再操心了。需要考虑如何在生产中配置系统,需要考虑内部依赖,并进行限制,还需要让系统易用、易维护。
生产环境与开发环境分离,不得在生产环境进行调试工作。
程序的运行是CPU指令的依序运行,程序经过编译成机器码后执行顺序就已经确定,单线程的执行中没有随机性,因此程序运行中的任何现象理论上都是可由计算机专业知识来解释。
12-factor理论。
系统建立在12-factor理论之上,模块之间要松散耦合,每个模块都有一个功能,并为了让系统的其他部分正常工作,而对这个功能进行管理。模块之间通过协议进行松散的通讯,也就是说在通讯中,各方都可以变更,只要仍旧通过不变的方式进行通讯。在设计协议时要考虑到未来的扩展问题,每个模块在设计时都要考虑依赖,各模块都可以随时替换掉,将其放在另一个系统中需要是仍然可用的。
要避免会滋生紧密耦合的深层依赖架构,在模块太过巨大时需要将其作拆分处理,但也要避免一大堆太过细小的模块,要保持复用功能的能力,从而减少依赖,依赖越少,程序越易于维护。
中间件只需传递数据,避免中间件对数据进行解析和诠释。
系统设计偏好以幂等性实现数据传递的方法,当从已知的稳定状态过渡到下一步状态,如果成功的话,会对一致性进行验证,然后保持在这种状态中,如果失败的话,就会进行重试,再来一次。这点对于分布式系统的尽力交付机制来说特别重要,因为在所有消息中拥有唯一ID,意味着超时状态下可以执行重试,并确保如果在接收系统中拥有执行日志的话,消息就不会被接收系统重复运行。
遵循UNIX原则:每个工具只做好一件事情,避免在一个工具中增加更多功能,而是另起一个工具。
代码正确比开发速度更重要,代码优雅比开发速度更重要,代码质量比开发速度更重要,其实速度真的不太重要。
在执行算法和数据结构优化前要进行测量,确保优化是否起到了想要的作用。构建的系统应当能够在运行时收集自身状态指标,以便优化时作为参考。
大多时候对代码格式的讨论是没有意义的,因为标准在制定时也是随意的,之后大家都来效仿。
Python不太适合大规模并发,因为Python默认解释器CPython实现时引入了GIL(Global Interpreter Lock)。需要明确的一点是GIL并不是Python的特性,像其中的另外一款解释器Jython就没有GIL。由于用了Java实现解释器,也就失去了利用社区众多C语言模块有用特性的机会。