微服务架构 | 青训营

118 阅读5分钟

微服务架构介绍

系统架构演变历史

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

互联网爆炸性发展、硬件设施的快速发展、需求复杂、开发人员急剧增加……

单体架构

Image.png

优势:性能最高;冗余小

劣势:debug困难;模块互相影响;模块分工、开发流程

垂直应用架构

Image.png

按照业务线垂直划分

优势:业务之间独立开发维护

劣势:不同业务存在冗余;每个业务还是单体架构

分布式架构

Image.png

抽出与业务无关的公共模块

优势:业务无关的独立服务

劣势:服务模块bug导致全站瘫痪;调用关系复杂;不同服务间存在冗余

SOA架构

Image.png

面相服务,增加了服务注册更新

优势:服务注册

劣势:整个系统设计是中心化的;需要从上至下设计;重构困难

微服务架构

Image.png

彻底的服务化

优势:开发效率;业务独立化;自下而上;故障隔离

劣势:治理、运维难度;安全性;分布式系统

微服务架构概览

Image.png

网关处理外部流量

核心要素

  • 服务治理:服务注册;服务发现;负载均衡;扩缩容……

  • 可观测性:日志采集;日志分析;监控打点

  • 安全性:身份验证;认证授权;访问令牌

微服务架构原理及特征

基本概念

Image.png

  • 服务:一组具有相同逻辑(代码一样)运行实体

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

  • 实体与进程的关系:实例与进程之间没有必然的对应关系,可以一个实例对应一个或多个进程

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

  • 常见的实力承载形式:进程、VM、k8s pod……

  • 有状态/无状态服务:服务的实例是否存储了可以持久化的数据

  • 服务之间通信

    • 对于单体服务,不同模块通信只是简单的函数调用
    • 对于微服务,服务间通信意味着网络传输 Image.png

服务注册与发行

如何指定调用一个目标服务的地址?

若使用DNS存在以下问题:

  • 本地DNS存在缓存,导致延时
  • 负载均衡问题
  • 不支持服务实例的探活检查
  • 域名无法配置端口

新增一个统一的服务注册中心,用于存储服务名搭到服务实例映射。

Image.png

服务实例上线及下线过程

下线实例3过程

Image.png

  1. 在服务注册中心将服务3删去,过一段时间服务A不会调用实例3,因为A会不断刷新服务注册中心记录

  2. 下线实例3,因为已经没有流量可以安全下线 

上线实例3

Image.png

  1. 先添加实例,然后进行health check,测试该实例是否可以正常运行
  2. 再放入注册中心

流量特征

Image.png

  • 统一网关入口
  • 内网通信多数采用RPC,使用二进制形式,提高效率
  • 网状调用链路

核心服务治理功能

服务发布:

让一个服务升级运行新的代码的过程

难点

  • 服务不可用
  • 服务抖动,对某个实例无法提供服务
  • 服务回滚

蓝绿部署**

Image.png

要更新绿色的集群,先将流量切换到蓝色的集群,反之亦然。

简单、稳定,但需要两倍的资源。

灰度发布(金丝雀发布)

Image.png

先对一个实例进行发布,进行试探

流量处理

Image.png

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

对发往内部的流量进行标记,避免影响线上的用户

负载均衡(LB)

负责分配请求在每个下游实例上的分布

Image.png

常见的LB策略:random、round robin、ring hash……

稳定性治理

线上服务总是会出现问题,这与程序的正确性无关。例如网络攻击、流量冲突、机房断电……

稳定性治理功能:

1)限流

Image.png

2)熔断

Image.png

3)过载保护

Image.png

4)降级:重要的服务保证工作

Image.png

字节跳动服务治理实践

重试的意义

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

  • 降低长尾延时:对于偶尔耗时较长的请求,重试请求有机会提前返回

  • 容忍暂时性错误:某些时候系统会暂时性异常(例如抖动),重试可以尽量避免

  • 避开下游故障实例:服务可能会有少量实例故障(例如机器故障),重试其他实例可以成功

重试的问题

1)幂等性:任意多次执行所产生的影响与一次执行的影响相同

2)超时设置:第一次和第二次重试的时间间隔设置困难

3)重试风暴:微服务调用链路很深,重试次数呈指数级增长

解决方法:

  • 限制重试比例,设定一个重试比例阈值,重试次数占所有请求比例不超过该阈值

    Image.png

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

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

     Image.png