读发布!设计与部署稳定的分布式系统(第2版)笔记04_集成点
2023-06-18 08:02:21 博客园
【资料图】
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页面
7.2.5.服务提供方可能声称要发送JSON,但实际上发送了纯文本,或者是内核二进制文件,抑或是Weird Al Yankovic创作的MP3音乐
7.3.建议
7.3.1.避免使用那些将响应直接映射到领域对象的客户端程序库
7.3.2.要将响应视为数据,除非已经确认响应符合设计预期
8.供应商的API程序库
8.1.阻塞是影响供应商API程序库稳定性的首要问题
8.1.1.无论是内部资源池、套接字读取指令、HTTP连接,还是最一般的Java序列化,处处可以发现不安全的编程实践
8.2.供应商可能会对其销售的服务器软件进行强化,但对客户端API程序库则很少这样做
8.3.程序库的代码只是出自常规开发工程师之手,与其他任何随机抽样的代码一样,在质量、风格和安全性等方面具有不稳定性
8.4.它们几乎不受控制
8.5.需要等待供应商官方补丁版本