Serverer杂谈
00 min
2024-1-21
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,赶紧止损,该回滚回滚,该降级降级,该限流限流,总之缩小影响范围是第一步。