Переглянути джерело

Add exceptionsToIgnore configuration support in @SentinelResource annotation (#683)

master
yikangfeng Eric Zhao 5 роки тому
джерело
коміт
08611fae0f
4 змінених файлів з 57 додано та 8 видалено
  1. +10
    -0
      sentinel-core/src/main/java/com/alibaba/csp/sentinel/annotation/SentinelResource.java
  2. +26
    -7
      sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/AbstractSentinelAspectSupport.java
  3. +16
    -0
      sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/integration/SentinelAnnotationIntegrationTest.java
  4. +5
    -1
      sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/integration/service/FooService.java

+ 10
- 0
sentinel-core/src/main/java/com/alibaba/csp/sentinel/annotation/SentinelResource.java Переглянути файл

@@ -65,4 +65,14 @@ public @interface SentinelResource {
* @since 1.5.1 * @since 1.5.1
*/ */
Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class}; Class<? extends Throwable>[] exceptionsToTrace() default {Throwable.class};
/**
* Indicates the exceptions to be ignored. Note that {@code exceptionsToTrace} should
* not appear with {@code exceptionsToIgnore} at the same time, or {@code exceptionsToIgnore}
* will be of higher precedence.
*
* @return the list of exception classes to ignore, empty by default
* @since 1.6.0
*/
Class<? extends Throwable>[] exceptionsToIgnore() default {};
} }

+ 26
- 7
sentinel-extension/sentinel-annotation-aspectj/src/main/java/com/alibaba/csp/sentinel/annotation/aspectj/AbstractSentinelAspectSupport.java Переглянути файл

@@ -53,7 +53,7 @@ public abstract class AbstractSentinelAspectSupport {
} }


protected Object handleBlockException(ProceedingJoinPoint pjp, String fallback, String blockHandler, protected Object handleBlockException(ProceedingJoinPoint pjp, String fallback, String blockHandler,
Class<?>[] blockHandlerClass, BlockException ex) throws Exception {
Class<?>[] blockHandlerClass, BlockException ex) throws Exception {
// Execute fallback for degrading if configured. // Execute fallback for degrading if configured.
Object[] originArgs = pjp.getArgs(); Object[] originArgs = pjp.getArgs();
if (isDegradeFailure(ex)) { if (isDegradeFailure(ex)) {
@@ -78,6 +78,11 @@ public abstract class AbstractSentinelAspectSupport {
} }


protected void traceException(Throwable ex, SentinelResource annotation) { protected void traceException(Throwable ex, SentinelResource annotation) {
Class<? extends Throwable>[] exceptionsToIgnore = annotation.exceptionsToIgnore();
// The ignore list will be checked first.
if (exceptionsToIgnore.length > 0 && isIgnoredException(ex, exceptionsToIgnore)) {
return;
}
if (isTracedException(ex, annotation.exceptionsToTrace())) { if (isTracedException(ex, annotation.exceptionsToTrace())) {
Tracer.trace(ex); Tracer.trace(ex);
} }
@@ -86,8 +91,10 @@ public abstract class AbstractSentinelAspectSupport {
/** /**
* Check whether the exception is in tracked list of exception classes. * Check whether the exception is in tracked list of exception classes.
* *
* @param ex provided throwable
* @param exceptionsToTrace list of exceptions to trace
* @param ex
* provided throwable
* @param exceptionsToTrace
* list of exceptions to trace
* @return true if it should be traced, otherwise false * @return true if it should be traced, otherwise false
*/ */
private boolean isTracedException(Throwable ex, Class<? extends Throwable>[] exceptionsToTrace) { private boolean isTracedException(Throwable ex, Class<? extends Throwable>[] exceptionsToTrace) {
@@ -102,6 +109,18 @@ public abstract class AbstractSentinelAspectSupport {
return false; return false;
} }


private boolean isIgnoredException(Throwable ex, Class<? extends Throwable>[] exceptionsToIgnore) {
if (exceptionsToIgnore == null) {
return false;
}
for (Class<? extends Throwable> exceptionToIgnore : exceptionsToIgnore) {
if (exceptionToIgnore.isAssignableFrom(ex.getClass())) {
return true;
}
}
return false;
}

private boolean isDegradeFailure(/*@NonNull*/ BlockException ex) { private boolean isDegradeFailure(/*@NonNull*/ BlockException ex) {
return ex instanceof DegradeException; return ex instanceof DegradeException;
} }
@@ -176,8 +195,8 @@ public abstract class AbstractSentinelAspectSupport {
Method[] methods = clazz.getDeclaredMethods(); Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) { for (Method method : methods) {
if (name.equals(method.getName()) && checkStatic(mustStatic, method) if (name.equals(method.getName()) && checkStatic(mustStatic, method)
&& returnType.isAssignableFrom(method.getReturnType())
&& Arrays.equals(parameterTypes, method.getParameterTypes())) {
&& returnType.isAssignableFrom(method.getReturnType())
&& Arrays.equals(parameterTypes, method.getParameterTypes())) {


RecordLog.info("Resolved method [{0}] in class [{1}]", name, clazz.getCanonicalName()); RecordLog.info("Resolved method [{0}] in class [{1}]", name, clazz.getCanonicalName());
return method; return method;
@@ -190,7 +209,7 @@ public abstract class AbstractSentinelAspectSupport {
} else { } else {
String methodType = mustStatic ? " static" : ""; String methodType = mustStatic ? " static" : "";
RecordLog.warn("Cannot find{0} method [{1}] in class [{2}] with parameters {3}", RecordLog.warn("Cannot find{0} method [{1}] in class [{2}] with parameters {3}",
methodType, name, clazz.getCanonicalName(), Arrays.toString(parameterTypes));
methodType, name, clazz.getCanonicalName(), Arrays.toString(parameterTypes));
return null; return null;
} }
} }
@@ -204,7 +223,7 @@ public abstract class AbstractSentinelAspectSupport {
Class<?> targetClass = joinPoint.getTarget().getClass(); Class<?> targetClass = joinPoint.getTarget().getClass();


Method method = getDeclaredMethodFor(targetClass, signature.getName(), Method method = getDeclaredMethodFor(targetClass, signature.getName(),
signature.getMethod().getParameterTypes());
signature.getMethod().getParameterTypes());
if (method == null) { if (method == null) {
throw new IllegalStateException("Cannot resolve target method: " + signature.getMethod().getName()); throw new IllegalStateException("Cannot resolve target method: " + signature.getMethod().getName());
} }


+ 16
- 0
sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/integration/SentinelAnnotationIntegrationTest.java Переглянути файл

@@ -83,6 +83,22 @@ public class SentinelAnnotationIntegrationTest extends AbstractJUnit4SpringConte
fooService.baz("Sentinel"); fooService.baz("Sentinel");
} }


@Test
public void testAnnotationExceptionsToIgnore() {
assertThat(fooService.baz("Sentinel")).isEqualTo("cheers, Sentinel");
String resourceName = "apiBaz";
ClusterNode cn = ClusterBuilderSlot.getClusterNode(resourceName);
assertThat(cn).isNotNull();
assertThat(cn.passQps()).isPositive();

try {
fooService.baz("fail");
fail("should not reach here");
} catch (IllegalMonitorStateException ex) {
assertThat(cn.exceptionQps()).isZero();
}
}

@Test @Test
public void testNormalBlockHandlerAndFallback() throws Exception { public void testNormalBlockHandlerAndFallback() throws Exception {
assertThat(fooService.foo(1)).isEqualTo("Hello for 1"); assertThat(fooService.foo(1)).isEqualTo("Hello for 1");


+ 5
- 1
sentinel-extension/sentinel-annotation-aspectj/src/test/java/com/alibaba/csp/sentinel/annotation/aspectj/integration/service/FooService.java Переглянути файл

@@ -49,8 +49,12 @@ public class FooService {
return ThreadLocalRandom.current().nextInt(0, 30000); return ThreadLocalRandom.current().nextInt(0, 30000);
} }


@SentinelResource(value = "apiBaz", blockHandler = "bazBlockHandler")
@SentinelResource(value = "apiBaz", blockHandler = "bazBlockHandler",
exceptionsToIgnore = {IllegalMonitorStateException.class})
public String baz(String name) { public String baz(String name) {
if (name.equals("fail")) {
throw new IllegalMonitorStateException("boom!");
}
return "cheers, " + name; return "cheers, " + name;
} }




Завантаження…
Відмінити
Зберегти