@@ -65,4 +65,10 @@ flow control, degrade or system load protection. You can implement your own `Dub | |||
and then register to `DubboFallbackRegistry`. If no fallback is configured, Sentinel will wrap the `BlockException` | |||
then directly throw it out. | |||
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. | |||
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. |
@@ -22,6 +22,7 @@ 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; | |||
@@ -55,14 +56,17 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements | |||
@Override | |||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { | |||
// Get origin caller. | |||
String application = DubboUtils.getApplication(invocation, ""); | |||
String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(invoker, invocation); | |||
if (null == origin) { | |||
origin = ""; | |||
} | |||
Entry interfaceEntry = null; | |||
Entry methodEntry = null; | |||
try { | |||
String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | |||
String interfaceName = invoker.getInterface().getName(); | |||
ContextUtil.enter(resourceName, application); | |||
ContextUtil.enter(resourceName, origin); | |||
interfaceEntry = SphU.entry(interfaceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN); | |||
methodEntry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_RPC, | |||
EntryType.IN, invocation.getArguments()); | |||
@@ -0,0 +1,34 @@ | |||
/* | |||
* 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; | |||
import com.alibaba.csp.sentinel.adapter.dubbo.DubboUtils; | |||
import com.alibaba.dubbo.rpc.Invocation; | |||
import com.alibaba.dubbo.rpc.Invoker; | |||
/** | |||
* Default Dubbo origin parse. | |||
* | |||
* @author tiecheng | |||
*/ | |||
public class DefaultDubboOriginParser implements DubboOriginParser { | |||
@Override | |||
public String parse(Invoker<?> invoker, Invocation invocation) { | |||
return DubboUtils.getApplication(invocation, ""); | |||
} | |||
} |
@@ -0,0 +1,38 @@ | |||
/* | |||
* 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; | |||
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()} | |||
* | |||
* @author tiecheng | |||
*/ | |||
public interface DubboOriginParser { | |||
/** | |||
* Handle the origin parse. | |||
* | |||
* @param invoker Dubbo invoker | |||
* @param invocation Dubbo invocation | |||
* @return parse result | |||
*/ | |||
String parse(Invoker<?> invoker, Invocation invocation); | |||
} |
@@ -0,0 +1,37 @@ | |||
/* | |||
* 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() {} | |||
} |
@@ -0,0 +1,74 @@ | |||
/* | |||
* 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; | |||
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; | |||
/** | |||
* @author tiecheng | |||
*/ | |||
public class DubboOriginRegistryTest { | |||
@After | |||
public void cleanUp() { | |||
DubboOriginParserRegistry.setDubboOriginParser(new DefaultDubboOriginParser()); | |||
} | |||
@Test(expected = IllegalArgumentException.class) | |||
public void testDefaultOriginParserFail() { | |||
DubboOriginParserRegistry.getDubboOriginParser().parse(null, null); | |||
} | |||
@Test | |||
public void testDefaultOriginParserSuccess() { | |||
RpcInvocation invocation = new RpcInvocation(); | |||
String dubboName = "sentinel"; | |||
invocation.setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, dubboName); | |||
String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); | |||
Assert.assertEquals(dubboName, origin); | |||
} | |||
@Test | |||
public void testCustomOriginParser() { | |||
DubboOriginParserRegistry.setDubboOriginParser(new DubboOriginParser() { | |||
@Override | |||
public String parse(Invoker<?> invoker, Invocation invocation) { | |||
return invocation.getAttachment(DubboUtils.DUBBO_APPLICATION_KEY, "default") + "_" + invocation | |||
.getMethodName(); | |||
} | |||
}); | |||
RpcInvocation invocation = new RpcInvocation(); | |||
String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); | |||
Assert.assertEquals("default_null", origin); | |||
String dubboName = "sentinel"; | |||
invocation.setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, dubboName); | |||
origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); | |||
Assert.assertEquals(dubboName + "_null", origin); | |||
invocation.setMethodName("hello"); | |||
origin = DubboOriginParserRegistry.getDubboOriginParser().parse(null, invocation); | |||
Assert.assertEquals(dubboName + "_hello", origin); | |||
} | |||
} |