一. 概述
版本:2.7.8
解决问题
- 对服务方法或服务接口中所有服务方法并发调用请求进行限制
调用时机
- 消费端通过 org.apache.dubbo.rpc.filter.ActiveLimitFilter 进行限制
- 消费端在使用 DubboInvoker 的 invoke() 方法真正向远端发起RPC请求前,先调用 ActiveLimitFilter 的 invoke() 方法限制
二. 源码分析
RpcStatus类
源码说明:
- 该类表示提供端服务接口(包括接口中所有服务方法)、消费端服务接口(包括接口中所有服务方法)的当前调用次数、总数、失败数、调用间隔等状态信息
- 代码中有详细注释,重点关注beginCount方法、endCount方法
- SERVICE_STATISTICS/METHOD_STATISTICS是静态变量,相当于缓存
package org.apache.dubbo.rpc;
public class RpcStatus {
/**
* key 为服务接口(url.toIdentityString()),value 为该服务接口中所有方法的 RpcStatus 状态
* 静态变量:所有服务接口共用(缓存)
*/
private static final ConcurrentMap<String, RpcStatus> SERVICE_STATISTICS = new ConcurrentHashMap<>();
/**
* key 为服务接口(url.toIdentityString()),value 为 ConcurrentMap<String,RpcStatus> 对象,其中key为具体的服务方法,value为服务方法的 RpcStatus 状态
* 静态变量:所有服务接口共用(缓存)
*/
private static final ConcurrentMap<String, ConcurrentMap<String, RpcStatus>> METHOD_STATISTICS = new ConcurrentHashMap<>();
private final ConcurrentMap<String, Object> values = new ConcurrentHashMap<>();
// 服务方法正在执行中的数量
private final AtomicInteger active = new AtomicInteger();
// 服务方法调用的总数量
private final AtomicLong total = new AtomicLong();
// 服务方法调用失败的数量
private final AtomicInteger failed = new AtomicInteger();
private final AtomicLong totalElapsed = new AtomicLong();
private final AtomicLong failedElapsed = new AtomicLong();
private final AtomicLong maxElapsed = new AtomicLong();
private final AtomicLong failedMaxElapsed = new AtomicLong();
private final AtomicLong succeededMaxElapsed = new AtomicLong();
/**
* 根据 URL 返回服务接口的 RpcStatus 状态
*/
public static RpcStatus getStatus(URL url) {
String uri = url.toIdentityString();
return SERVICE_STATISTICS.computeIfAbsent(uri, key -> new RpcStatus());
}
/**
* 根据 URL 返回接口中服务方法的 RpcStatus 状态
*/
public static RpcStatus getStatus(URL url, String methodName) {
String uri = url.toIdentityString();
ConcurrentMap<String, RpcStatus> map = METHOD_STATISTICS.computeIfAbsent(uri, k -> new ConcurrentHashMap<>(