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

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


return invoker.invoke(invocation); return invoker.invoke(invocation);
} catch (BlockException e) { } catch (BlockException e) {
throw new SentinelRpcException(e);
return DubboFallbackRegistry.getProviderFallback().handle(invoker, invocation, e);
} catch (RpcException e) { } catch (RpcException e) {
Tracer.trace(e); Tracer.trace(e);
throw 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; 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.ConsumerConfiguration;
import com.alibaba.csp.sentinel.demo.dubbo.consumer.FooServiceConsumer; 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 com.alibaba.csp.sentinel.slots.block.SentinelRpcException;


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


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

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


for (int i = 0; i < 15; i++) { 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"; private static final String INTERFACE_RES_KEY = "com.alibaba.csp.sentinel.demo.dubbo.FooService";


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


initFlowRule();

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(ProviderConfiguration.class); context.register(ProviderConfiguration.class);
context.refresh(); 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.ExecutorService;
import java.util.concurrent.Executors; 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.concurrent.NamedThreadFactory;
import com.alibaba.csp.sentinel.demo.dubbo.consumer.ConsumerConfiguration; import com.alibaba.csp.sentinel.demo.dubbo.consumer.ConsumerConfiguration;
import com.alibaba.csp.sentinel.demo.dubbo.consumer.FooServiceConsumer; 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.SentinelRpcException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; 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; import org.springframework.context.annotation.AnnotationConfigApplicationContext;


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


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


AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext consumerContext = new AnnotationConfigApplicationContext();
consumerContext.register(ConsumerConfiguration.class); consumerContext.register(ConsumerConfiguration.class);
@@ -68,9 +70,7 @@ public class FooConsumerBootstrap {
ex.printStackTrace(); 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"); flowRule.setLimitApp("default");
FlowRuleManager.loadRules(Collections.singletonList(flowRule)); 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 class FooProviderBootstrap {


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


AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();


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