第十一章 规模化微服务
11.1 故障无处不在
问题
硬盘挂载,软件崩溃,网络不可靠。。。
==》难以避免
==》拥抱故障,计划停机总比意外停机好吧
==》或者是如何优雅地处理
11.2 多少是太多
- 你可以容忍多少故障呢?
- 系统需要有多快呢?
指标:
- 延迟
- 可用性
- 数据持久性
- 功能降级
- 某个辅助服务不可用的时候,去除了也不影响主业务。
==》思考一下这个服务挂载了,会有什么后果。
架构安全性
- 服务响应缓慢是一个很糟糕的故障(占满所有worker)
- 「断路器」设置超时时间
11.5 反脆弱的组织
- 事物实际上收益于失败和混乱。
- 混乱的猴子,在一天的特定时间破坏系统。(开发人员不得不做好准备)
- 在失败中学习,而不是一味地指责。
解决:
- 超时
- 断路器(当失败到了一定阈值,拒绝请求)
- 手动使用比较安全。
- 工具:Hystrix
- 舱壁(故障隔离),保护级联系统【最重要的】
- 越是依赖就越需要隔离
11.6 幂等
多次执行=一次执行(存钱的操作)
11.7 扩展(避免失败)
- 更强大的主机
- 拆分负载(分开多个服务)
- 分散风险(多个虚拟机,虚拟化,或者多个数据中心)
- 负载均衡
- vlan
- 基于worker 的系统
- hadoop(共享作业队列)
- 重新设计(拆分+新技术)==》有危险
11.8 扩展数据库
- 服务的可用性和数据的持久性
- 扩展读取(加缓存)
- 扩展写(分片)
难点在查询,你也可以使用一些中间件 - 共享数据库基础设施(服务)
CQRS(命令查询职责分离)
存储和查询的替代模型
执行
- 收到命令-->有效-->应用到模型(允许扩展模型)
- 处理命令和查询模型本身是相互独立的
- 命令和查询可能在不同的机器上,不同服务上。
- 查询也可以不同返回格式
缓存(性能优化的一种方式)
- 客户端(改变较难),代理(cdn)和服务器缓存
- http缓存
- cache-control
- expires
- Etag(url还是一样,但是Etag变就会重新获取数据)
- 为写使用缓存
- 弹性使用缓存(确保有一个可用的版本)
隐藏源服务
- 当缓存区都被清了,就要适当写入新的缓存
- 外部请求适当减少,保证系统正常
- 缓存不要太多
- 失效时间+主动失效
11.10 自动伸缩
预测伸缩,响应伸缩(谨慎)
11.11 CAP定理
- 一致性
- 可用性
- 分区容忍性
牺牲一致性(ap系统)==》后期不得不做同步
牺牲可用性(数据不能同步,系统断开不可用)
牺牲分区容忍性(没有分区容忍就没有跨网络调用了)
AP还是CP(CP的挑战较大)
不是所有服务都需要这样去做
11.12 服务发现
怎么找到你?
- dns
- 某个机器有问题的时候,怎么主动拒绝呢?
- 动态服务注册
- zk(通用)
- Consul(比zk更先进)
- 提供现成的DNS服务器,并支持SRV
- 节点健康检查(高容错设计)
- 故障管理和报警
- Eureka
- 负载均衡
别忘了人
数据是给人看的
11.14 文档服务
明显清晰的API
- Swagger(作者推荐)
- HAL和HAL浏览器(使用超媒体)
11.15 自描述系统
- UDDI (描述,发现,服务集成)
- 系统当前运行情况
推荐书籍:
- 《反脆弱》
- 《发布!软件的设计与部署》
CH12 总结
- 制定原则,作为决策的依据
- 什么时候不应该使用微服务
- 难免会有一些错误
缩小决策的范围,影响一小部分。
拥抱演进式的架构