[错误]并发限制过滤器在下游限制异常中泄露了活动计数
预选
- 所有内容均为英文.
- 我搜索了现有问题,并拉动请求 ActiveLimitFilter, ExecuteLimitFilter, 活动计数, 和限制例外清理。
Apache Dubbo 组件
Java SDK (apache/dubbo), dubbo-rpc-api过滤器和dubbo-集群过滤器链.
Dubbo 版本
3.3.7-SNAPSHOT,分行 "3.3 " ,位于 " dab47b7843 " ;Windows, OpenJDK 17.0.17, Maven 3.9.4.
· 复制这一问题的步骤
两种货币过滤器都跳过Rpcstatus.endCount ()',只要其错误的倾听者收到带有LIMIT-EXCEED-EXCEPTION'的`RpcExcution'。 当过滤器本身拒绝录取时,这是正确的跳过清理,但在录取成功时也跳过清理,而下游的援引者则抛出这种例外(或其反应未来将例外地完成)。
在“dubbo-cluster”试验(JUnit 5/Mockito;普通进口省略)中进行最小同步复制:
贾瓦 URL URL = URL. valueOf ("test://localhost:12345/limit-repro?Actives=1&timeout=1";). Invoker 目标=模拟(Invoker.class); 当(目标.getUrl ())时,返回(url); 当(目标.getInterface ())时,返回(对象.类); 当( 目标. invoke( 任何( )) ) 时, 然后 Throw () 新的 Rpc 例外(Rpc 例外.Limit EXCEED EXCEPTION,"下游拒绝") ;
过滤器过滤器 = 新的 ActiveLimitFilter (); Invoker < Object > 链条 = 新建过滤器ChanBuilder. CallbackRegistration Invoker * * * () 新建 FilterChanBuilder.CopyOfFilterChanNode(目标、目标、过滤器), 收藏. singletonList(过滤器)); RpcI援引=新的RpcI援引(); 引用. set 方法Name (“ invoke ”) ;
主张 Throws( Rpcexcion. class, () - > 链条. invoke( 引用) ); profile Equals( 0), Rpcstatus.getstatus(url, "invoke"). getAactive (); // 实际:1
将`活性=1'改为`执行=1',并使用`ExecuteLimitFilter'来复制提供者方的情况。
对于同步案件,将“新AsyncRpcResult(待决、援引)”从目标上返回,并在调用链条后例外地完成“待决”。 现数也为一.
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你预期会发生什么
取得货币槽的电话必须在下游故障时发出,并记录故障情况。 当地拒收不得放出另一个机上通话槽.
受限为1分,被泄露的计数导致后期活性限制的调用被暂停或执行限制的调用被否决,即使失败的调用已不再运行.
核查
我通过生产“CopyOfFFilterChainNode”/“召回注册”增加了8个参数化回归案例 (原始内容存档于2018-03-21). Invoker ' 生命周期. 在修复之前,所有4起下游失败案件都以`预期:<0>但为:<1>;4起局部拒绝/引用-再用控制通过而失败。 有0个测试错误。
修补将跟踪此过滤器是否为当前引用尝试获得了一个插槽, 将每个条目上的状态重置, 因此重复使用不会带有陈旧的录入状态 。
这涉及例外情况
. . . . . . .
内容来源: apache/dubbo