远程调用

  • RPC
  • REST

事务处理

事务处理的意义是为了保证系统中所有的数据都是符合期望的

本地事务

隔离级别

(这个部分看到了太多不同的说法)

写锁:持有写锁的才能写入,其他事务不能再加锁

读锁:不允许其他事务加写锁

范围锁:对于某个范围加锁,这个范围内不能再更改、删除和更新

  1. 可串行化:每次读写都加上读锁、写锁和范围锁
  2. 可重复读:不加范围锁,所以别的事务虽然不能更改已有的数据,但是可以插入新的数据,导致幻读
  3. 读已提交:一旦读操作结束就释放读锁,于是其他事务可以加写锁修改数据,这时候再去读就会发现数据变咯,也就是不可重复读
  4. 读未提交:

追求一致性的全局事务

单个服务使用多个数据源

XA

  • 准备阶段:协调者询问事务所有参与者(比如不同的数据库)是否准备好提交,准备好的回复一条Prepared
  • 提交阶段:如果所有参与者都准备好了,协调者自己先commit一次,然后向参与者发送commit指令,如果出现了问题,自己先Abort然后发送Abort指令

问题:

协调者寄了,整个就寄了

性能问题,整个过程要持续到参与集群最慢的那个做完

一致性风险:宕机如果不可恢复,那么无法实现一致性,同时在提交阶段,如果协调者已经在日志里写了commit记录,但是网络却断了,指令没有发出去,就会产生不一致的情况

三段式:添加一个让参与者们自检完成事务的可能性,如果自检都通过那么成功的概率大大提高,大家也就不用在准备阶段瞎忙活了

共享事务

多个服务使用单个数据源

这往往是一个伪需求

之所以强调理论可行,是因为该方案是与实际生产系统中的压力方向相悖的,一个服务集 群里数据库才是压力最大而又最不容易伸缩拓展的重灾区,所以现实中只有类似ProxySQL 、MaxScale 这样用于对多个数据库实例做负载均衡的数据库代理,而几乎没有反过来代理一个数据库为多个应用提供事务协调的交易服务代理。 这也是说它更有可能是个伪需求的原因,如果你有充足理由让多个微服务去共享数据库, 就必须找到更加站得住脚的理由来向团队解释拆分微服务的目的是什么才行。

除了使用一个代理服务器,还可以用消息队列,多个服务向一个消息队列里添加消息,由消费者来统一处理,但是这仍然与系统抗压设计向悖

分布式事务

多个服务同时访问多个数据源

CAP原理

在涉及共享数据问题时,Consistency、Availability和Partition Tolerance只能最多满足其二

首先,Patition Tolerance是不可能放弃的,你不能保证系统的任何一部分都是永远可靠的

于是就只剩下两种选择:

  • AP-放弃一致性保可用性:这是目前大多数分布式系统的选择,A 通常是建设分布式的目 的,如果可用性随着节点数量增加反而降低的话,很多分布式系统可能就失去了存在的 价值
  • CP-放弃可用性保一致性:银行、证券等宁愿中断也不愿意出现不一致的系统,这类系统对一致性的要求很高

既然强一致性已经被AP放弃了,接下来就该讨论如何做到尽可能获得正确的结果,也就是追求弱一致性了

最终一致性

如果数据一段时间没有被其他操作所修改,那么它最终会达到与强一致性过程相同的结果,面向最终一致性的算法常常被称作“乐观复制算法”

柔性事务

满足ACID的事务被称作刚性事务,而追求最终一致性的事务被称作柔性事务

QUIC与0rtt(zero roundtrip time)

0rtt的tls1.3

tls1.3的核心思想是,如果客户端和服务端曾经有过tls通讯,那么下一次tls通讯时,两端之间就不用煞费苦心去沟通参数,客户端可以使用pre_shared_key来在第一下clientHello就开始发送加密的数据

我看不懂…

tls1.3

透明多级分流系统

客户端缓存

域名解析

传输链路

CDN content distribution network

CDN与路由解析

加入cdn后,当客户端请求一个域名时,将不再得到源站的ip,而是得到cdn服务器的cname,本地得到cname后,向提供该cname的权威dns查询dns,权威dns根据各种策略选择一个最合适的ip给客户端,这个ip将有能力中转客户端的请求到源站

CDN与内容分发

cdn获取源站资源的过程被称为内容分发

  • 主动分发Push:分发由源站主动发起,将内容从源站或者其他资源库推送到用户边 缘的各个 CDN 缓存节点上,这个过程对于源站并不是透明的。
  • 被动回源Pull:当用户访问cdn的边缘服务器并且边缘服务器发现自己没有缓存源站的资源时,会实时从源站中获取

内容更新

对于“CDN 如何管理(更新)资源”这个问题,同样没有统一的标准可言,尽管在 HTTP 协 议中,关于缓存的 Header 定义中确实是有对 CDN 这类共享缓存的一些指引性参数,譬如 Cache-Control的 s-maxage,但是否要遵循,完全取决于 CDN 本身的实现策略。更令人 感到无奈的是,由于大多数网站的开发和运维人员并不十分了解 HTTP 缓存机制,所以导 致如果 CDN 完全照着 HTTP Headers 来控制缓存失效和更新,效果反而会相当的差,还可 能引发其他问题。因此,CDN 缓存的管理就不存在通用的准则。 现在,最常见的做法是超时被动失效与手工主动失效相结合。超时失效是指给予缓存资源 一定的生存期,超过了生存期就在下次请求时重新被动回源一次。而手工失效是指 CDN 服 务商一般会提供给程序调用来失效缓存的接口,在网站更新时,由持续集成的流水线自动 调用该接口来实现缓存更新,譬如“ icyfenix.cn ”就是依靠Travis-CI 的持续集成服务来 触发 CDN 失效和重新预热的。

CDN的作用

  • 加速静态资源的访问:本职工作
  • 安全防御:(在源站的ip没有泄露的基础上)CDN可以防御譬如DDoS攻击(很多针对静态资源的攻击都会打到cdn上)
  • 协议升级:可以实现源站是http协议,对外开放强制https访问,类似的还有http1升级到3,IPv4升级到IPv6
  • 状态缓存
  • 修改资源:可以压缩一些静态资源加速访问,也可以修改CORS头提供跨域共享
  • 访问控制:可以实现IP黑/白名单功能
  • 注入功能:可以在不修改源代码的前提下为源站注入各种功能
  • 绕过长城防火墙:CDN隐藏VPS的真实ip,让防火墙只能封CDN ip,CDN监测到异常后,马上为用户换一个可以用的ip

负载均衡 load balancing

如何构建 和调度服务集群这事情,又必须对用户一侧保持足够的透明,即使请求背后是由一千台、 一万台机器来共同响应的,也绝非用户所关心的事情,用户需记住的只有一个域名地址而 已。调度后方的多台机器,以统一的接口对外提供服务,承担此职责的技术组件被称为“负 载均衡”(Load Balancing)

我们这里讨论负载均衡已不再包含CDN和DNS解析等的负载均衡

数据链路层负载均衡

这一层的负载均衡的核心原理是修改数据帧中的MAC目标地址,首先所有的数据帧都指向负载均衡器,负载均衡器将请求帧的MAC地址指向真实地址

实现

由于只修改了二层数据帧的MAC目标地址,因此IP等内容全部没有改变,这就要求负载均衡器和真实服务器的ip地址是一致的,这里一般采用让真实服务器集群的虚拟ip地址与负载均衡器的虚拟ip相同。

pros

这种实现的一大好处是返回的数据不用再经过负载均衡器改为负载均衡器的ip,而是可以由真实服务器直接返回结果给客户端,一定程度上缓解负载均衡器带宽造成的性能瓶颈。

cons

  • 需要感知应用层协议的负载均衡场景无法胜任
  • 由于是在数据链路层工作,所以必须二层可达,要求负载均衡器必须和真实服务器在同一子网内,不能跨VLAN,不能跨子网