微服务架构原理与治理实践 | 青训营笔记

105 阅读5分钟

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

01 微服务架构介绍

1.1 系统架构演变历史

单体架构

image.png

优:

  1. 性能最高
  2. 冗余少

劣:

  1. debug困难
  2. 模块相互影响
  3. 模块分工、开发流程

垂直应用架构,按照业务线垂直划分

image.png

优: 业务独立开发维护

劣:

  1. 不同业务存在冗余
  2. 每个业务还是单体

分布式架构 抽出业务无关的公共模块

image.png

优: 业务无关的独立服务

劣:

  1. 服务模块bug可能导致全站瘫痪
  2. 调用关系复杂
  3. 不同服务冗余

SOA架构 面向服务

image.png

优: 服务注册

劣势:

  1. 整个系统设计是中心化的
  2. 需要从上至下设计
  3. 重构困难

微服务架构 彻底的服务化

image.png

优:

  1. 开发效率
  2. 业务独立设计
  3. 自上而下
  4. 故障隔离

劣:

  1. 治理运维难度大
  2. 观测挑战
  3. 安全性
  4. 分布式系统

1.2 微服务架构概览

image.png

1.3 微服务架构的核心要素

服务治理:

  • 服务注册
  • 服务发现
  • 流量治理
  • 扩缩容
  • 负载均衡
  • 稳定性治理

可观测性:

  • 日志采集
  • 日志分析
  • 链路追踪
  • 监控大盘
  • 监控打点
  • 异常报警

安全:

  • 身份验证
  • 认证授权
  • 传输加密
  • 黑产攻击
  • 审计
  • 访问令牌

02 微服务架构原理及特征

2.1 基本概念

image.png

  • 服务:一组具有相同代码的运行实体
  • 实例:一个服务中,每一个运行实体都是一个实例
  • 实例与进程的关系:他们之间没有必然的联系,但是一般一个实例可以对应一个或者多个进程
  • 集群:通常指服务内的逻辑划分,包含多个实例
  • 常见的实例承载形式:进程、vm、k8s pod
  • 有状态/无状态服务:服务的实例是否存储了可持久化的数据。 服务间通信:网络传输,一般是RPC

2.2 服务注册及发现

  • hardcode 硬编码只能指定一个实例,而服务的实例有多个,并且实例的变更很困难。
  • DNS
  1. 本地DNS存在缓存,导致延时
  2. 负载均衡问题,因为一般是选第一个
  3. 不支持服务实例的探活检测
  4. 端口不能很好的利用
  • 注册中心

服务实例上线以及下线过程

  • 当下线一个实例的时候,可以告诉注册中心不再分发给这个实例流量,当这个实例没有流量的时候就可以把这个实例进行下线了。
  • 当一个实例想上线的时候,可以将这个实例进行自测,然后把这个实例注册到注册中心中去。

2.3 流量特征

image.png

  • 统一网关入口,网关可以用作身份认证,而将token附在请求上
  • 内网通信多采用rpc
  • 网状调用链路

03 核心服务治理功能

3.1 服务发布

服务发布的难点

  • 服务不可用
  • 服务抖动
  • 服务回滚

发布方式: 蓝绿发布,简单,稳定,但是需要两倍的资源 金丝雀发布:回滚难度大,基础设施要求高

3.2 流量治理

image.png 在微服务架构下,我们可以基于地区、集群、实例、请求等维度,对端对端的路由路径进行精准控制。

3.3 负载均衡

常见的LB策略

  • Round Robin
  • Random
  • Ring Hash
  • Least Request

3.4 稳定性治理

  • 网络攻击
  • 流量突增
  • 机房断电
  • 光纤被挖
  • 机器故障
  • 网络故障
  • 机房空调故障

微服务架构中典型的稳定性治理功能

  • 限流,保证请求的数量不会超过服务的请求上限
  • 熔断,如果下游服务不可用,直接返回
  • 过载保护,下游服务的cpu利用率过高的时候拒接服务
  • 降级,下游任务过载过高的时候,放弃处理不重要的任务,处理那些关键的任务

image.png

image.png

image.png

image.png

04 字节跳动服务治理实践

4.1 重试的意义

远程函数调用可能会出现异常

  • 网络抖动
  • 下游负载过高导致超时
  • 下游机器宕机
  • 本地机器负载高,调度超时
  • 下游熔断、限流

重试可能避免掉偶发的错误,提高SLA

  • 降低错误率 假设单个请求的错误概率为0.01,那么连续两次的错误概率为0.0001
  • 降低长尾延时 对于偶尔耗时的请求,重试请求有机会提前返回
  • 容忍暂时性错误 某些时候系统会有暂时性的异常,重试可以尽量规避
  • 避开下游故障实例 一个服务可能有少量的服务故障,重试其他实例可以成功

4.2 重试的难点

  • 幂等性,多次请求可能导致数据不一致
  • 重试风暴,随着调用深度的增加,重试的次数会指数上升
  • 超时设置,一般设置p99

4.3 重试策略

限制重试的比例,设置一个重试比例的阈值,重试次数占有的比例不超过改阈值 防止链路重试,链路层面的防重试风暴的核心是限制每层都发生重试,理想情况下只有最下面一层发生重试。 Hedged Requests,对于可能超时的请求,重新向另一个下游实例发送同一个请求,并等待先到达的响应。