Polish Dubbo 2.6.x adapter and unify callback registry into DubboAdapterGlobalConfig (#1572)
* Unify Dubbo callback registry (for fallback and origin parser) into DubboAdapterGlobalConfig * Polish default fallback implementation (wrap exception with RpcResult rather than directly throw it out) Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
parent
5334f51d21
commit
58ff01e39b
|
|
@ -1,6 +1,6 @@
|
|||
# Sentinel Dubbo Adapter
|
||||
|
||||
> Note: 中文文档请见[此处](https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6%E7%9A%84%E9%80%82%E9%85%8D#dubbo)。
|
||||
> Note: 中文文档请见[此处](https://github.com/alibaba/Sentinel/wiki/主流框架的适配#dubbo)。
|
||||
|
||||
Sentinel Dubbo Adapter provides service consumer filter and provider filter
|
||||
for [Dubbo](https://dubbo.apache.org/en-us/) services.
|
||||
|
|
@ -52,23 +52,21 @@ If `limitApp` of flow rules is not configured (`default`), flow control will tak
|
|||
If `limitApp` of a flow rule is configured with a caller, then the corresponding flow rule will only take effect on the specific caller.
|
||||
|
||||
> Note: Dubbo consumer does not provide its Dubbo application name when doing RPC,
|
||||
so developers should manually put the application name into *attachment* at consumer side,
|
||||
then extract it at provider side. Sentinel Dubbo Adapter has implemented a filter (`DubboAppContextFilter`)
|
||||
where consumer can carry application name information to provider automatically.
|
||||
If the consumer does not use Sentinel Dubbo Adapter but requires flow control based on caller, developers can manually put the application name into attachment with the key `dubboApplication`.
|
||||
> so developers should manually put the application name into *attachment* at consumer side,
|
||||
> then extract it at provider side. Sentinel Dubbo Adapter has implemented a filter (`DubboAppContextFilter`)
|
||||
> where consumer can carry application name information to provider automatically.
|
||||
> If the consumer does not use Sentinel Dubbo Adapter but requires flow control based on caller,
|
||||
> developers can manually put the application name into attachment with the key `dubboApplication`.
|
||||
>
|
||||
> Since 1.8.0, the adapter provides support for customizing origin parsing logic. You may register your own `DubboOriginParser`
|
||||
> implementation to `DubboAdapterGlobalConfig`.
|
||||
|
||||
## Global fallback
|
||||
|
||||
Sentinel Dubbo Adapter supports global fallback configuration.
|
||||
The global fallback will handle exceptions and give replacement result when blocked by
|
||||
flow control, degrade or system load protection. You can implement your own `DubboFallback` interface
|
||||
and then register to `DubboFallbackRegistry`. If no fallback is configured, Sentinel will wrap the `BlockException`
|
||||
then directly throw it out.
|
||||
and then register to `DubboAdapterGlobalConfig`.
|
||||
If no fallback is configured, Sentinel will wrap the `BlockException` as the fallback result.
|
||||
|
||||
Besides, we can also leverage [Dubbo mock mechanism](http://dubbo.apache.org/en-us/docs/user/demos/local-mock.html) to provide fallback implementation of degraded Dubbo services.
|
||||
|
||||
## Global dubbo provider origin parse
|
||||
|
||||
Sentinel Dubbo Adapter supports global origin parse for provider.
|
||||
You can implement your own `DubboOriginParser` interface
|
||||
and then register to `DubboOriginParserRegistry`. If no originParse is configured, Sentinel will user dubbo url property application.
|
||||
Besides, we can also leverage [Dubbo mock mechanism](http://dubbo.apache.org/en-us/docs/user/demos/local-mock.html) to provide fallback implementation of degraded Dubbo services.
|
||||
|
|
@ -25,12 +25,12 @@ import com.alibaba.dubbo.rpc.Invoker;
|
|||
*/
|
||||
abstract class AbstractDubboFilter implements Filter {
|
||||
|
||||
protected String getResourceName(Invoker<?> invoker, Invocation invocation) {
|
||||
protected String getMethodResourceName(Invoker<?> invoker, Invocation invocation) {
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
buf.append(invoker.getInterface().getName())
|
||||
.append(":")
|
||||
.append(invocation.getMethodName())
|
||||
.append("(");
|
||||
.append(":")
|
||||
.append(invocation.getMethodName())
|
||||
.append("(");
|
||||
boolean isFirst = true;
|
||||
for (Class<?> clazz : invocation.getParameterTypes()) {
|
||||
if (!isFirst) {
|
||||
|
|
@ -43,15 +43,24 @@ abstract class AbstractDubboFilter implements Filter {
|
|||
return buf.toString();
|
||||
}
|
||||
|
||||
protected String getResourceName(Invoker<?> invoker, Invocation invocation, String prefix) {
|
||||
protected String getMethodResourceName(Invoker<?> invoker, Invocation invocation, String prefix) {
|
||||
if (StringUtil.isBlank(prefix)) {
|
||||
return getResourceName(invoker, invocation);
|
||||
return getMethodResourceName(invoker, invocation);
|
||||
}
|
||||
StringBuilder buf = new StringBuilder(64);
|
||||
return buf.append(prefix)
|
||||
.append(getResourceName(invoker, invocation))
|
||||
.toString();
|
||||
.append(getMethodResourceName(invoker, invocation))
|
||||
.toString();
|
||||
}
|
||||
|
||||
protected String getInterfaceName(Invoker<?> invoker) {
|
||||
return invoker.getInterface().getName();
|
||||
}
|
||||
|
||||
protected String getInterfaceName(Invoker<?> invoker, String prefix) {
|
||||
if (StringUtil.isBlank(prefix)) {
|
||||
return getInterfaceName(invoker);
|
||||
}
|
||||
return prefix + getInterfaceName(invoker);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DefaultDubboFallback;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallback;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.origin.DefaultDubboOriginParser;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.origin.DubboOriginParser;
|
||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
/**
|
||||
* <p>Global config and callback registry of Dubbo legacy adapter.</p>
|
||||
*
|
||||
* @author lianglin
|
||||
* @author Eric Zhao
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public final class DubboAdapterGlobalConfig {
|
||||
|
||||
private static final String TRUE_STR = "true";
|
||||
|
||||
public static final String DUBBO_RES_NAME_WITH_PREFIX_KEY = "csp.sentinel.dubbo.resource.use.prefix";
|
||||
public static final String DUBBO_PROVIDER_RES_NAME_PREFIX_KEY = "csp.sentinel.dubbo.resource.provider.prefix";
|
||||
public static final String DUBBO_CONSUMER_RES_NAME_PREFIX_KEY = "csp.sentinel.dubbo.resource.consumer.prefix";
|
||||
|
||||
private static final String DEFAULT_DUBBO_PROVIDER_PREFIX = "dubbo:provider:";
|
||||
private static final String DEFAULT_DUBBO_CONSUMER_PREFIX = "dubbo:consumer:";
|
||||
|
||||
private static volatile DubboFallback consumerFallback = new DefaultDubboFallback();
|
||||
private static volatile DubboFallback providerFallback = new DefaultDubboFallback();
|
||||
private static volatile DubboOriginParser originParser = new DefaultDubboOriginParser();
|
||||
|
||||
public static boolean isUsePrefix() {
|
||||
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_RES_NAME_WITH_PREFIX_KEY));
|
||||
}
|
||||
|
||||
public static String getDubboProviderPrefix() {
|
||||
if (isUsePrefix()) {
|
||||
String config = SentinelConfig.getConfig(DUBBO_PROVIDER_RES_NAME_PREFIX_KEY);
|
||||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_PROVIDER_PREFIX;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getDubboConsumerPrefix() {
|
||||
if (isUsePrefix()) {
|
||||
String config = SentinelConfig.getConfig(DUBBO_CONSUMER_RES_NAME_PREFIX_KEY);
|
||||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_CONSUMER_PREFIX;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DubboFallback getConsumerFallback() {
|
||||
return consumerFallback;
|
||||
}
|
||||
|
||||
public static void setConsumerFallback(DubboFallback consumerFallback) {
|
||||
AssertUtil.notNull(consumerFallback, "consumerFallback cannot be null");
|
||||
DubboAdapterGlobalConfig.consumerFallback = consumerFallback;
|
||||
}
|
||||
|
||||
public static DubboFallback getProviderFallback() {
|
||||
return providerFallback;
|
||||
}
|
||||
|
||||
public static void setProviderFallback(DubboFallback providerFallback) {
|
||||
AssertUtil.notNull(providerFallback, "providerFallback cannot be null");
|
||||
DubboAdapterGlobalConfig.providerFallback = providerFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the origin parser of Dubbo adapter.
|
||||
*
|
||||
* @return the origin parser
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public static DubboOriginParser getOriginParser() {
|
||||
return originParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the origin parser of Dubbo adapter.
|
||||
*
|
||||
* @param originParser the origin parser
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public static void setOriginParser(DubboOriginParser originParser) {
|
||||
AssertUtil.notNull(originParser, "originParser cannot be null");
|
||||
DubboAdapterGlobalConfig.originParser = originParser;
|
||||
}
|
||||
|
||||
private DubboAdapterGlobalConfig() {}
|
||||
}
|
||||
|
|
@ -20,8 +20,6 @@ import com.alibaba.csp.sentinel.EntryType;
|
|||
import com.alibaba.csp.sentinel.ResourceTypeConstants;
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
import com.alibaba.csp.sentinel.Tracer;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
import com.alibaba.dubbo.common.extension.Activate;
|
||||
|
|
@ -56,10 +54,12 @@ public class SentinelDubboConsumerFilter extends AbstractDubboFilter implements
|
|||
Entry interfaceEntry = null;
|
||||
Entry methodEntry = null;
|
||||
try {
|
||||
String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix());
|
||||
interfaceEntry = SphU.entry(invoker.getInterface().getName(), ResourceTypeConstants.COMMON_RPC,
|
||||
EntryType.OUT);
|
||||
methodEntry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT, invocation.getArguments());
|
||||
String prefix = DubboAdapterGlobalConfig.getDubboConsumerPrefix();
|
||||
String interfaceResourceName = getInterfaceName(invoker, prefix);
|
||||
String methodResourceName = getMethodResourceName(invoker, invocation, prefix);
|
||||
interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT);
|
||||
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC,
|
||||
EntryType.OUT, invocation.getArguments());
|
||||
|
||||
Result result = invoker.invoke(invocation);
|
||||
if (result.hasException()) {
|
||||
|
|
@ -70,7 +70,7 @@ public class SentinelDubboConsumerFilter extends AbstractDubboFilter implements
|
|||
}
|
||||
return result;
|
||||
} catch (BlockException e) {
|
||||
return DubboFallbackRegistry.getConsumerFallback().handle(invoker, invocation, e);
|
||||
return DubboAdapterGlobalConfig.getConsumerFallback().handle(invoker, invocation, e);
|
||||
} catch (RpcException e) {
|
||||
Tracer.traceEntry(e, interfaceEntry);
|
||||
Tracer.traceEntry(e, methodEntry);
|
||||
|
|
|
|||
|
|
@ -20,9 +20,6 @@ import com.alibaba.csp.sentinel.EntryType;
|
|||
import com.alibaba.csp.sentinel.ResourceTypeConstants;
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
import com.alibaba.csp.sentinel.Tracer;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.fallback.DubboFallbackRegistry;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.origin.DubboOriginParserRegistry;
|
||||
import com.alibaba.csp.sentinel.context.ContextUtil;
|
||||
import com.alibaba.csp.sentinel.log.RecordLog;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
|
|
@ -56,7 +53,7 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements
|
|||
@Override
|
||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
|
||||
// Get origin caller.
|
||||
String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(invoker, invocation);
|
||||
String origin = DubboAdapterGlobalConfig.getOriginParser().parse(invoker, invocation);
|
||||
if (null == origin) {
|
||||
origin = "";
|
||||
}
|
||||
|
|
@ -64,11 +61,12 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements
|
|||
Entry interfaceEntry = null;
|
||||
Entry methodEntry = null;
|
||||
try {
|
||||
String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix());
|
||||
String interfaceName = invoker.getInterface().getName();
|
||||
ContextUtil.enter(resourceName, origin);
|
||||
String prefix = DubboAdapterGlobalConfig.getDubboProviderPrefix();
|
||||
String methodResourceName = getMethodResourceName(invoker, invocation, prefix);
|
||||
String interfaceName = getInterfaceName(invoker, prefix);
|
||||
ContextUtil.enter(methodResourceName, origin);
|
||||
interfaceEntry = SphU.entry(interfaceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN);
|
||||
methodEntry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_RPC,
|
||||
methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC,
|
||||
EntryType.IN, invocation.getArguments());
|
||||
|
||||
Result result = invoker.invoke(invocation);
|
||||
|
|
@ -80,7 +78,7 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements
|
|||
}
|
||||
return result;
|
||||
} catch (BlockException e) {
|
||||
return DubboFallbackRegistry.getProviderFallback().handle(invoker, invocation, e);
|
||||
return DubboAdapterGlobalConfig.getProviderFallback().handle(invoker, invocation, e);
|
||||
} catch (RpcException e) {
|
||||
Tracer.traceEntry(e, interfaceEntry);
|
||||
Tracer.traceEntry(e, methodEntry);
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* 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.config;
|
||||
|
||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Responsible for dubbo service provider, consumer attribute configuration
|
||||
* </p>
|
||||
*
|
||||
* @author lianglin
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public final class DubboConfig {
|
||||
|
||||
public static final String DUBBO_USE_PREFIX = "csp.sentinel.dubbo.resource.use.prefix";
|
||||
private static final String TRUE_STR = "true";
|
||||
|
||||
public static final String DUBBO_PROVIDER_PREFIX = "csp.sentinel.dubbo.resource.provider.prefix";
|
||||
public static final String DUBBO_CONSUMER_PREFIX = "csp.sentinel.dubbo.resource.consumer.prefix";
|
||||
|
||||
private static final String DEFAULT_DUBBO_PROVIDER_PREFIX = "dubbo:provider:";
|
||||
private static final String DEFAULT_DUBBO_CONSUMER_PREFIX = "dubbo:consumer:";
|
||||
|
||||
public static boolean isUsePrefix() {
|
||||
return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_USE_PREFIX));
|
||||
}
|
||||
|
||||
|
||||
public static String getDubboProviderPrefix() {
|
||||
if (isUsePrefix()) {
|
||||
String config = SentinelConfig.getConfig(DUBBO_PROVIDER_PREFIX);
|
||||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_PROVIDER_PREFIX;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getDubboConsumerPrefix() {
|
||||
if (isUsePrefix()) {
|
||||
String config = SentinelConfig.getConfig(DUBBO_CONSUMER_PREFIX);
|
||||
return StringUtil.isNotBlank(config) ? config : DEFAULT_DUBBO_CONSUMER_PREFIX;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ 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;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
|
||||
/**
|
||||
* @author Eric Zhao
|
||||
|
|
@ -28,7 +29,7 @@ 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);
|
||||
// Just wrap the exception.
|
||||
return new RpcResult(new SentinelRpcException(ex));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,33 +15,31 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.adapter.dubbo.fallback;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.DubboAdapterGlobalConfig;
|
||||
|
||||
/**
|
||||
* Global fallback registry for Dubbo.
|
||||
*
|
||||
* Note: Degrading is mainly designed for consumer. The provider should not
|
||||
* give fallback result in most circumstances.
|
||||
* <p>Global fallback registry for Dubbo.</p>
|
||||
*
|
||||
* @author Eric Zhao
|
||||
* @deprecated use {@link DubboAdapterGlobalConfig} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class DubboFallbackRegistry {
|
||||
|
||||
private static volatile DubboFallback consumerFallback = new DefaultDubboFallback();
|
||||
private static volatile DubboFallback providerFallback = new DefaultDubboFallback();
|
||||
|
||||
public static DubboFallback getConsumerFallback() {
|
||||
return consumerFallback;
|
||||
return DubboAdapterGlobalConfig.getConsumerFallback();
|
||||
}
|
||||
|
||||
public static void setConsumerFallback(DubboFallback consumerFallback) {
|
||||
DubboFallbackRegistry.consumerFallback = consumerFallback;
|
||||
DubboAdapterGlobalConfig.setConsumerFallback(consumerFallback);
|
||||
}
|
||||
|
||||
public static DubboFallback getProviderFallback() {
|
||||
return providerFallback;
|
||||
return DubboAdapterGlobalConfig.getProviderFallback();
|
||||
}
|
||||
|
||||
public static void setProviderFallback(DubboFallback providerFallback) {
|
||||
DubboFallbackRegistry.providerFallback = providerFallback;
|
||||
DubboAdapterGlobalConfig.setProviderFallback(providerFallback);
|
||||
}
|
||||
|
||||
private DubboFallbackRegistry() {}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,10 @@ import com.alibaba.dubbo.rpc.Invocation;
|
|||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
|
||||
/**
|
||||
* Default Dubbo origin parse.
|
||||
* Default Dubbo origin parser.
|
||||
*
|
||||
* @author tiecheng
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public class DefaultDubboOriginParser implements DubboOriginParser {
|
||||
|
||||
|
|
|
|||
|
|
@ -15,23 +15,23 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.adapter.dubbo.origin;
|
||||
|
||||
import com.alibaba.csp.sentinel.context.Context;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
|
||||
/**
|
||||
* Customized origin parse in Dubbo provider filter. {@link Context#getOrigin()}
|
||||
* Customized origin parser for Dubbo provider filter.
|
||||
*
|
||||
* @author tiecheng
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public interface DubboOriginParser {
|
||||
|
||||
/**
|
||||
* Handle the origin parse.
|
||||
* Parses the origin (caller) from Dubbo invocation.
|
||||
*
|
||||
* @param invoker Dubbo invoker
|
||||
* @param invocation Dubbo invocation
|
||||
* @return parse result
|
||||
* @return the parsed origin
|
||||
*/
|
||||
String parse(Invoker<?> invoker, Invocation invocation);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2020 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
|
||||
*
|
||||
* https://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.origin;
|
||||
|
||||
/**
|
||||
* Global origin parser registry for Dubbo.
|
||||
*
|
||||
* @author tiecheng
|
||||
*/
|
||||
public final class DubboOriginParserRegistry {
|
||||
|
||||
private static volatile DubboOriginParser dubboOriginParser = new DefaultDubboOriginParser();
|
||||
|
||||
public static DubboOriginParser getDubboOriginParser() {
|
||||
return dubboOriginParser;
|
||||
}
|
||||
|
||||
public static void setDubboOriginParser(DubboOriginParser dubboOriginParser) {
|
||||
DubboOriginParserRegistry.dubboOriginParser = dubboOriginParser;
|
||||
}
|
||||
|
||||
private DubboOriginParserRegistry() {}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.alibaba.csp.sentinel.adapter.dubbo;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService;
|
||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
|
|
@ -26,15 +25,15 @@ public class AbstractDubboFilterTest {
|
|||
@Before
|
||||
public void setUp() {
|
||||
SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "true");
|
||||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, "");
|
||||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, "");
|
||||
SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_PROVIDER_RES_NAME_PREFIX_KEY, "");
|
||||
SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_CONSUMER_RES_NAME_PREFIX_KEY, "");
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "false");
|
||||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, "");
|
||||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, "");
|
||||
SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_PROVIDER_RES_NAME_PREFIX_KEY, "");
|
||||
SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_CONSUMER_RES_NAME_PREFIX_KEY, "");
|
||||
}
|
||||
|
||||
private AbstractDubboFilter filter = new AbstractDubboFilter() {
|
||||
|
|
@ -55,7 +54,7 @@ public class AbstractDubboFilterTest {
|
|||
when(invocation.getMethodName()).thenReturn(method.getName());
|
||||
when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
|
||||
|
||||
String resourceName = filter.getResourceName(invoker, invocation);
|
||||
String resourceName = filter.getMethodResourceName(invoker, invocation);
|
||||
|
||||
assertEquals("com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
|
||||
}
|
||||
|
|
@ -71,19 +70,19 @@ public class AbstractDubboFilterTest {
|
|||
when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
|
||||
|
||||
//test with default prefix
|
||||
String resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix());
|
||||
String resourceName = filter.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboProviderPrefix());
|
||||
System.out.println("resourceName = " + resourceName);
|
||||
assertEquals("dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
|
||||
resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix());
|
||||
resourceName = filter.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboConsumerPrefix());
|
||||
assertEquals("dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
|
||||
|
||||
|
||||
//test with custom prefix
|
||||
SentinelConfig.setConfig(DubboConfig.DUBBO_PROVIDER_PREFIX, "my:dubbo:provider:");
|
||||
SentinelConfig.setConfig(DubboConfig.DUBBO_CONSUMER_PREFIX, "my:dubbo:consumer:");
|
||||
resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix());
|
||||
SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_PROVIDER_RES_NAME_PREFIX_KEY, "my:dubbo:provider:");
|
||||
SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_CONSUMER_RES_NAME_PREFIX_KEY, "my:dubbo:consumer:");
|
||||
resourceName = filter.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboProviderPrefix());
|
||||
assertEquals("my:dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
|
||||
resourceName = filter.getResourceName(invoker, invocation, DubboConfig.getDubboConsumerPrefix());
|
||||
resourceName = filter.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboConsumerPrefix());
|
||||
assertEquals("my:dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public class SentinelDubboConsumerFilterTest extends BaseTest {
|
|||
// As not call ContextUtil.enter(resourceName, application) in SentinelDubboConsumerFilter, use default context
|
||||
// In actual project, a consumer is usually also a provider, the context will be created by SentinelDubboProviderFilter
|
||||
// If consumer is on the top of Dubbo RPC invocation chain, use default context
|
||||
String resourceName = filter.getResourceName(invoker, invocation);
|
||||
String resourceName = filter.getMethodResourceName(invoker, invocation);
|
||||
assertEquals(Constants.CONTEXT_DEFAULT_NAME, context.getName());
|
||||
assertEquals("", context.getOrigin());
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public class SentinelDubboProviderFilterTest extends BaseTest {
|
|||
assertNotNull(context);
|
||||
|
||||
// As ContextUtil.enter(resourceName, application) in SentinelDubboProviderFilter
|
||||
String resourceName = filter.getResourceName(invoker, invocation);
|
||||
String resourceName = filter.getMethodResourceName(invoker, invocation);
|
||||
assertEquals(resourceName, context.getName());
|
||||
assertEquals(originApplication, context.getOrigin());
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.adapter.dubbo.fallback;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.DubboAdapterGlobalConfig;
|
||||
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;
|
||||
|
|
@ -31,24 +32,25 @@ import org.junit.Test;
|
|||
*/
|
||||
public class DubboFallbackRegistryTest {
|
||||
|
||||
@Test(expected = SentinelRpcException.class)
|
||||
@Test
|
||||
public void testDefaultFallback() {
|
||||
// Test for default.
|
||||
// Test for default fallback.
|
||||
BlockException ex = new FlowException("xxx");
|
||||
DubboFallbackRegistry.getConsumerFallback()
|
||||
.handle(null, null, ex);
|
||||
Result result = new DefaultDubboFallback().handle(null, null, ex);
|
||||
Assert.assertTrue(result.hasException());
|
||||
Assert.assertEquals(SentinelRpcException.class, result.getException().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomFallback() {
|
||||
BlockException ex = new FlowException("xxx");
|
||||
DubboFallbackRegistry.setConsumerFallback(new DubboFallback() {
|
||||
DubboAdapterGlobalConfig.setConsumerFallback(new DubboFallback() {
|
||||
@Override
|
||||
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException e) {
|
||||
return new RpcResult("Error: " + e.getClass().getName());
|
||||
}
|
||||
});
|
||||
Result result = DubboFallbackRegistry.getConsumerFallback()
|
||||
Result result = DubboAdapterGlobalConfig.getConsumerFallback()
|
||||
.handle(null, null, ex);
|
||||
Assert.assertFalse("The invocation should not fail", result.hasException());
|
||||
Assert.assertEquals("Error: " + ex.getClass().getName(), result.getValue());
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@
|
|||
*/
|
||||
package com.alibaba.csp.sentinel.adapter.dubbo.origin;
|
||||
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.DubboAdapterGlobalConfig;
|
||||
import com.alibaba.csp.sentinel.adapter.dubbo.DubboUtils;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.RpcInvocation;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
|
@ -30,12 +32,12 @@ public class DubboOriginRegistryTest {
|
|||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
DubboOriginParserRegistry.setDubboOriginParser(new DefaultDubboOriginParser());
|
||||
DubboAdapterGlobalConfig.setOriginParser(new DefaultDubboOriginParser());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testDefaultOriginParserFail() {
|
||||
DubboOriginParserRegistry.getDubboOriginParser().parse(null, null);
|
||||
DubboAdapterGlobalConfig.getOriginParser().parse(null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -43,13 +45,13 @@ public class DubboOriginRegistryTest {
|
|||
RpcInvocation invocation = new RpcInvocation();
|
||||
String dubboName = "sentinel";
|
||||
invocation.setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, dubboName);
|
||||
String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation);
|
||||
String origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
|
||||
Assert.assertEquals(dubboName, origin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomOriginParser() {
|
||||
DubboOriginParserRegistry.setDubboOriginParser(new DubboOriginParser() {
|
||||
DubboAdapterGlobalConfig.setOriginParser(new DubboOriginParser() {
|
||||
@Override
|
||||
public String parse(Invoker<?> invoker, Invocation invocation) {
|
||||
return invocation.getAttachment(DubboUtils.DUBBO_APPLICATION_KEY, "default") + "_" + invocation
|
||||
|
|
@ -58,16 +60,16 @@ public class DubboOriginRegistryTest {
|
|||
});
|
||||
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation);
|
||||
String origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
|
||||
Assert.assertEquals("default_null", origin);
|
||||
|
||||
String dubboName = "sentinel";
|
||||
invocation.setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, dubboName);
|
||||
origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation);
|
||||
origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
|
||||
Assert.assertEquals(dubboName + "_null", origin);
|
||||
|
||||
invocation.setMethodName("hello");
|
||||
origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation);
|
||||
origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
|
||||
Assert.assertEquals(dubboName + "_hello", origin);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,16 +19,14 @@ 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.adapter.dubbo.DubboAdapterGlobalConfig;
|
||||
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;
|
||||
import com.alibaba.csp.sentinel.init.InitExecutor;
|
||||
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;
|
||||
|
|
@ -88,7 +86,7 @@ public class FooConsumerBootstrap {
|
|||
// 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) ->
|
||||
DubboAdapterGlobalConfig.setConsumerFallback((a, b, ex) ->
|
||||
new RpcResult("Error: " + ex.getClass().getTypeName()));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue