alibaba / alibaba/Sentinel

Throwing exceptions in customized slots | 自定义 Slot 中抛出自定义异常后,StatisticSlot 不会统计到

Open
#2,605 3 comments 0 reactions 0 assignees View on GitHub
kind/question wait-for-feedback
Dominant language
Java
Stars
23.1k
Forks
8.1k
PR merge metrics
No merged PRs in 30d

Description

Type: bug report

**Issue Description**

某些情况下StatisticNode中记录的统计信息可能是错误的

**Describe what happened (or what feature you want)**

如果自定义的ProcessSlot的entry方法中抛出了一个非BlockException,那么这个异常会在CtSph#entryWithPriority 执行ProcessSlot 调用链的时候被捕获且这个异常被忽略了,业务无感知。自定义ProcessSlot的entry执行失败,导致StatisticSlot的entry方法中并没有对 资源的并发数,通过数量等做统计。而在执行entry.exist的时候,StatisticSlot的exist方法会判断当前Entry是否有记录blockError,如果没有就会记录成功信息、往返时间,以及 对资源的并发持有数做减法,从而出现了统计信息错误的情况。

**Describe what you expected to happen**

**How to reproduce it (as minimally and precisely as possible)**
1,自定义一个ProcessSlot,将其放置在最后执行。 entry方法中抛出RuntimeException
2,正常使用Sentinel, 关注 entry.exist的时候 资源的ClusterNode中的curThreadNum

```
@Spi(order =0)
public class CustomSlot extends AbstractLinkedProcessorSlot {
@Override
public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode param, int count, boolean prioritized, Object... args) throws Throwable {
if (resourceWrapper.getName().contains("resourceA")) {

throw new RuntimeException("entry custome processor slot error");
}
fireEntry(context, resourceWrapper, param, count, prioritized, args);
}

@Override
public void exit(Context context, ResourceWrapper resourceWrapper, int count, Object... args) {
fireExit(context, resourceWrapper, count, args);

}
}

```

```
public static void testBug( ){
Entry resourceA = null;
try {
resourceA = SphU.entry("resourceA");
} catch (BlockException e) {
e.printStackTrace();
} catch (Throwable throwable){
//trace
}finally {
if (resourceA != null) {
try {
DefaultNode curNode = (DefaultNode) resourceA.getCurNode();
ClusterNode clusterNode = curNode.getClusterNode();
Field curThreadNumField = ReflectionUtils.findField(ClusterNode.class, "curThreadNum");
curThreadNumField.setAccessible(true);
LongAdder curThreadNum= (LongAdder)curThreadNumField.get(clusterNode);
// 多次执行 依次输出 0 ,-1 ,-2,-3,-4,-5.。。。。
System.out.println(curThreadNum.intValue());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
resourceA.exit();
}
}
}
```
``

environment
jdk 1.8/ senitnel1.8.3

Contributor guide

Open the contributing guide

Research direction

Start at CtSph#entryWithPriority and trace how StatisticSlot handles entry and exit when a customized ProcessSlot throws a non-BlockException. Reproduce the issue with the provided CustomSlot and resourceA example, then verify that ClusterNode.curThreadNum and related statistics no longer become negative after repeated calls.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend, observability
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.