这是我参与「第五届青训营 」伴学笔记创作活动的第 11 天
基本概念
服务(service)
一组具有相同逻辑的运行实体。
实例( instance)
一个服务中,每个运行实体即为一个实例。
实例与进程的关系
实例与进程之间没有必然对应关系,可以一个实例可以对应一个或多个进程(反之不常见).
集群(cluster)
通常指服务内部的逻辑划分,包含多个实例。
常见的实例承载形式
进程、VM、k8s pod ...
有状态/无状态服务
服务的实例是否存储了可持久化的数据(例如磁盘文件)。
服务间通信
- 对于单体服务,不同模块通信只是简单的函数调用。
- 对于微服务,服务间通信意味着网络传输。
服务注册及发现
DNS:
- 本地DNS存在缓存,导致延时。
- 负载均衡问题。
- 不支持服务实例的探活检查。
- 域名无法配置端口。
流量特征
- 统一网关入口
- 内网通信多数采用RPC
- 网状调用链路
核心服务治理功能
服务发布
服务发布(deployment),即指让一个服务升级运行新的代码的过程。
服务发布难点
蓝绿部署
简单、稳定,但是需要两倍资源。
流量治理
负载均衡
负载均衡(Load Balance)负责分配请求在每个下游实例上的分布。
稳定性治理
就算是代码写得再厉害,一点bug也没有,但是在上线后肯定会出现一些不可控的问题,这与程序的正确性无关。
例如:
- 网络攻击
- 流量突增
- 机房断电
- 光纤被挖
- 机器故障
- 网络故障
- 机房空调故障
典型的稳定性治理功能:
限流
熔断
过载保护
降级
重试的意义
降低错误率
- 假设单次请求的错误概率为0.01,那么连续两次错误概率则为0.0001。
降低长尾延时
- 对于偶尔耗时较长的请求,重试请求有机会提前返回。
容忍暂时性错误
- 某些时候系统会有暂时性异常(例如网络抖动),重试可以尽量规避。
避开下游故障实例
- 一个服务中可能会有少量实例故障(例如机器故障),重试其他实例可以成功。
重试策略
限制重试比例
设定一个重试比例阈值(例如1%),重试次数占所有请求比例不超过该阈值。
防止链路重试
链路层面的防重试风暴的核心是限制每层都发生重试,理想情况下只有最下一层发生重试。可以返回特殊的status表明“请求失败,但别重试”。
Hedged requests
对于可能超时(或延时高)的请求,重新向另一个下游实例发送一个相同的请求,并等待先到达的响应。
引用
本文全部内容来自- 字节内部课:后端入门 - Go 框架设计与实现