微服务| 青训营笔记

139 阅读5分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记


1,微服务架构介绍

1.1,架构历史

  • 演进原因:互联网的发展;硬件设施的发展;需求多样复杂;开发人员增多;计算机技术理论发展。
  • 系统架构的演进历史:单体架构---> 垂直应用架构--->分布式架构--->SOA架构--->微服务架构
  • 单机架构:All in one,所有的东西都在一个进程里,部署在一个机器上。
    • 优点:简单;
    • 缺点:运维需要停服,用户体验较差承载能力有限。
  • 单体架构:在单机架构的基础上,将进程部署到多个机器上。
    • 优点:具备水平扩容能力,运维不需要停服
    • 缺点:后端进程职责太多,越来越臃肿;爆炸半径较大,进程中一个很小的模块出现问题,都可能导致整个进程崩溃。
  • 垂直应用架构,在单机架构基础上,将进程按照某种依据切分开,然后再按照单体模式的思路,部署在多个机器上。
    • 优点:一定程度上减少了后端进程职责;一定程度上缩小爆炸半径
    • 缺点:没有根本解决单体架构的问题
  • 面向服务架构:服务为一等公民,将进程按照不同的功能单元进行抽象,拆分为『服务』。有了服务之后,SOA 还为服务之间的通信定义了标准,保证各个服务之间通讯体验的一致性。
    • 优点:各服务的职责更清晰;运维粒度减小到服务,爆炸半径可控
    • 缺点:ESB (企业服务总线) 往往需要一整套解决方案
  • 微服务:在 SOA 架构中,ESB 起到了至关重要的作用。但从架构拓扑来看,它更像是一个集中式的模块。有一个SOA 分布式演进的分支,最终的形态便是微服务。
    • 优点:兼具 SOA 解决的问题;服务间的通信更敏捷、灵活
    • 缺点:运维成本

1.2,微服务架构的三大要素

  • 服务治理:服务注册;服务发现;负载均衡;扩缩容; 流量治理;稳定性治理
  • 可观测性:日志采集;日志分析;监控打点; 监控大盘;异常报警;链路追踪
  • 安全:身份验证;认证授权;访问令牌; 审计; 传输加密; 黑产攻击

2,微服务架构原理及特征

2.1,微服务架构中的基本概念及组件

  • 服务:一组具有相同逻辑的运行实体
  • 实例: 一个服务中的每个运行实体。常见的实例承载形式:进程、VM、k8s pod
  • 实例与进程的关系: 没有必然对应关系,一般一对一或者一对多
  • 集群:服务内部逻辑划分,包含多个实例
  • 服务间通信:微服务之间通过网络进行通信,常见的通信协议包括 HTTP、RPC image.png ####2.2, 服务注册及服务发现
  • 在服务间调用中,指定下游服务实例的地址
    • 直接指定 ip:port,没有任何动态能力,难以处理多个实例下游实例
    • 使用 DNS:本地 DNS 存在缓存,导致延迟;DNS 没有负载均衡;不支持服务探活检查;DNS 不能指定端口
    • 服务注册发现:新增一个统一的服务注册中心,用于存储服务名到服务实例之间的映射关系;旧服务实例下线前,从服务注册中心删除该实例,下线流量;新服务实例上线后,在服务注册中心注册该实例,上线流量 image.png

2.3,微服务流量特征

  • 统一网关入口
  • 外网通信多数采用 HTTP,
  • 内网通信多数采用 RPC(Thrift, gRPC) image.png

3,微服务治理功能

3.1,服务发布

  • 服务发布:让一个服务升级运行新的代码的过程
  • 服务发布难点: 服务不可用; 服务抖动; 服务回滚 image.png
  • 蓝绿部署:将服务分成两个部分,分别先后发布;简单、稳定;但需要两倍资源 image.png
  • 灰度发布(金丝雀发布):先发布少部分实例,接着逐步增加发布比例;不需要增加资源;回滚难度大,基础设施要求高 image.png

3.2,流量治理

  • 流量控制:在微服务架构中,可以从各个维度对端到端的流量在链路上进行精确控制
  • 控制维度:地区维度;集群维度;实例维度;请求维度

3.3, 负载均衡

  • 负责分配请求在每个下游实例上的分布。
  • 策略:Round Robin;Random;Ring Hash; Least Request

3.4,稳定性治理

  • 限流:限制服务处理的最大 QPS,拒绝过多请求
  • 熔断:中断请求路径,增加冷却时间从而让故障实例尝试恢复
  • 过载保护:在负载高的实例中,主动拒绝一部分请求,防止实例被打挂
  • 降级:服务处理能力不足时,拒绝低级别的请求,只响应线上高优请求 image.png

4,字节跳动服务治理实践

4.1, 请求重试

  • 本地函数调用,通常没有重试意义
  • 远程函数调用:由于存在网络抖动、下游负载高、下游机器宕机,重试是有意义的,可以避免偶发性的错误,提高 SLA
  • 重试的意义: 降低错误率;降低长尾延时;容忍暂时性错误;避开下游故障实例

4.1, 请求重试的难点

  • 幂等性:多次请求造成数据不一致
  • 重试风暴:随着调用链路的增加,重试次数呈指数级上升 image.png
  • 超时设置:超时阈值设定

4.3, 重试策略

  • 限制重试比例:设定一个重试比例阈值(例如 1%),重试次数占所有请求比例不超过该阈值 image.png
  • 防止链路重试:返回特殊的 status code,表示“请求失败,但别重试” image.png
  • Hedged Requests:对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,并等待先到达的响应 image.png