Преглед на файлове

Add default fallback support for Dubbo

- Update test cases and demo

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao преди 6 години
родител
ревизия
b37c237a61
променени са 10 файла, в които са добавени 207 реда и са изтрити 20 реда
  1. +3
    -2
      sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java
  2. +3
    -1
      sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java
  3. +34
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DefaultDubboFallback.java
  4. +39
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallback.java
  5. +48
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistry.java
  6. +56
    -0
      sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistryTest.java
  7. +8
    -12
      sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo1/FooConsumerBootstrap.java
  8. +3
    -1
      sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo1/FooProviderBootstrap.java
  9. +12
    -4
      sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo2/FooConsumerBootstrap.java
  10. +1
    -0
      sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo2/FooProviderBootstrap.java

+ 3
- 2
sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java Целия файл

@@ -19,10 +19,10 @@ import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.Filter;
import com.alibaba.dubbo.rpc.Invocation;
@@ -39,6 +39,7 @@ import com.alibaba.dubbo.rpc.RpcException;
* </pre>
*
* @author leyou
* @author Eric Zhao
*/
@Activate(group = "consumer")
public class SentinelDubboConsumerFilter extends AbstractDubboFilter implements Filter {
@@ -58,7 +59,7 @@ public class SentinelDubboConsumerFilter extends AbstractDubboFilter implements
methodEntry = SphU.entry(resourceName, EntryType.OUT);
return invoker.invoke(invocation);
} catch (BlockException e) {
throw new SentinelRpcException(e);
return DubboFallbackRegistry.getConsumerFallback().handle(invoker, invocation, e);
} catch (RpcException e) {
Tracer.trace(e);
throw e;


+ 3
- 1
sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java Целия файл

@@ -19,6 +19,7 @@ import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;
@@ -39,6 +40,7 @@ import com.alibaba.dubbo.rpc.RpcException;
* </pre>
*
* @author leyou
* @author Eric Zhao
*/
@Activate(group = "provider")
public class SentinelDubboProviderFilter extends AbstractDubboFilter implements Filter {
@@ -63,7 +65,7 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements

return invoker.invoke(invocation);
} catch (BlockException e) {
throw new SentinelRpcException(e);
return DubboFallbackRegistry.getProviderFallback().handle(invoker, invocation, e);
} catch (RpcException e) {
Tracer.trace(e);
throw e;


+ 34
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DefaultDubboFallback.java Целия файл

@@ -0,0 +1,34 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.dubbo.fallback;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;

/**
* @author Eric Zhao
*/
public class DefaultDubboFallback implements DubboFallback {

@Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) {
// Just wrap and throw the exception.
throw new SentinelRpcException(ex);
}
}

+ 39
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallback.java Целия файл

@@ -0,0 +1,39 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.dubbo.fallback;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;

/**
* Fallback handler for Dubbo services.
*
* @author Eric Zhao
*/
public interface DubboFallback {

/**
* Handle the block exception and provide fallback result.
*
* @param invoker Dubbo invoker
* @param invocation Dubbo invocation
* @param ex block exception
* @return fallback result
*/
Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex);
}

+ 48
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistry.java Целия файл

@@ -0,0 +1,48 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.dubbo.fallback;

/**
* Global fallback registry for Dubbo.
*
* Note: Degrading is mainly designed for consumer. The provider should not
* give fallback result in most circumstances.
*
* @author Eric Zhao
*/
public final class DubboFallbackRegistry {

private static volatile DubboFallback consumerFallback = new DefaultDubboFallback();
private static volatile DubboFallback providerFallback = new DefaultDubboFallback();

public static DubboFallback getConsumerFallback() {
return consumerFallback;
}

public static void setConsumerFallback(DubboFallback consumerFallback) {
DubboFallbackRegistry.consumerFallback = consumerFallback;
}

public static DubboFallback getProviderFallback() {
return providerFallback;
}

public static void setProviderFallback(DubboFallback providerFallback) {
DubboFallbackRegistry.providerFallback = providerFallback;
}

private DubboFallbackRegistry() {}
}

+ 56
- 0
sentinel-adapter/sentinel-dubbo-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/fallback/DubboFallbackRegistryTest.java Целия файл

@@ -0,0 +1,56 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.csp.sentinel.adapter.dubbo.fallback;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.dubbo.rpc.Invocation;
import com.alibaba.dubbo.rpc.Invoker;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcResult;

import org.junit.Assert;
import org.junit.Test;

/**
* @author Eric Zhao
*/
public class DubboFallbackRegistryTest {

@Test(expected = SentinelRpcException.class)
public void testDefaultFallback() {
// Test for default.
BlockException ex = new FlowException("xxx");
DubboFallbackRegistry.getConsumerFallback()
.handle(null, null, ex);
}

@Test
public void testCustomFallback() {
BlockException ex = new FlowException("xxx");
DubboFallbackRegistry.setConsumerFallback(new DubboFallback() {
@Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException e) {
return new RpcResult("Error: " + e.getClass().getName());
}
});
Result result = DubboFallbackRegistry.getConsumerFallback()
.handle(null, null, ex);
Assert.assertFalse("The invocation should not fail", result.hasException());
Assert.assertEquals("Error: " + ex.getClass().getName(), result.getValue());
}
}

+ 8
- 12
sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo1/FooConsumerBootstrap.java Целия файл

@@ -15,10 +15,8 @@
*/
package com.alibaba.csp.sentinel.demo.dubbo.demo1;


import com.alibaba.csp.sentinel.demo.dubbo.consumer.ConsumerConfiguration;
import com.alibaba.csp.sentinel.demo.dubbo.consumer.FooServiceConsumer;
import com.alibaba.csp.sentinel.init.InitExecutor;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -36,8 +34,6 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
public class FooConsumerBootstrap {

public static void main(String[] args) {
InitExecutor.doInit();

AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext();
consumerContext.register(ConsumerConfiguration.class);
consumerContext.refresh();
@@ -45,14 +41,14 @@ public class FooConsumerBootstrap {
FooServiceConsumer service = consumerContext.getBean(FooServiceConsumer.class);

for (int i = 0; i < 15; i++) {
try {
String message = service.sayHello("Eric");
System.out.println("Success: " + message);
} catch (SentinelRpcException ex) {
System.out.println("Blocked");
} catch (Exception ex) {
ex.printStackTrace();
}
try {
String message = service.sayHello("Eric");
System.out.println("Success: " + message);
} catch (SentinelRpcException ex) {
System.out.println("Blocked");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}

+ 3
- 1
sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo1/FooProviderBootstrap.java Целия файл

@@ -40,9 +40,11 @@ public class FooProviderBootstrap {
private static final String INTERFACE_RES_KEY = "com.alibaba.csp.sentinel.demo.dubbo.FooService";

public static void main(String[] args) {
initFlowRule();
// Users don't need to manually call this method.
InitExecutor.doInit();

initFlowRule();

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(ProviderConfiguration.class);
context.refresh();


+ 12
- 4
sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo2/FooConsumerBootstrap.java Целия файл

@@ -19,6 +19,7 @@ import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry;
import com.alibaba.csp.sentinel.concurrent.NamedThreadFactory;
import com.alibaba.csp.sentinel.demo.dubbo.consumer.ConsumerConfiguration;
import com.alibaba.csp.sentinel.demo.dubbo.consumer.FooServiceConsumer;
@@ -27,6 +28,8 @@ import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.SentinelRpcException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.dubbo.rpc.Result;
import com.alibaba.dubbo.rpc.RpcResult;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@@ -50,7 +53,6 @@ public class FooConsumerBootstrap {

public static void main(String[] args) {
initFlowRule();
InitExecutor.doInit();

AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext();
consumerContext.register(ConsumerConfiguration.class);
@@ -68,9 +70,7 @@ public class FooConsumerBootstrap {
ex.printStackTrace();
}
});
pool.submit(() -> {
System.out.println("Another: " + service.doAnother());
});
pool.submit(() -> System.out.println("Another: " + service.doAnother()));
}
}

@@ -82,4 +82,12 @@ public class FooConsumerBootstrap {
flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule));
}

private static void registerFallback() {
// Register fallback handler for consumer.
// If you only want to handle degrading, you need to
// check the type of BlockException.
DubboFallbackRegistry.setConsumerFallback((a, b, ex) ->
new RpcResult("Error: " + ex.getClass().getTypeName()));
}
}

+ 1
- 0
sentinel-demo/sentinel-demo-dubbo/src/main/java/com/alibaba/csp/sentinel/demo/dubbo/demo2/FooProviderBootstrap.java Целия файл

@@ -32,6 +32,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
public class FooProviderBootstrap {

public static void main(String[] args) {
// Users don't need to manually call this method.
InitExecutor.doInit();

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();


Loading…
Отказ
Запис