高危接口访问熔断机制

简介:

背景介绍

阿里云ECS实例的停机、重启、释放等操作都属于高风险动作,直接影响到ECS实例本身所承载的计算任务和业务。特别是大批量操作时,更加需要明确停机或释放机器的准确性,一旦批量误操作甚至导致整个网站业务线的崩溃。为了防止造成这种巨大损失的局面,针对高风险操作接口提供一种限流熔断机制,批量操作时可以有效的制止过度的错误停机、重启及释放。

设计方案

ECS实例的停机、重启及释放属于高风险操作,未来随着接口应用的深入,其他接口也可能处于高风险状态,例如安全组ACL授权操作等。为了能够让所有高风险操作都可以使用该熔断机制,所以设计的首要原则是高风险接口与熔断机制本身解耦。
需要统计添加熔断机制接口单位时间内的调用频次,设置合理的熔断上限,在不影响日常合理调用的前提下,还需要考虑正常且正确的批量调用,需要提供临时白名单策略。白名单内的用户不受熔断机制限制,需要认真确认实例信息,以免造成大量错误停机、重启或释放的情况。
针对接口熔断类功能需要添加开关进行控制,并逐个地域进行开放,便于观察各接口的熔断情况和调整接口的熔断上限,通关开关的控制可以应对熔断机制带来的突发状况。比如熔断机制不合理,导致接口调用收到严重限制,没有接口只能通过回滚代码的方式进行恢复,时效性低并且存在风险。
设计方案的基本原则:

  • 需要熔断的接口与限流熔断机制之间解耦合;
  • 提供白名单策略,应对超过熔断上限的合理调用;
  • 提供开关策略统一控制各接口的熔断机制;

注解和切面(Annotation+Spect)的方式实现熔断

在不对需要熔断接口的代码做任何修改的前提下,只需要在接口的方法上添加熔断注解就可以实现熔断限流的作用,熔断功能模块独立,接口本身的逻辑和代码独立,通过添加注解的方式实现高内聚低耦合。
首先,定义一个熔断的注解AccessLimit:

/**
 * 高危接口熔断机制
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AccessLimit {}

通过注解@AccessLimit获取方法参数中调用者的信息,实现一个以@AccessLimit为入口的切面,该切面实现了熔断机制的全部逻辑。以调用者的信息作为Key,利用Tair天生Key/Value存储结构的统计该调用者在当前小时内的调用次数,Tair中提供累加的incr方法:

/**
 * @param namespace
 * @param key
 * @param value
 * @param defaultValue
 * @param expireTime
 * @return
 */
Result<Integer> incr(int namespace, Serializable key, int value, int defaultValue, int expireTime);

Tair统计每个调用者Key值过期之前的调用次数,达到熔断上限时抛出异常信息,提示达到风控上线的信息,并不再进一步调用该方法,达到熔断限流的效果。

Tair中incr方法的过期时间

针对同一个调用者,在过期之前的单位时间内,同一方法调用一次访问次数累加一次。incr方法需要注意的是过期时间参数每次调用都会更新的,这样就会存在问题:
1、如果已经达到访问上线,并可以继续执行incr,那么从最后一次访问开始重新记录过期时间。如果在释放Key之前继续访问,将导致该接口针对该用户无法访问。
2、如果已经达到访问上线,并阻止继续执行incr,那么从最后一次访问开始重新记录过期时间,直到该Key过期才能重新继续访问。
以上两种情况统计同一用户对同一接口的访问次数均不准确。解决该问题的方式需要将调用者的Key与当前时间相结合,熔断机制限制方式为每小时N次,任意小时内任何时间取整到小时都是同一个值,将该值与调用者信息拼接作为CacheKey,一天内同一调用者在任意小时内的CacheKey都不一样,这样即使incr方法中的过期时间每次更新,仍然可以准确统计每小时内的访问上线次数。不会出现以上两种请款带来的时间延迟或持续无法访问的情况。关于Key值处理:

/**
 * 获取 cache key
 * @param key
 * @return
 */
private String getCacheKey(String key) {
    Calendar calendar = Calendar.getInstance();
    String hour = String.valueOf(calendar.get(Calendar.HOUR_OF_DAY));
    StringBuilder cacheKey = new StringBuilder(key);
    cacheKey.append("#");
    cacheKey.append(hour)
    return cacheKey.toString();
}

总结

关于接口限流的熔断机制,利用注解和切面的方式进行实现,不仅设计逻辑明确、容易理解,而且很好的体现了高内聚低耦合的设计思想。结合白名单及开关的策略,使得熔断机制的使用更加广泛、安全、灵活。

目录
相关文章
|
消息中间件 设计模式 监控
如何优雅地实现接口统一调用?
【2月更文挑战第6天】
848 3
|
域名解析 监控 网络协议
Ping命令的替代工具有哪些?
【8月更文挑战第14天】Ping命令的替代工具有哪些?
849 2
|
数据采集 移动开发 监控
函数计算操作报错合集之返回时报错:{"ErrorCode":"AccessDenied","ErrorMessage":"unauthorized method 'POST'"},该如何配置
在使用函数计算服务(如阿里云函数计算)时,用户可能会遇到多种错误场景。以下是一些常见的操作报错及其可能的原因和解决方法,包括但不限于:1. 函数部署失败、2. 函数执行超时、3. 资源不足错误、4. 权限与访问错误、5. 依赖问题、6. 网络配置错误、7. 触发器配置错误、8. 日志与监控问题。
602 0
|
存储 Kubernetes 监控
Kubernetes(k8s)集群健康检查常用的五种指标
Kubernetes(k8s)集群健康检查常用的五种指标
1732 1
|
安全 应用服务中间件 数据安全/隐私保护
手把手带你部署Docker私有镜像仓库Harbor v2.3.2
手把手带你部署Docker私有镜像仓库Harbor v2.3.2
6081 0
|
JSON Kubernetes 监控
K8S之yaml 文件详解(pod、deployment、service)
K8S之yaml 文件详解(pod、deployment、service)
13445 3
K8S之yaml 文件详解(pod、deployment、service)
|
存储
什么是raid? 在虚拟机上实现raid5。 raid和热备盘
RAID 是洋文“Redundant Array of Inexpensive Disks”的缩写,中文称之为“磁盘冗余阵列”。
944 0
|
存储 弹性计算 运维
阿里云无影云电脑具体价格
阿里云无影云电脑具体价格,阿里云无影云电脑配置具体价格表,无影云桌面4核8G企业办公型云电脑可以免费使用3个月,无影云电脑地域不同价格不同,无影云电脑价格是由云桌面配置、云盘价格、互联网访问带宽价格、AD Connector 价格、桌面组共用桌面session 价格等费用组成
181 0
|
JavaScript 小程序 Java
Spring Boot 实现日志链路追踪,无需引入组件,让日志定位更方便!
Spring Boot 实现日志链路追踪,无需引入组件,让日志定位更方便!
|
负载均衡 监控 Java
5 种主流API网关技术选型,yyds! 上
5 种主流API网关技术选型,yyds! 上