type
status
date
slug
summary
tags
category
icon
password
Core
- 服务类的程序都是无限游戏,是能跑越久越好的。
- 越底层业务,越严格,越抽象;越顶层业务,越兼容,越复杂。
- 假设服务调用链为
A→B→C
,它们自身可用性初始默认都为99%,那么C理论上就是99%*99%*99%
。但是服务端要做的,就是要让可用性大于这个值,而不是随着调用链变深而越来越小。
- 高可用、高复用的系统,分布式多层的系统架构,流水线的生产,服务化的能力供应,自动化的运维,乃软件工程。
- 大数据场景要解决的核心问题,就是资源的管理和任务的分发。
Code
- 业务代码的本质,就是流程和参数。
- 类型是对内存的一种抽象,也是一种对混乱的约束。
- 编程语言作为机器代码和业务逻辑的粘合层,是在让程序员可以控制更多底层的灵活性,还是屏蔽底层细节,让程序员可以更多地关注于业务逻辑之间 trade-off 的。
- 业务代码不一定是最有技术含量的,但一定是最有价值的,是直接创收的。
Network
- 分布式环境下,请假设网络会在任意阶段出错。
- 对发送的内容保持警惕,对接收的内容保持自由。
- 应用程序之间的通信,可以看作是一种交易(req&resp),这是个匹配问题。
- 后端程序大多是IO密集型程序,其本质是接口的集合,其职责就是协调其他服务(数据库、第三方服务、文件系统……),如果IO阻塞了,程序跑的再快也没用,别再纠结语言了。
- 开并发多线程的适合场景——IO密集。
- 单核 CPU 一般能承载 2000 路 IO。
- 流量调度可以让分布式系统发挥出最佳性能。
- 分布式系统的吞吐会变大,但是时延是有一定牺牲的。
Interface
- 不要试图在文档中说明,很多用户不看文档。要让设计的API自解释。
- 接口分不分B/C端,不是看流量,而是看对接口的期望。B端更看重一致性、正确性,C端更看重可用性。
- 接口/数据源默认不可信,一定要测,调通了再说。
- 所有的 Service Interface,都必须从骨子里到表面上设计成能对外界开放的。也就是说,必须做好规划与设计,以便未来把接口开放给全世界的程序员,没有任何例外。
System Design
- 简单的规则产生复杂的行为,复杂的规则产生愚蠢的行为。(参考UNIX哲学)
- 程序可以处于的状态越多,错误就越有可能潜入,而空指针会使可能的状态数量爆炸式增长。
- 业务系统,OOD是底线。
- DO是慢慢丰富起来的,由业务驱动;而非一下子把VO、PO叠在一起套进去。
- DDD强调的是一个复杂的业务系统怎么“拆”,而不是如何build-up。重点在限界、上下文的界定划分。
- 警惕Global!
- 不要做太多的监控和日志,信息太多等于没有信息。
- 服务的依赖越多、越复杂,系统就越易碎。
- 如果系统设计出现了问题,需要重新思考一个新的抽象。
Storage
- 存储是状态的维持者。
- 存储对可用性的要求极高,不能故障。
- 缓存只是缓存,默认不可靠,更不能用来做持久存储(即使它支持)。
Work
- 对于搬砖式的交作业工作,交付就行了。但是要不断提高“交作业”的效率,做高ROI的事情(比如:代码复用、自动化、砍需求等),才有时间去做更有价值的事情。
for(int i=0;i<n;i++)
在A业务可以值2000元,但在B业务可以一文不值,看业务场景。
- 运维理想状态:人管代码,代码管机器;人不用去管机器。
- 故障发生是常态,运维工作应该要尽可能地自动化。
- 发生线上故障不要第一时间debug,赶紧止损,该回滚回滚,该降级降级,该限流限流,总之缩小影响范围是第一步。