1. 第一个拥有10亿用户的网站
1.1. 2016年,Facebook宣布其每日活跃用户数量为11.3亿
1.2. 对整个应用程序来说,“五个9”的可靠性远远不够,这每天会让成千上万的用户失望
1.3. 假如按照六西格玛质量标准来衡量,那么Facebook每天会惹怒768000个用户
1.4. 每页200个请求,每日11.3亿个活跃用户,每百万次机会有3.4个缺陷
2. 当集成一个个的系统时,系统相互之间的紧耦合就会变为常态
2.1. 大型系统往往比小型系统更快地陷入失效
2.2. 紧耦合会令系统某一部分的裂纹开始蔓延并成倍增大,最终跨越层级或系统的边界
3. 问题膨胀
3.1. 轻微的失误转化为重大的系统失效
3.2. 冷却监控和控制系统中隐藏的连锁反应,就是导致美国三里岛核反应堆事故的部分原因
4. 每一个反模式都会在系统中产生、加速或增加裂纹
4.1. 仅仅避免使用这些反模式还不够,因为所有事物都会出问题,失误不可能避免
4.2. 不要假装可以消除所有可能的失误来源,无论是系统本身的失误还是人为引起的失误
4.3. 要做最坏的假设,失误肯定会发生
5. 集成点
5.1. 集成点是系统的头号杀手
5.2. 所有的都是集成项目
5.3. 蝴蝶图
5.4. 蜘蛛图
5.4.1. 精心设计
5.4.2. 随意设置
5.5. 所有这些连接都是集成点,它们中的每一个都有可能破坏系统
5.6. 小型服务的数量设计得越多,与SaaS提供商的整合程度就越高,越是采用API优先的策略,越会让情况变得更糟
6. 套接字协议
6.1. 较高层级的许多集成协议通过套接字运行
6.2. 除了命名管道和进程间通信(共享内存),几乎所有的通信都基于套接字来实现
6.3. 最简单的系统失效方式是远程系统拒绝连接
6.4. TCP部分则是一个关于如何在离散的数据包基础上,构建出看似连续连接的协议
6.4.1. TCP还定义了“同时打开”的握手方式,即在发送SYN/ACK之前,这两台机器会互相发送SYN数据包。然而在基于客户端-服务器交互的系统中,这是相对少见的
6.5. 如果想要结束阻塞调用,就必须设置套接字超时时间。在超时情况下,程序能够处理相关的异常
6.6. 网络系统失效按速度分为快慢两种
6.6.1. 快速的网络系统失效,会让调用代码立即出现异常
6.6.1.1. “拒绝连接”是非常快速的系统失效,只需要几毫秒的时间就能返回给调用方
6.6.2. 缓慢的系统失效,比如一个被丢弃的ACK,会让线程在抛出异常之前被阻塞几分钟
6.6.2.1. 一个缓慢的响应比没有响应糟糕得多
6.7. 问题
6.7.1. 防火墙内的“已建立连接”表
6.7.1.1. 该表是有时长限制的
6.7.1.2. 即使TCP本身允许无限时长的连接,该表也不允许
6.7.1.3. 防火墙丢弃了这些数据包,而不是通知发送方无法到达目标主机
6.7.1.4. 闲置时长会轻松超过防火墙中配置的1小时闲置连接超时
6.7.2. TCP从来也不是为处于网络连接中间的那种智能设备而设计的,任何第三方都无法告诉连接终端它们的连接正在被拆除
6.8. 方案
6.8.1. ping数据包本身就是解决方案所需要的,其可以用来重置防火墙连接的“最后数据包”时间,可以使连接保持活动状态
6.8.2. “无效连接检测”既能让连接保持活动状态,又可以让人睡个安稳觉
6.8.3. 为了更好地理解问题,需要知道如何继续深入至少两个抽象层次,才能了解层次的“实际情况”,找到问题所在
6.9. tcpdump是从网络接口捕获数据包的常用UNIX工具
6.10. Wireshark可以在网线上嗅探数据包
6.10.1. 类似tcpdump,但它也能在图形用户界面中显示数据包的结构
6.10.2. 需要在X Window系统上运行
6.10.2.1. 无法安装在Docker容器或AWS实例中
7. HTTP协议
7.1. 所有基于HTTP的协议都使用套接字
7.2. 可能会给调用方带来的影响
7.2.1. 服务提供方可能会接受TCP连接,但不会响应HTTP请求
7.2.2. 服务提供方可以接受连接但不能读取请求
7.2.3. 服务提供方可能会发回调用方不知道该如何处理的响应状态
7.2.4. 在服务提供方发回的响应中,可能带有调用方不期望或不知道如何处理的内容类型
7.2.4.1. 当DNS查找失败时,互联网服务提供商可能会注入一个HTML页面