This is an automated email from the ASF dual-hosted git repository. huxing pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/dubbo-sentinel-support.git
commit 3b87a01c4e1357f32d69c0daae2fd1de2ffe067c Author: Eric Zhao <sczy...@gmail.com> AuthorDate: Fri Jul 27 14:32:27 2018 +0800 Initial commit for Sentinel Dubbo Adapter Signed-off-by: Eric Zhao <sczy...@gmail.com> --- .gitignore | 43 +++++++------ README.md | 54 +++++++++++++++- pom.xml | 40 ++++++++++++ .../adapter/dubbo/AbstractDubboFilter.java | 29 +++++++++ .../adapter/dubbo/DubboAppContextFilter.java | 28 ++++++++ .../csp/sentinel/adapter/dubbo/DubboUtils.java | 20 ++++++ .../adapter/dubbo/SentinelDubboConsumerFilter.java | 55 ++++++++++++++++ .../adapter/dubbo/SentinelDubboProviderFilter.java | 60 ++++++++++++++++++ .../META-INF/dubbo/com.alibaba.dubbo.rpc.Filter | 3 + .../csp/sentinel/adapter/dubbo/DemoService.java | 8 +++ .../sentinel/adapter/dubbo/DubboConsumerTest.java | 74 ++++++++++++++++++++++ .../sentinel/adapter/dubbo/DubboProviderTest.java | 32 ++++++++++ .../adapter/dubbo/provider/DemoServiceImpl.java | 12 ++++ .../resources/spring-dubbo-consumer-filter.xml | 20 ++++++ .../resources/spring-dubbo-provider-filter.xml | 20 ++++++ 15 files changed, 477 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index a1c2a23..378800f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,26 @@ -# Compiled class file -*.class +# IntelliJ project files +.idea/ +*.iml +out +gen -# Log file -*.log +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +!/.mvn/wrapper/maven-wrapper.jar -# BlueJ files -*.ctxt +# Eclipse +.classpath +.settings/ +.project -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +# System related +*.DS_Store +Thumbs.db diff --git a/README.md b/README.md index 9b0be3d..d112457 100644 --- a/README.md +++ b/README.md @@ -1 +1,53 @@ -# dubbo-sentinel-support \ No newline at end of file +# Sentinel Dubbo Adapter + +Sentinel Dubbo Adapter provides service consumer filter and provider filter +for [Dubbo](http://dubbo.io/) services. + +To use Sentinel Dubbo Adapter, you can simply add the following dependency to your `pom.xml`: + +```xml +<dependency> + <groupId>com.alibaba.csp</groupId> + <artifactId>sentinel-dubbo-adapter</artifactId> + <version>x.y.z</version> +</dependency> +``` + +The Sentinel filters are **enabled by default**. Once you add the dependency, +the Dubbo services and methods will become protected resources in Sentinel, +which can leverage Sentinel's flow control and guard ability when rules are configured. +Demos can be found in [sentinel-demo-dubbo](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo/sentinel-demo-dubbo). + +If you don't want the filters enabled, you can manually disable them. For example: + +```xml +<dubbo:consumer filter="-sentinel.dubbo.consumer.filter"/> + +<dubbo:provider filter="-sentinel.dubbo.provider.filter"/> +``` + +For more details of Dubbo filter, see [here](https://dubbo.incubator.apache.org/#/docs/dev/impls/filter.md?lang=en-us). + +## Dubbo resources + +The resource for Dubbo services has two granularities: service interface and service method. + +- Service interface:resourceName format is `interfaceName`,e.g. `com.alibaba.csp.sentinel.demo.dubbo.FooService` +- Service method:resourceName format is `interfaceName:methodSignature`,e.g. `com.alibaba.csp.sentinel.demo.dubbo.FooService:sayHello(java.lang.String)` + +## Flow control based on caller + +In many circumstances, it's also significant to control traffic flow based on the **caller**. +For example, assuming that there are two services A and B, both of them initiate remote call requests to the service provider. +If we want to limit the calls from service B only, we can set the `limitApp` of flow rule as the identifier of service B (e.g. service name). + +Sentinel Dubbo Adapter will automatically resolve the Dubbo consumer's *application name* as the caller's name (`origin`), +and will bring the caller's name when doing resource protection. +If `limitApp` of flow rules is not configured (`default`), flow control will take effects on all callers. +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`. diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..a7ed335 --- /dev/null +++ b/pom.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.alibaba.csp</groupId> + <artifactId>sentinel-adapter</artifactId> + <version>0.1.0</version> + </parent> + <artifactId>sentinel-dubbo-adapter</artifactId> + <packaging>jar</packaging> + + <dependencies> + <dependency> + <groupId>com.alibaba.csp</groupId> + <artifactId>sentinel-core</artifactId> + </dependency> + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>dubbo</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>fastjson</artifactId> + <version>1.2.47</version> + <scope>test</scope> + </dependency> + </dependencies> + + +</project> \ No newline at end of file diff --git a/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/AbstractDubboFilter.java b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/AbstractDubboFilter.java new file mode 100755 index 0000000..2400b3c --- /dev/null +++ b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/AbstractDubboFilter.java @@ -0,0 +1,29 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +import com.alibaba.dubbo.rpc.Filter; +import com.alibaba.dubbo.rpc.Invocation; +import com.alibaba.dubbo.rpc.Invoker; + +/** + * @author leyou + */ +abstract class AbstractDubboFilter implements Filter { + + protected String getResourceName(Invoker<?> invoker, Invocation invocation) { + StringBuilder buf = new StringBuilder(64); + buf.append(invoker.getInterface().getName()) + .append(":") + .append(invocation.getMethodName()) + .append("("); + boolean isFirst = true; + for (Class<?> clazz : invocation.getParameterTypes()) { + if (!isFirst) { + buf.append(","); + } + buf.append(clazz.getName()); + isFirst = false; + } + buf.append(")"); + return buf.toString(); + } +} diff --git a/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilter.java b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilter.java new file mode 100644 index 0000000..36835cc --- /dev/null +++ b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboAppContextFilter.java @@ -0,0 +1,28 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.extension.Activate; +import com.alibaba.dubbo.rpc.Filter; +import com.alibaba.dubbo.rpc.Invocation; +import com.alibaba.dubbo.rpc.Invoker; +import com.alibaba.dubbo.rpc.Result; +import com.alibaba.dubbo.rpc.RpcContext; +import com.alibaba.dubbo.rpc.RpcException; + +/** + * Puts current consumer's application name in the attachment of each invocation. + * + * @author Eric Zhao + */ +@Activate(group = "consumer") +public class DubboAppContextFilter implements Filter { + + @Override + public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { + String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY); + if (application != null) { + RpcContext.getContext().setAttachment(DubboUtils.DUBBO_APPLICATION_KEY, application); + } + return invoker.invoke(invocation); + } +} diff --git a/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java new file mode 100644 index 0000000..73fd51b --- /dev/null +++ b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboUtils.java @@ -0,0 +1,20 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +import com.alibaba.dubbo.rpc.Invocation; + +/** + * @author Eric Zhao + */ +public final class DubboUtils { + + public static final String DUBBO_APPLICATION_KEY = "dubboApplication"; + + public static String getApplication(Invocation invocation, String defaultValue) { + if (invocation == null || invocation.getAttachments() == null) { + throw new IllegalArgumentException("Bad invocation instance"); + } + return invocation.getAttachment(DUBBO_APPLICATION_KEY, defaultValue); + } + + private DubboUtils() {} +} diff --git a/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java new file mode 100755 index 0000000..2f79b04 --- /dev/null +++ b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboConsumerFilter.java @@ -0,0 +1,55 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +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.context.ContextUtil; +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; +import com.alibaba.dubbo.rpc.Invoker; +import com.alibaba.dubbo.rpc.Result; +import com.alibaba.dubbo.rpc.RpcException; + +/** + * <p>Dubbo service consumer filter for Sentinel. Auto activated by default.</p> + * + * If you want to disable the consumer filter, you can configure: + * <pre> + * <dubbo:consumer filter="-sentinel.dubbo.consumer.filter"/> + * </pre> + * + * @author leyou + */ +@Activate(group = "consumer") +public class SentinelDubboConsumerFilter extends AbstractDubboFilter implements Filter { + + @Override + public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { + Entry interfaceEntry = null; + Entry methodEntry = null; + try { + String resourceName = getResourceName(invoker, invocation); + ContextUtil.enter(resourceName); + interfaceEntry = SphU.entry(invoker.getInterface().getName(), EntryType.OUT); + methodEntry = SphU.entry(resourceName, EntryType.OUT); + return invoker.invoke(invocation); + } catch (BlockException e) { + throw new SentinelRpcException(e); + } catch (RpcException e) { + Tracer.trace(e); + throw e; + } finally { + if (methodEntry != null) { + methodEntry.exit(); + } + if (interfaceEntry != null) { + interfaceEntry.exit(); + } + ContextUtil.exit(); + } + } +} diff --git a/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java new file mode 100755 index 0000000..8c3951f --- /dev/null +++ b/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo/SentinelDubboProviderFilter.java @@ -0,0 +1,60 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +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.context.ContextUtil; +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; +import com.alibaba.dubbo.rpc.Invoker; +import com.alibaba.dubbo.rpc.Result; +import com.alibaba.dubbo.rpc.RpcException; + +/** + * <p>Dubbo service provider filter for Sentinel. Auto activated by default.</p> + * + * If you want to disable the provider filter, you can configure: + * <pre> + * <dubbo:provider filter="-sentinel.dubbo.provider.filter"/> + * </pre> + * + * @author leyou + */ +@Activate(group = "provider") +public class SentinelDubboProviderFilter extends AbstractDubboFilter implements Filter { + + @Override + public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { + // Get origin caller. + String application = DubboUtils.getApplication(invocation, ""); + + Entry interfaceEntry = null; + Entry methodEntry = null; + try { + String resourceName = getResourceName(invoker, invocation); + String interfaceName = invoker.getInterface().getName(); + ContextUtil.enter(resourceName, application); + interfaceEntry = SphU.entry(interfaceName, EntryType.IN); + methodEntry = SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments()); + + return invoker.invoke(invocation); + } catch (BlockException e) { + throw new SentinelRpcException(e); + } catch (RpcException e) { + Tracer.trace(e); + throw e; + } finally { + if (methodEntry != null) { + methodEntry.exit(1, invocation.getArguments()); + } + if (interfaceEntry != null) { + interfaceEntry.exit(); + } + ContextUtil.exit(); + } + } +} diff --git a/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter b/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter new file mode 100755 index 0000000..af7c961 --- /dev/null +++ b/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter @@ -0,0 +1,3 @@ +sentinel.dubbo.provider.filter=com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboProviderFilter +sentinel.dubbo.consumer.filter=com.alibaba.csp.sentinel.adapter.dubbo.SentinelDubboConsumerFilter +dubbo.application.context.name.filter=com.alibaba.csp.sentinel.adapter.dubbo.DubboAppContextFilter \ No newline at end of file diff --git a/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DemoService.java b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DemoService.java new file mode 100755 index 0000000..8ccc4a0 --- /dev/null +++ b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DemoService.java @@ -0,0 +1,8 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +/** + * @author leyou + */ +public interface DemoService { + String sayHello(String name, int n); +} diff --git a/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboConsumerTest.java b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboConsumerTest.java new file mode 100755 index 0000000..4ba0a4d --- /dev/null +++ b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboConsumerTest.java @@ -0,0 +1,74 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +import java.util.Arrays; + +import com.alibaba.csp.sentinel.node.ClusterNode; +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.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * 运行该用例的时候需要加入JVM参数:-Djava.net.preferIPv4Stack=true, + * 否则可能会抛出{@code java.lang.IllegalStateException: Can't assign requested address} + * + * @author leyou + */ +public class DubboConsumerTest { + private final String resource = "com.alibaba.csp.sentinel.adapter.dubbo.DemoService:sayHello(java.lang.String,int)"; + private final String interfaceResource = "com.alibaba.csp.sentinel.adapter.dubbo.DemoService"; + private ClassPathXmlApplicationContext context; + + @Before + public void init() { + context = new ClassPathXmlApplicationContext( + new String[] {"spring-dubbo-consumer-filter.xml"}); + context.start(); + } + + @Test + public void testConsumerFilter() throws Exception { + DemoService demoService = (DemoService)context.getBean("demoService"); + String result = demoService.sayHello("Test dubbo consumer filter", 2); + System.out.println("result=" + result); + ClusterNode node = ClusterBuilderSlot.getClusterNode(resource); + Assert.assertNotNull(node); + } + + @Test(expected = SentinelRpcException.class) + public void testConsumerBlock() throws Exception { + FlowRule flowRule = new FlowRule(); + flowRule.setResource(resource); + flowRule.setCount(10); + flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); + flowRule.setLimitApp("default"); + FlowRuleManager.loadRules(Arrays.asList(flowRule)); + + DemoService demoService = (DemoService)context.getBean("demoService"); + for (int i = 0; i < 100; i++) { + demoService.sayHello("Test dubbo consumer filter", 2); + } + } + + @Test(expected = SentinelRpcException.class) + public void testConsumerBlock2() throws Exception { + FlowRule flowRule = new FlowRule(); + flowRule.setResource(interfaceResource); + flowRule.setCount(10); + flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS); + flowRule.setLimitApp("default"); + FlowRuleManager.loadRules(Arrays.asList(flowRule)); + + DemoService demoService = (DemoService)context.getBean("demoService"); + for (int i = 0; i < 100; i++) { + demoService.sayHello("Test dubbo consumer filter", 2); + } + } + +} diff --git a/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboProviderTest.java b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboProviderTest.java new file mode 100755 index 0000000..8c4657e --- /dev/null +++ b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/DubboProviderTest.java @@ -0,0 +1,32 @@ +package com.alibaba.csp.sentinel.adapter.dubbo; + +import com.alibaba.csp.sentinel.node.ClusterNode; +import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot; + +import org.junit.Assert; +import org.junit.Test; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * 运行该用例的时候需要加入JVM参数:-Djava.net.preferIPv4Stack=true, + * 否则可能会抛出{@code java.lang.IllegalStateException: Can't assign requested address} + * + * @author leyou + */ +public class DubboProviderTest { + + private final String resource = "com.alibaba.csp.sentinel.adapter.dubbo.DemoService:sayHello(java.lang.String,int)"; + + @Test + public void testProviderFilter() throws Exception { + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( + new String[] {"spring-dubbo-provider-filter.xml"}); + context.start(); + DemoService demoService = (DemoService)context.getBean("demoService"); + String result = demoService.sayHello("Test dubbo provider filter", 1); + System.out.println("result=" + result); + ClusterNode node = ClusterBuilderSlot.getClusterNode(resource); + Thread.sleep(1000 * 60 * 100); + Assert.assertNotNull(node); + } +} diff --git a/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoServiceImpl.java b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoServiceImpl.java new file mode 100755 index 0000000..db566e7 --- /dev/null +++ b/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo/provider/DemoServiceImpl.java @@ -0,0 +1,12 @@ +package com.alibaba.csp.sentinel.adapter.dubbo.provider; + +import com.alibaba.csp.sentinel.adapter.dubbo.DemoService; + +/** + * @author leyou + */ +public class DemoServiceImpl implements DemoService { + public String sayHello(String name, int n) { + return "Hello " + name + ", " + n; + } +} diff --git a/src/test/resources/spring-dubbo-consumer-filter.xml b/src/test/resources/spring-dubbo-consumer-filter.xml new file mode 100755 index 0000000..ae0a89d --- /dev/null +++ b/src/test/resources/spring-dubbo-consumer-filter.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://code.alibabatech.com/schema/dubbo + http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> + + <dubbo:application name="demo-consumer"/> + <dubbo:registry address="multicast://224.5.6.7:1234"/> + <dubbo:protocol name="dubbo" port="20880"/> + <dubbo:service interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService" ref="demoServiceImp" /> + <bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoServiceImpl"/> + + <dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService"/> + + <dubbo:consumer filter="sentinel.dubbo.consumer.filter" /> + +</beans> \ No newline at end of file diff --git a/src/test/resources/spring-dubbo-provider-filter.xml b/src/test/resources/spring-dubbo-provider-filter.xml new file mode 100755 index 0000000..0990c39 --- /dev/null +++ b/src/test/resources/spring-dubbo-provider-filter.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://code.alibabatech.com/schema/dubbo + http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> + + <dubbo:application name="demo-provider"/> + <dubbo:registry address="multicast://224.5.6.7:1234"/> + <dubbo:protocol name="dubbo" port="20880"/> + <dubbo:service interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService" ref="demoServiceImp" /> + <bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo.provider.DemoServiceImpl"/> + + <dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo.DemoService"/> + + <dubbo:provider filter="sentinel.dubbo.provider.filter" /> + +</beans> \ No newline at end of file