这是我参与「第三届青训营-后端场」笔记创作活动的的第7篇笔记.
一、微服务架构介绍
系统架构演变历史
单体
优势:性能高,冗余小
劣势:debug困难,模块互相影响,模块分工和开发流程
垂直
优势:业务独立开发维护
劣势:业务之间存在冗余,每个业务还是单体
分布式
优势:业务无关的独立服务
劣势:服务模块bug全部瘫痪,调用关系复杂,不同服务存在冗余
SOA:面向服务
优势:服务注册
劣势:系统设计中心化,从上至下设计,重构困难
微服务:彻底服务化
优势:开发效率,业务独立设计,自下而上,故障隔离
劣势(分布式系统存在的问题):治理、运维难度,观测挑战,安全性
架构概览
基本要素
服务治理
可观测性
安全
二、微服务架构原理及特征
基本组件
服务service:一组具有相同逻辑(同一份代码)的运行实体
实例instance:服务中的一个实体
实例与进程:没有必然对应关系,多为一个实例对应一个或多个进程
集群cluster:服务内部的逻辑划分,多个实例
常见的实例承载形式:进程、VM(虚拟机)、k8s pod
有状态/无状态服务:服务的实例是否存储了可持久化数据(比如磁盘文件)
HDFS:分布式文件系统,看作微服务
NameNode和DataNode逻辑不同,所以分开不同的服务
服务间通信
对于单体服务:不同模块通信只是函数调用
对于微服务:服务间通信意味着网络传输
工作原理
服务注册及发现
问题:调用一个目标服务的地址(ip:port),但是不止一个端口,ip也会变
使用DNS:一个域名多个ip
问题:本地DNS存在缓存,导致延时;可能存在负载均衡问题(DNS内ip是静态的,大家可能都去访问第一个);不支持服务实例的探活检查;域名无法配置端口
服务注册中心
增加一个服务注册中心,存储服务名到服务实例的映射
并使用random随机访问某个ip
服务实例上线下线过程
告知服务注册中心,不再分配此实例,再下线
上线后测试无误,告知服务注册中心
流量特征
统一网关入口
内网通信多采用RPC
网状调用链路
三、核心服务治理功能
服务发布
让一个服务升级运行新的代码的过程
难点:服务不可用,服务抖动,服务回滚
具体流程可参考《需求到开发全上线》
流量治理
基于地区、集群、实例、请求等维度,对端对端流量的路由过程进行控制
负载均衡 Load Balance
负责分配请求在每个下游实例上的分布
常见的LB策略:Round Robin, Random, Ring Hash(某用户有需求)
稳定性治理
限流
熔断
过载保护
降级
四、字节跳动服务治理实践:请求重试策略
重试的意义
可以避免掉偶发的错误,提高Service-level Agreement
降低错误率
降低长尾延时:对于偶尔耗时较长的请求,重试有机会提前返回
容忍暂时性错误:网络抖动
避开下游故障实例:可能少量实例故障(比如机器故障),但是重试其他实例可以成功
函数调用异常
本地函数调用的异常:此时没有必要重试
参数非法,Out Of Memory,Null Pointer Exception,边界case,系统崩溃,死循环,程序异常退出
远程函数调用异常:重试可能成功
网络抖动,下游负载高超时,下游机器宕机,本地机器负载高,调用超时
重试的难点
幂等性:每次重试结果都一样
超时设置:超时时间设置多少
重试风暴:链路上每次请求都放大一次
重试策略
限制重试比例:重试次数占所有请求比例不超过阈值
防止链路重试:防重试风暴的核心,限制每层都重试,理想情况下只有最下一层发生重试,返回特殊的status表明请求失败但不可重试
Hedged requests
对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,等待先到达的响应