方法级并发数限制

概述

Service Keeper提供了方法级的隔离和并发数限制,底层基于信号量实现。使用时只需通过@ConcurrentLimiter注解的threshold属性设置并发数阈值即可。业界通常采用基于线程池的隔离术来实现资源间的隔离,这种方式效果更好,但也存在明显的不足:

  • 线程池数量太多,不便于管理
  • 线程之间切换频繁,增加了系统负荷

Service Keeper通过限制方法的并发调用数,使其占用的系统资源保持在可控的范围类(通常指线程资源),避免出现因某个方法耗尽系统资源导致整个系统不可用的"悲剧"。Service Keeper实现了与基于线程池隔离相似的效果,但占用的系统资源更少,使用方式更加灵活。

Note
  1. 并发数阈值(threshold参数)支持通过本地配置文件动态配置,实时生效。
  2. 对并发数超过限制的方法调用,如果原始方法正确配置了降级方法则执行该方法,否则直接抛出ConcurrentOverflowException

使用示例

在方法上使用@ConcurrentLimiter注解来完成方法的并发数限制,该注解只有一个属性threshold,表示并发数阈值,要求该值必须大于0。示例如下:

@RequestMapping("/list")
@ResponseBody
@ConcurrentLimiter(threshold = 100)
public Employee list() {
    return new Employee();
}

该配置表示同一时刻最多只允许100个线程执行该方法。

Note

如果配置文件中配置了该方法的最大并发数,则配置文件中的优先级更高。

注解配置简化

@RequestMapping("/list")
@ResponseBody
@ConcurrentLimiter(100) //表示threshold为100
public Employee list() {
    return new Employee();
}

配置文件配置

如前文所述,只要原始方法可以被ServiceKeeper拦截到,可以不使用@ConcurrentLimiter注解,直接在配置文件中配置并发数阈值即可完成对该方法的隔离和并发数限制。示例如下:

#并发数限制为10
io.esastack.servicekeeper.demo.ConcurrentLimitDemo.demoMethod.maxConcurrentLimit=10

其中,io.esastack.servicekeeper.demo.ConcurrentLimitDemo.demoMethod原始方法的名称(类全限定名+方法名)。

Note

通过配置文件配置并发数限制时 maxConcurrentLimit为必需配置。

动态更新参数限制

并不是所有的参数都支持动态更新,其中支持动态更新的参数项:动态参数配置项