微服务架构介绍

系统架构演进历史

为什么系统架构需要演进?

  • 互联网的爆炸性发展
  • 硬件设施的快速发展
  • 需求复杂性的多样化
  • 开发人员的急剧增加
  • 计算机理论及技术的发展

image-20220609160002559

单体架构

image-20221101202521310

All in one process

优势:

  1. 性能最高
  2. 冗余小

劣势:

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

垂直应用架构

img

按照业务线垂直划分

优势:

  1. 业务独立开发维护

劣势:

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

分布式架构

img

抽出业务无关的公共模块

优势:

  1. 业务无关的独立服务

劣势:

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

SOA架构(Service Oriented Architecture)

img

面向服务

优势:

  1. 服务注册

劣势:

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

微服务架构

img

彻底的服务化

优势:

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

劣势:

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

微服务架构概览

img

微服务架构核心要素

服务治理

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

可观察性

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

安全

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

微服务架构原理及特征

基本概念

img

  • 服务(Service)

    一组具有相同逻辑的运行实体

  • 实例(Instance)

    一个服务中,每个运行实体即为一个实例

  • 实例与进程的关系

    实例与进程直接没有必然对应关系,一个实例可以对应一个或多个进程(反之不常见)

  • 集群(Cluster)

    通常指服务内部的逻辑划分,包含多个实例

  • 常见的实例承载形式

    进程、VM、k8s pod…

  • 有状态/无状态服务

    服务的实例是否存储了可持久化的数据(例如磁盘文件)

  • 服务间通信

    对于单体服务,不同模块通信只是简单的函数调用

    对于微服务,服务间通信意味着网络传输

    img


例:如果将 HDFS 看做一组微服务:

img


服务注册与发现

服务注册

问题:在代码层面,如何指定调用一个目标服务的地址(ip:port)?

  • hardcode?

    img

    问题:如果写死了,就只能使用一个实例

  • DNS?

    img

    问题:

    1. 本地 DNS 存在缓存,导致延时

    2. 负载均衡问题

    3. 不支持服务实例的探活检查

    4. 域名无法配置接口


解决思路:新增一个统一的服务注册中心,用于存储服务名到服务实例的映射

img

服务发现

(服务上线及下线过程)

img

img

img

img

img

img

img

流量特征

img

  • 统一网关入口
  • 内网通信多采用PRC
  • 网状调用链路

总结

  • 微服务架构中基本组件及术语
  • 服务注册及发现
  • 无损的服务示例上下线流程
  • 微服务架构中的基本流量特征

核心服务治理功能

服务发布

服务发布(Deployment),指让一个服务升级运行新的代码的过程

服务发布的难点

  • 服务不可用

    img

  • 服务抖动

    img

  • 服务回滚

    img

蓝绿部署

先用另一个集群接替工作,原集群升级完毕后再切回来

img

img

img

img

img

img

简单、稳定,但是需要双倍资源

灰度发布(金丝雀发布)

让一些流量先适用新版本,再逐步扩大比例

img

img

img

img

img

img

占用资源小,但是也有不足,如某些问题是达到一定规模之后才能发现的,如果更新了99%才发现重大bug,那么要回滚会非常麻烦

流量治理

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

img

负载均衡

负载均衡(Load Balance)负责分配请求在每个下游实例上的分布

img

常见的 LB 策略:

  • Round Robin
  • Random
  • Ring Hash
  • Least Request

稳定性治理

线上服务总是会出问题的,这与程序的正确性无关

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

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

限流

img

(根据流量限度,该拒绝的拒绝,不能让服务卡死宕机)

熔断

img

(下游联系不到时,直接拒绝上游请求,不然上游会一直重试)

过载保护

img

(根据负载限度,该拒绝的拒绝,不能让服务卡死宕机)

降级

img

(对比服务的重要性,拒绝一些请求)

总结

  • 服务发布:蓝绿发布、灰度发布
  • 基于地区、集群、实例、请求等多维度的流量治理功能
  • 几种常见的负载均衡策略
  • 微服务架构中的稳定性治理功能

字节跳动服务治理实践

重试的意义

本地函数调用如果出错,重试没有意义,远程函数调用才有意义

  • 降低错误率

    假设单次请求的错误概率为0.01,那么连续两次错误的概率为0.0001

  • 降低长尾延时

    对于偶尔耗时较长的请求,重试请求有机会提前返回

  • 容忍暂时性错误

    可尽量规避网络抖动

  • 避开下游故障实例

    一个服务中可能会有少量实例故障,重试其他实例可以成功

重试的难点

既然重试有这么多好处,为什么默认不用呢

  • 幂等性(多次执行的结果是否相同,如对数据库中添加记录,连续执行两次就添加了两条记录)

  • 重试风暴

    img

    (如果每一次都无脑重试3次)

  • 超时设置

重试策略

限制重试比例

设定一个重试比例阈值(例如1%),重试次数占所有请求比例不超过该阈值

img

防止链路重试

链路层面的防重试风暴的核心是限制每层都发生重试,理想情况下只有最下一层发生重试,可以返回特殊的 status 表面 “请求失败,但别重试”

img

Hedged Request

对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,并等待先到的响应

img

重试效果验证

实践验证经过上述重试策略后,在链路上发生的重试放大效应

img

总结

  • 重试的意义及难点
  • 应对重试风暴的策略
原视频截图

image-20220603214941247

image-20220603215003990

image-20220603215051155

image-20220603215406969

image-20220603215448935

image-20220603215629975

image-20220603215830585

image-20220603220222622

image-20220603220233888

image-20220603220638113

image-20220603221057175

image-20220603221226932

image-20220603221355737

image-20220603221414071

image-20220603221455281

image-20220603221734043

image-20220603221839011

image-20220603222006386

image-20220603222017689

image-20220603222032762

image-20220603222108577

image-20220603222120677

image-20220603222142652

image-20220603222358493

image-20220603222506593

image-20220603222649761

image-20220603222913566

image-20220603222942947

image-20220603222947460

image-20220603222954548

image-20220603223116821

image-20220603223127375

image-20220603223719285

image-20220603223846532

image-20220603223935627

image-20220603224105179

image-20220603224126050

image-20220603224508158

image-20220603224558490

image-20220603224732443

image-20220603224826855

image-20220603224917767

image-20220603225102994

image-20220603225208540

image-20220603225336155

(如果每一次都无脑重试3次)

image-20220603225513996

image-20220603225716845

image-20220603225838931

image-20220603230039932

image-20220603230156787