@@ -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` | and then register to `DubboFallbackRegistry`. If no fallback is configured, Sentinel will wrap the `BlockException` | ||||
then directly throw it out. | 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.Tracer; | ||||
import com.alibaba.csp.sentinel.adapter.dubbo.config.DubboConfig; | 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.fallback.DubboFallbackRegistry; | ||||
import com.alibaba.csp.sentinel.adapter.dubbo.origin.DubboOriginParserRegistry; | |||||
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; | ||||
@@ -55,14 +56,17 @@ public class SentinelDubboProviderFilter extends AbstractDubboFilter implements | |||||
@Override | @Override | ||||
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { | public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { | ||||
// Get origin caller. | // Get origin caller. | ||||
String application = DubboUtils.getApplication(invocation, ""); | |||||
String origin = DubboOriginParserRegistry.getDubboOriginParser().parse(invoker, invocation); | |||||
if (null == origin) { | |||||
origin = ""; | |||||
} | |||||
Entry interfaceEntry = null; | Entry interfaceEntry = null; | ||||
Entry methodEntry = null; | Entry methodEntry = null; | ||||
try { | try { | ||||
String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | String resourceName = getResourceName(invoker, invocation, DubboConfig.getDubboProviderPrefix()); | ||||
String interfaceName = invoker.getInterface().getName(); | String interfaceName = invoker.getInterface().getName(); | ||||
ContextUtil.enter(resourceName, application); | |||||
ContextUtil.enter(resourceName, origin); | |||||
interfaceEntry = SphU.entry(interfaceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN); | interfaceEntry = SphU.entry(interfaceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN); | ||||
methodEntry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_RPC, | methodEntry = SphU.entry(resourceName, ResourceTypeConstants.COMMON_RPC, | ||||
EntryType.IN, invocation.getArguments()); | 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); | |||||
} | |||||
} |