规模化微服务
故障
与其为防止故障做上一百个准备,不如定制一个快速从故障中恢复过来的流程
测量
- 响应时间
对于响应时间的测量,有时候网络是有异常情况的,所以使用百分比来测量连接的响应时间
- 可用性
对于24/7小时服务,可接受停机报告只有在历史报告的角度才有用
- 数据持久性
数据应该保持多久,能容忍多少丢失?
功能降级
微服务系统是的功能是由多个服务合作提供的,所以某些不重要的服务即使不可用,也不该让整个系统不可用
架构性安全
也就说必须实现接口隔离,如果一个服务的请求都是共享同一个连接池,那很有可能某一接口会导致阻塞的请求越来越多,从而导致不可用
一些情况
- 超时
超时设置的太短或者太长都不好,尝试着设置一个默认的超时时间,记录日志,看超时的时候发生了什么
- 熔断器
如果发生一定量的失败请求后,断路器会打开,在断路器打开后任何调用都会快速失败,此后,客户端会发一些请求给生产者看服务是否恢复,如果恢复,就关闭断路器
- 接口隔离
可以把熔断器当做接口隔离服务不可用时的一种隔离手段
- 服务隔离
- 幂等性
所以幂等就是调用一次与调用多次的结果都是一样的,这种情况,在基于事件的协作下可能很好用
扩展
- 用更强的主机
- 垂直扩展
- 负载拆分
- 对单主机多服务进行服务拆分
- 将服务拆分为更小的服务
- 分散风险
- 尽量将服务分散在不同的主机、不同的数据中心
- 负载均衡
- 基于worker的系统
- 基于消息队列来实现
- 重新设计
- 设计一个系统时,我们往往不知道真正想要构建的是什么,如果在刚开始构建时引入了太多对未来的预测,这会耗费本可以花在更重要的事上的精力
数据库
- 读取扩展
对于数据来说,大部分数据读取的次数远远比写的次数要多得多
对于许多关系型数据库,可以设置在单个节点进行写操作,写入的这些数据将在某一时刻被同步到所有数据库节点,而读取操作可以被分发到各个节点上,但这可能会读取到不一致数据,虽然最终结果是一致的,这杯称为最终一致性
- 写扩展
可以对要被写的数据进行分片,存到不同的数据库上,但会引入对数据库查询的复杂性
- 使用共享的数据库基础设施
这会很节省主机资源,但是也会影响一个重要的单点故障
- CQRS
类似于日志数据库,通过存取一系列的操作日志,来计算出某一具体时刻的数据
缓存
- 客户端缓存
缓存控制在客户端,所以如果想控制缓存是很困难
HTTP缓存
- 代理服务器缓存
好处是对客户端透明的,但会引入额外的网络跳数
- 服务器缓存
对客户端完全透明,而且想要控制缓存也必将容易
后写式缓存,有些情况会对同一数据执行许多次写操作,此时就可以先将数据缓存在内存中,待到特定时刻再写到数据源中
缓存过期的数据,当服务不可用时,可以返回这些过期的版本
当缓存大量击穿时,不应该采取同步的方法,而应该对客户快速失败,后台异步调用服务增加缓存
缓存应该保持简单
自动伸缩
可以一些规则,让运维系统自动增减服务实例
CAP定理
- 一致性:访问多个节点都得到同意的数据
- 可用性:每个请求都能获得响应
- 分区容忍性:某些节点无法联系之后,整个集群还能继续提供服务
这三个条件无法同时满足,当一个上去了,另外两个就要下来了
服务发现
- DNS
动态的服务注册
- zookeeper
- consul
- eureka
文档
- swagger
- hal