架构修炼之道读书笔记

网关之道

  1. 网关和代理的区别,代理是纯粹的数据透传,协议不会发生变化。
  2. 一个API网关的基本功能包括统一接入、协议适配、流量管控与容错,以及安全防护。
  3. 从单体应用到微服务的演变,我们引入了API网关的概念。
  4. API网关通过管道技术来实现逻辑的依次处理。用管道比用if else在结构上会更清晰。
  5. 管道的思想和责任链模式是类似的。平常使用的过滤器或拦截器也属于管道技术思维的应用。
  6. 同步网关指接收请求到调用API接口提供方的过程都是同步调用。 半同步则是将IO请求线程和业务处理线程分开,但业务线程内部还是同步调用API接口。 全异步指整个链路都是异步请求。
  7. CPU利用率显示的是程序在运行期间实时占用的CPU百分比。 CPU负载显示的是一段时间内正在使用和等待使用CPU的平均任务数。 单核CPU的负载为1.0时,假设CPU每分钟能处理100个进程,而它正好处理100个。如果是2.0则表示这分钟他处理了100个,还有100个在等待处理。双核为2.0时也正好没需要等待的进程。类比。 有的进程CPU利用率高,有的利用率低(等待IO操作)。利用率低但负载高可能是IO高。
  8. 磁盘主要通过iostat查看磁盘使用率和磁盘负载百分比。 我们关注磁盘负载百分比这个参数,%util,代表一秒中有多少时间用于IO操作,如果接近100%代表IO请求太多,IO系统已经满负载,该磁盘可能存在瓶颈。
  9. 在全异步网关中,RPC客户端内部有一个回调线程池处理异步调用。
  10. 一种使用缓存的方式是将缓存持久化,要解决数据更新问题,一般利用时间戳,每次都对比一下时间戳是否过期,过期则去库里面取最新的更新。
  11. 凡是不需要重启应用服务器就能够让程序对象的属性值改变的行为都属于热更新。
  12. 常见的热更新的方法有MQ、RPC、ZOOKEEPER。
  13. 网关有七种武器,分别为降级、限流、熔断、线程池隔离、管道技术、配置热更新和异步。用来保证网关系统的健壮性。

开放之道

分布式之道

  1. CAP理论,C一致性,A可用性,P分区容错性(从分区和容错的角度来理解,当各个节点不能进行通信时,就会形成很多孤立的节点。容错是指在网络异常后整个分布式还是可用的。一般会把数据复制到所有节点上,当分区出现后每个节点都能访问到数据)。CAP不能同时都满足。
  2. BASE理论,BA基本可用,S软状态(如页面显示支付中,允许中间状态的存在),E(eventual consistency)最终一致性。从CAP的基础上演化成了BASE理论。
  3. 老的分布式事务通过二阶段提交来实现,分为准备阶段和提交阶段。一般我们都不用二阶段提交,而采用BASE理论实现分布式事务。
  4. 分布式锁的实现,redis和zookeeper。redis使用redission。
  5. QPS指服务器每秒能响应的查询次数。TPS指服务器每秒内处理的事务个数,这个事务包括请求服务器,处理,返回三个过程。一般用来评估数据库、交易系统的基准性能。
  6. RT指响应时间,包括请求发出时间、网络传输时间和服务器处理时间三部分组成。
  7. 评估系统扩容需要增加多少机器。 总PV*0.8/每天秒数*0.2 = 峰值时间内每秒请求数(QPS) 峰值时间内每秒请求数(QPS)/单机QPS = 需要的机器

MQ之道

  1. JMS消息类型: 点对点使用队列,生产者将消息放到队列,消费者把消息取出并删除,不会有重复消费的问题,而且只有一个消费者能消费该消息。 发布订阅,引入主题概念,发布者发布一个主题,并向主题发送消息,订阅者订阅自己感兴趣的主题,订阅该主题的消费者都能消费该主题消息,发布者和订阅者之间也不需要关心对方的存在。

  2. 生产者-消费者模式 生产者消费者之间增加了一个缓冲区,他们不需要知道对方的存在,相互不依赖,实现了空间解耦。 生产者不关心消费者什么时间去消费数据,消费者可以按照自己的逻辑来控制,实现了时间解耦。

  3. 空间解耦和时间解耦

| | 时间耦合 | 时间解耦 | | ——– | ———————————————————— | ———————————————————— | | 空间耦合 | 与一个或一些给定的接收者直接通信。发送者接受者必须同时存在,比如PRC调用。 | 与一个或一些给定的接收者直接通信。他们都可以有自己的生命周期。比如苹果推送等。 | | 空间解耦 | 发送者不需要知道接收者的身份,但是他们必须同时存在。比如代理、网关。 | 发送者不需要知道接收者的身份。他们都可以有自己的生命周期。如发布订阅系统,消息队列等。 |

  1. 观察者模式与发布订阅 发布订阅是观察者模式的一种变化。 他们的不同在于,首先观察者模式中,观察者需要提前注册到主题上,所以他在空间和时间上是耦合的。 而发布订阅模式中,发布者将内容发布到MQ队列中,所以发布和订阅是完全解耦的。

  2. 消费幂等 一般使用唯一的消息key来进行幂等处理。

  3. MQ的各种功能场景 解耦 削峰填谷 最终一致性,利用MQ的幂等、重试等机制来保证业务的最终一致性 广播消费 使用集群消费模拟广播 重试之坑,由于网络原因,已经消费了被认为没消费导致重复发送,这种要保证重试时发送的流水号相同。

  4. 数据异构,对数据按需进行异地构建。

  5. 常见数据异构的方式:完整克隆、标记同步(标记时间戳,故障从时间点开始重新同步)、binlog方式、MQ方式。

  6. binlog方式进行异构,使用开源订阅binlog日志组件canal。

消息推送之道

  1. 消息推送主要有两种方式,自建或利用第三方平台。 自建一般通过HTTP和TCP协议,HTTP的话一般通过1.1之后的长连接来支持,TCP的话实现端到端的通信,可以借助Netty这样的框架,而不用关心TCP的细节。
  2. 自建HTTP的时候,一般架构lvs+haproxy->nginx,这个时候响应是haproxy返回给客户端的,也就是LVS的dr模式。在这里,浏览器与haproxy之间建立长连接,haproxy与nginx之间建立长连接。
  3. HTTP的长连接推送会涉及到session管理、心跳、消息接受、消息推送、消息追踪五大模块。
  4. 一般是从客户端往服务端发送心跳包。
  5. 一般消息使用半推半拉的模式,推送一个简单的消息通知而不是消息实体,避免浪费传输资源。
  6. 长连接推送系统需要保持大量的连接,这时我们考虑使用NIO的IO复用模型,利用事件驱动机制使用少量线程保持住大量的连接。
  7. 黏包问题 在TCP协议中,当发送端缓冲区数据大于网卡MTU时,会将这个数据拆成几个数据包发送出去。 而对于数据过小的情况,发送端要等到缓冲区满了才发送,把多个消息合在一起,造成黏包。 因此将消息设为定长可以解决黏包问题。或者在消息体后加回车换行符。
  8. 一台服务器可以跑多少个连接 与端口数无关,服务端的80端口能建立的连接数取决于服务端的优化。 首先是最大文件数,每个TCP连接都会建立一个socket句柄。通过ulimit -n来查看。 然后是调整TCP的发送、读取缓冲区以及TCP的内存大小。
  9. 一台服务器能跑多少个线程 使用NIO后,较少的线程数可以处理很多连接。
  10. 苹果的APNs

RPC之道

  1. 动态代理,如通过CGLIB的开源实现。
  2. 反射,指计算机程序在运行时能访问、检测和修改他本身状态和行为的能力。 传入远程服务名和方法名,通过反射自动定位到需要被调用的方法,再传入参数,从而进行RPC调用。
  3. 序列化,把内存中的数据转为字节流,常见的序列化协议有protobuf,thrift等。
  4. 使用动态代理解决代理逻辑代码和业务隔离,通过反射实现自动定位到具体远程方法,序列化为网络传输做好准备。

IO之道

  1. IO多路复用 select方式,进程受阻于select调用,等待可能多个套接字中的任何一个变为可读。
  2. IO多路复用中的IO指网络IO,多路指多个TCP连接(或多个channel),复用指复用一个或少量线程。串起来就是多个网络IO复用一个或少量线程来处理这些连接
  3. 用户进程和内核 应用层指用户进程,传输层包括以下的都指内核。
  4. IO模型有阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO。
  5. 阻塞IO和IO复用的第一个阶段都是阻塞,但是阻塞IO如果要接受更多连接就要创建更多线程。而IO复用的第一个阶段可以把大量连接直接注册到selector复用器上,同时只需要少量线程来循环处理这些连接事件就可以了。

微服务之道

  1. 拆分时,不同服务的数据库要进行解耦,对于依赖的冗余数据,可以通过数据异构的方式解决,或者RPC。

容错之道

  1. 降级限流。降级使用托底数据。限流使用漏桶或令牌桶。

  2. 线程池隔离,为了保证一个业务响应延迟、导致大量请求过来,线程数可能持续增加导致整个系统崩溃。 这是需要给不同服务不同的线程池。 一般会设置每个线程池的最大数量,超过不再处理。 可以使用Hystrix的线程池隔离。他也提供了信号量隔离。

  3. 快速失败 最有效的方法是设置超时时间,有网络问题及时结束请求。

  4. 熔断 熔断器会根据调用失败计数器来决定打开、关闭、半开的状态。 Hystrix里的Breaker,阿里的Sentinel都提供了开源方案。

  5. 线程池隔离和信号量隔离的区别 对于不依赖网络访问的服务,不适合使用线程池隔离技术。 线程池方式下业务请求线程和执行依赖的服务线程不是同一个线程;信号量方式下业务请求线程和执行依赖服务的线程是同一个。所以信号量隔离更轻量级。

  6. 熔断器会报告成功、失败、超时、拒绝四中状态。根据这四种状态决定熔断状态。

← docker开发kong  Go代码片段 →