微服务系统中的服务治理 | 青训营笔记

106 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第24天。补一下青训营第四阶段“微服务框架-不变的基建”的笔记,这节课主要介绍了微服务架构的原理及特征、核心服务治理能力以及字节跳动在微服务架构稳定性治理中的实践。

服务发现与注册

微服务架构中有一个关键问题是在服务间调用中,如何指定下游服务实例的地址, 比较直接的思路有以下两种:

直接指定ip:port: 这种方案首先没有任何动态能力,如果服务的种类或者调用关系有变故的话需要重新更改配置文件;另外如果一个服务对应多个下游实例也不好直接进行指定;

使用DNS: 这种方案具备一定的动态能力,但是有几个问题

  • 本地DNS存在缓存,会导致延迟
  • 没有负载均衡能力
  • 不支持服务探活检查
  • DNS不能指定端口

为了更好的解决这个问题,提出了服务注册发现的方案,该方案新增一个统一的服务注册中心,用于存储服务名到服务实例之间的映射关系,相当于用一个独立的KV存储服务来记录服务名与ip:port的映射关系,这个KV存储服务的载体可以是ETCD、nacos、zookeeper等,该方式下服务采用以下的方式来上下线:

  • 旧服务实例下线前,从服务注册中心删除该实例,下线流量;
  • 新服务实例上线后,在服务注册中心注册该实例,上线流量;

服务发布

让一个服务运行新的代码的过程就叫做服务发布,对于一个需要长期运行不允许停服的应用来说,服务发布有以下三个难点:

  • 服务不可用(直接停服)
  • 服务抖动(报很多错误)
  • 服务回滚(运行时出现错误需要将状态回滚) 两个解决方案
  • 蓝绿部署: 将服务分成两个部分分别先后发布,该方案实现起来简单稳定,但是需要消耗两倍的资源;
  • 灰度发布(金丝雀发布): 先发布少部分实例,接着逐步增加发布比例,该方案不需要增加资源,但是回滚难度大,基础设施要求高;

流量治理

微服务架构需要从各个维度对端到端的流量在链路上进行精确控制,例如地区维度、集群维度、实力维度、请求维度,需要开发一些中间件来实现这种流量控制;

负载均衡

Kitex提供了两种负载均衡策略

  • WeightedRandom(默认):依据实例的权重进行加权随机,保证每个实例分配到的负载和自己的权重成比例;
  • ConsistentHash:一致性哈希策略,用于对上下文依赖程度高的场景(希望同一类型的请求打到同一台机器),可在初始化client时传入client.WithLoadBalancer(loadbalance.NewConsistBalancer(loadbalance.NewConsistentHashOption(keyFunc)))

稳定性治理

稳定性治理包括

  • 限流:限制服务处理的最大QPS,拒绝过多请求
  • 熔断:中断请求路径,增加冷却时间从而让故障实例尝试恢复
  • 过载保护:在负载高的实例中,主动拒绝一部分请求,方式实例被打挂
  • 降级:服务处理能力不足时,拒绝低级别的请求,只向应线上高优先请求 Kitex实现了对最大连接数和最大QPS的限制,默认的策略为
资源策略
最大连接数简单计数器
最大QPS令牌桶算法

另外Kitex默认提供了三个基本的熔断触发策略:

  • 连续错误数达到阈值
  • 错误数达到阈值
  • 错误率达到阈值 除此之外,Kitex还提供了一个简单的中间件构造器acl来支持用户自定义访问控制的逻辑,可以借此来实现过载保护和降级