Repository: alibaba/Sentinel
Pull request #2232 (2021-06-10 00:44:27)

solved #66, support default degrade rule.
纯基于扩展支持默认规则的实现思路, 适用已发布版本.

CLAassistant: [![CLA assistant check](https://cla-assistant.io/pull/badge/not_signed)](https://cla-assistant.io/alibaba/Sentinel?pullRequest=2232) <br/>Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our [Contributor License Agreement](https://cla-assistant.io/alibaba/Sentinel?pullRequest=2232) before we can accept your contribution.<br/><sub>You have signed the CLA already but the status is still pending? Let us [recheck](https://cla-assistant.io/check/alibaba/Sentinel?pullRequest=2232) it.</sub>

Patch:
diff --git a/README.md b/README.md
index 269f1dc2..8e5fdf5a 100755
--- a/README.md
+++ b/README.md
@@ -11,32 +11,36 @@
 ## Introduction
 
 As distributed systems become increasingly popular, the reliability between services is becoming more important than ever before.
-Sentinel takes "flow" as breakthrough point, and works on multiple fields including **flow control**,
-**traffic shaping**, **circuit breaking** and **system adaptive protection**, to guarantee reliability and resilience for microservices.
+Sentinel takes "flow" as breakthrough point, and works on multiple fields including **flow control**, **traffic shaping**,
+**concurrency limiting**, **circuit breaking** and **system adaptive overload protection**,
+to guarantee reliability and resilience for microservices.
 
 Sentinel has the following features:
 
 - **Rich applicable scenarios**: Sentinel has been wildly used in Alibaba, and has covered almost all the core-scenarios in Double-11 (11.11) Shopping Festivals in the past 10 years, such as “Second Kill” which needs to limit burst flow traffic to meet the system capacity, message peak clipping and valley fills, circuit breaking for unreliable downstream services, cluster flow control, etc.
 - **Real-time monitoring**: Sentinel also provides real-time monitoring ability. You can see the runtime information of a single machine in real-time, and the aggregated runtime info of a cluster with less than 500 nodes.
-- **Widespread open-source ecosystem**: Sentinel provides out-of-box integrations with commonly-used frameworks and libraries such as Spring Cloud, Dubbo and gRPC. You can easily use Sentinel by simply add the adapter dependency to your services.
-- **Polyglot support**: Sentinel has provided native support for Java, [Go](https://github.com/alibaba/sentinel-golang) and [C++](https://github.com/alibaba/sentinel-cpp).
+- **Widespread open-source ecosystem**: Sentinel provides out-of-box integrations with commonly-used frameworks and libraries such as Spring Cloud, gRPC, Apache Dubbo and Quarkus. You can easily use Sentinel by simply add the adapter dependency to your services.
+- **Polyglot support**: Sentinel has provided native support for Java, [Go](https://github.com/alibaba/sentinel-golang), [C++](https://github.com/alibaba/sentinel-cpp) and [Rust](https://github.com/sentinel-group/sentinel-rust).
 - **Various SPI extensions**: Sentinel provides easy-to-use SPI extension interfaces that allow you to quickly customize your logic, for example, custom rule management, adapting data sources, and so on.
 
 Features overview:
 
 ![features-of-sentinel](./doc/image/sentinel-features-overview-en.png)
 
+The community is also working on **the specification of traffic governance and fault-tolerance**.
+Please refer to [OpenSergo](https://opensergo.io/) for details.
+
 ## Documentation
 
-See the [Sentinel](https://sentinelguard.io/) for the document website.
+See the [Sentinel Website](https://sentinelguard.io/) for the official website of Sentinel.
 
-See the [中文文档](https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D) for document in Chinese.
+See the [中文文档](https://sentinelguard.io/zh-cn/docs/introduction.html) for document in Chinese.
 
 See the [Wiki](https://github.com/alibaba/Sentinel/wiki) for full documentation, examples, blog posts, operational details and other information.
 
 Sentinel provides integration modules for various open-source frameworks
-(e.g. Spring Cloud, Apache Dubbo, gRPC, Spring WebFlux, Reactor) and service mesh.
-You can refer to [the document](https://github.com/alibaba/Sentinel/wiki/Adapters-to-Popular-Framework) for more information.
+(e.g. Spring Cloud, Apache Dubbo, gRPC, Quarkus, Spring WebFlux, Reactor) and service mesh.
+You can refer to [the document](https://sentinelguard.io/en-us/docs/open-source-framework-integrations.html) for more information.
 
 If you are using Sentinel, please [**leave a comment here**](https://github.com/alibaba/Sentinel/issues/18) to tell us your scenario to make Sentinel better.
 It's also encouraged to add the link of your blog post, tutorial, demo or customized components to [**Awesome Sentinel**](./doc/awesome-sentinel.md).
@@ -60,7 +64,7 @@ If you're using Maven, just add the following dependency in `pom.xml`.
 <dependency>
     <groupId>com.alibaba.csp</groupId>
     <artifactId>sentinel-core</artifactId>
-    <version>1.8.4</version>
+    <version>1.8.6</version>
 </dependency>
 ```
 
@@ -100,7 +104,7 @@ rules.add(rule);
 FlowRuleManager.loadRules(rules);
 ```
 
-For more information, please refer to [How To Use](https://github.com/alibaba/Sentinel/wiki/How-to-Use).
+For more information, please refer to [How To Use](https://sentinelguard.io/en-us/docs/basic-api-resource-rule.html).
 
 ### 4. Check the Result
 
@@ -120,9 +124,9 @@ p stands for incoming request, block for blocked by rules, s for success handled
 
 This shows that the demo can print "hello world" 20 times per second.
 
-More examples and information can be found in the [How To Use](https://github.com/alibaba/Sentinel/wiki/How-to-Use) section.
+More examples and information can be found in the [How To Use](https://sentinelguard.io/en-us/docs/basic-api-resource-rule.html) section.
 
-The working principles of Sentinel can be found in [How it works](https://github.com/alibaba/Sentinel/wiki/How-it-works) section.
+The working principles of Sentinel can be found in [How it works](https://sentinelguard.io/en-us/docs/basic-implementation.html) section.
 
 Samples can be found in the [sentinel-demo](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo) module.
 
@@ -139,7 +143,7 @@ For details please refer to [Dashboard](https://github.com/alibaba/Sentinel/wiki
 ## Trouble Shooting and Logs
 
 Sentinel will generate logs for troubleshooting and real-time monitoring.
-All the information can be found in [logs](https://github.com/alibaba/Sentinel/wiki/Logs).
+All the information can be found in [logs](https://sentinelguard.io/en-us/docs/logs.html).
 
 ## Bugs and Feedback
 
diff --git a/doc/awesome-sentinel.md b/doc/awesome-sentinel.md
index 68a1db37..adb8fd1b 100644
--- a/doc/awesome-sentinel.md
+++ b/doc/awesome-sentinel.md
@@ -22,14 +22,18 @@ You can also add to [sentinel-group/sentinel-awesome](https://github.com/sentine
 - Sentinel 1.6.0 网关流控新特性介绍-Eric Zhao (Dubbo Tech Day-201905-Beijing): [PDF](https://github.com/sentinel-group/sentinel-awesome/blob/master/slides/Sentinel%201.6.0%20网关流控新特性介绍-Eric%20Zhao-DTED-201905.pdf)
 - Sentinel 微服务流控降级实践-Eric Zhao (Dubbo Tech Day-201907-Shenzhen): [PDF](https://github.com/sentinel-group/sentinel-awesome/blob/master/slides/Sentinel%20微服务流控降级实践-Eric%20Zhao-DTED-201907.pdf)
 - Sentinel 1.7.0 新特性展望-Eric Zhao (Dubbo Tech Day-201910-Chengdu): [PDF](https://github.com/sentinel-group/sentinel-awesome/blob/master/slides/Sentinel%201.7.0%20新特性展望-Eric%20Zhao-DTED-201910.pdf)
+- 《微服务容易挂？Sentinel Go 让微服务稳如磐石》-Eric Zhao (Spring Cloud Alibaba Meetup 1205 杭州站): [PDF](https://github.com/sentinel-group/sentinel-awesome/blob/master/slides/SCA%20Meetup%20Hangzhou-20201205-Sentinel%20Go-Eric%20Zhao.pdf)
+- Sentinel 2.0 流量治理全面升级-Eric Zhao (2022中间件开发者大会): [PDF](https://github.com/mse-group/Slides/blob/main/中间件开发者大会/10%20-%20赵奕豪(宿何)%20-Sentinel%202.0%20流量治理全面升级.pdf)
 
-## Tutorials
+## Tutorials/Samples
 
 - [Sentinel Guides](https://github.com/sentinel-group/sentinel-guides)
 
-## Demos
+## Polyglot Support
 
-- [sentinel-zuul-example](https://github.com/tigerMoon/sentinel-zuul-sample): A simple project integration Sentinel to Spring Cloud Zuul which provides Service and API Path level flow control management by [tiger](https://github.com/tigerMoon)
+- <img src="https://raw.githubusercontent.com/sentinel-group/sentinel-awesome/master/sentinel_favicon.ico" title="Sentinel official" height="16px"> [Sentinel Go](https://github.com/alibaba/sentinel-golang)
+- <img src="https://raw.githubusercontent.com/sentinel-group/sentinel-awesome/master/sentinel_favicon.ico" title="Sentinel official" height="16px"> [Sentinel C++](https://github.com/alibaba/sentinel-cpp)
+- <img src="https://raw.githubusercontent.com/sentinel-group/sentinel-awesome/master/sentinel_favicon.ico" title="Sentinel official" height="16px"> [Sentinel Rust](https://github.com/sentinel-group/sentinel-rust)
 
 ## Extensions / Integrations
 
@@ -72,5 +76,8 @@ You can also add to [sentinel-group/sentinel-awesome](https://github.com/sentine
   - [Sentinel 深入浅出之原理篇 DegradeSlot](https://www.jianshu.com/p/e910d4840e4a)
 - [Alibaba Sentinel RESTful 接口流控处理优化](https://www.jianshu.com/p/96f5980d9798) by [luanlouis](https://github.com/luanlouis)
 - [Sentinel 控制台前端开发环境搭建](https://www.cnblogs.com/cdfive2018/p/11084001.html) by [cdfive](https://github.com/cdfive)
+- [Sentinel 如何接入 OpenTracing](https://juejin.im/post/5de32fe46fb9a071a828feeb) by [Zhang Shun](https://github.com/ZShUn)
 - [阿里 Sentinel 源码解析](https://www.javadoop.com/post/sentinel) by [Javadoop](https://www.javadoop.com)
+- [阿里巴巴开源限流降级神器 Sentinel 大规模生产级应用实践](https://mp.weixin.qq.com/s/AjHCUmygTr78yo9yMxMEyg) by 步崖
 - [Introduction to Alibaba Sentinel](https://www.baeldung.com/java-sentinel-intro) by [Amit Bhave](https://github.com/Amitbhave)
+- [Sentinel Go 毫秒级统计数据结构揭秘](https://sentinelguard.io/zh-cn/blog/sentinel-go-internal-data-structure.html) by [Binbin Zhang](https://github.com/binbin0325)
diff --git a/pom.xml b/pom.xml
index facd89ad..cd36ec72 100755
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
     <groupId>com.alibaba.csp</groupId>
     <artifactId>sentinel-parent</artifactId>
-    <version>1.8.4</version>
+    <version>2.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
     <name>${project.artifactId}</name>
@@ -41,7 +41,7 @@
 
     <properties>
         <!-- Compile libs -->
-        <fastjson.version>1.2.75</fastjson.version>
+        <fastjson.version>1.2.83_noneautotype</fastjson.version>
         <javax.annotation-api.version>1.3.2</javax.annotation-api.version>
 
         <!-- Test libs -->
diff --git a/sentinel-adapter/pom.xml b/sentinel-adapter/pom.xml
index 9daaf897..bb8d2bf7 100755
--- a/sentinel-adapter/pom.xml
+++ b/sentinel-adapter/pom.xml
@@ -7,7 +7,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-adapter</artifactId>
     <packaging>pom</packaging>
@@ -18,6 +18,7 @@
         <module>sentinel-web-servlet</module>
         <module>sentinel-dubbo-adapter</module>
         <module>sentinel-apache-dubbo-adapter</module>
+        <module>sentinel-apache-dubbo3-adapter</module>
         <module>sentinel-apache-httpclient-adapter</module>
         <module>sentinel-sofa-rpc-adapter</module>
         <module>sentinel-grpc-adapter</module>
diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/README.md b/sentinel-adapter/sentinel-apache-dubbo-adapter/README.md
index 9d232bef..1fe2e2df 100755
--- a/sentinel-adapter/sentinel-apache-dubbo-adapter/README.md
+++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/README.md
@@ -1,9 +1,9 @@
 # Sentinel Apache Dubbo Adapter (for 2.7.x+)
 
-> Note: 中文文档请见[此处](https://github.com/alibaba/Sentinel/wiki/主流框架的适配#dubbo)。
+> Note: 中文文档请见[此处](https://sentinelguard.io/zh-cn/docs/open-source-framework-integrations.html)。
 
 Sentinel Dubbo Adapter provides service consumer filter and provider filter
-for [Apache Dubbo](https://dubbo.apache.org/en-us/) services.
+for [Apache Dubbo](https://dubbo.apache.org/en/) services.
 
 **Note: This adapter only supports Apache Dubbo 2.7.x and above.** For legacy `com.alibaba:dubbo` 2.6.x,
 please use `sentinel-dubbo-adapter` module instead.
@@ -51,7 +51,7 @@ 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,
+> Note: Earlier Dubbo 2.7.x 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.
diff --git a/sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml b/sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml
index d0825ac0..3f3ff34a 100644
--- a/sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-apache-dubbo-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/README.md b/sentinel-adapter/sentinel-apache-dubbo3-adapter/README.md
new file mode 100755
index 00000000..94228e5e
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/README.md
@@ -0,0 +1,71 @@
+# Sentinel Apache Dubbo Adapter (for 3.0.5+)
+
+> Note: 中文文档请见[此处](https://sentinelguard.io/zh-cn/docs/open-source-framework-integrations.html)。
+
+Sentinel Dubbo Adapter provides service consumer filter and provider filter
+for [Apache Dubbo](https://dubbo.apache.org/en/) services.
+
+**Note: This adapter only supports Apache Dubbo 3.0.5 and above.**
+For `org.apache:dubbo` 2.7.x, please use `sentinel-apache-dubbo-adapter` module instead.
+For legacy `com.alibaba:dubbo` 2.6.x, please use `sentinel-dubbo-adapter` module instead.
+
+To use Sentinel Dubbo 3.x Adapter, you can simply add the following dependency to your `pom.xml`:
+
+```xml
+<dependency>
+    <groupId>com.alibaba.csp</groupId>
+    <artifactId>sentinel-apache-dubbo3-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 overload protection ability when rules are configured.
+Demos can be found in [sentinel-demo-apache-dubbo](https://github.com/alibaba/Sentinel/tree/master/sentinel-demo/sentinel-demo-apache-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.apache.org/zh/docs3-v2/java-sdk/reference-manual/spi/description/filter/).
+
+## 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)`
+
+> **Note**: Dubbo *group+version+interface* level is also supported in Sentinel Apache Dubbo adapter.
+> You may just add `-Dcsp.sentinel.dubbo.interface.group.version.enabled=true` JVM property,
+> then the resource name of the Dubbo interface and method will be prefixed with group and version info.
+
+## 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: The adapter provides support for customizing origin parsing logic as well.
+> 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 `DubboAdapterGlobalConfig`.
+
+If no fallback is configured, Sentinel will wrap the `BlockException` with a `RuntimeException` as the fallback result.
+
+Besides, we can also leverage [Dubbo mock mechanism](https://dubbo.apache.org/zh/docs3-v2/java-sdk/advanced-features-and-usage/service/service-downgrade/) to provide fallback implementation of degraded Dubbo services.
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/pom.xml b/sentinel-adapter/sentinel-apache-dubbo3-adapter/pom.xml
new file mode 100644
index 00000000..0e69b2d4
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/pom.xml
@@ -0,0 +1,50 @@
+<?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">
+    <parent>
+        <artifactId>sentinel-adapter</artifactId>
+        <groupId>com.alibaba.csp</groupId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sentinel-apache-dubbo3-adapter</artifactId>
+    <packaging>jar</packaging>
+
+    <properties>
+        <java.source.version>1.8</java.source.version>
+        <java.target.version>1.8</java.target.version>
+        <apache.dubbo.version>3.0.9</apache.dubbo.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba.csp</groupId>
+            <artifactId>sentinel-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>${apache.dubbo.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/BaseSentinelDubboFilter.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/BaseSentinelDubboFilter.java
new file mode 100644
index 00000000..76ed1c54
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/BaseSentinelDubboFilter.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.dubbo3;
+
+
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+
+/**
+ * Base class of the {@link SentinelDubboProviderFilter} and {@link SentinelDubboConsumerFilter}.
+ *
+ * @author Zechao Zheng
+ */
+public abstract class BaseSentinelDubboFilter {
+
+
+    /**
+     * Get method name of dubbo rpc
+     *
+     * @param invoker
+     * @param invocation
+     * @return
+     */
+    abstract String getMethodName(Invoker invoker, Invocation invocation, String prefix);
+
+    /**
+     * Get interface name of dubbo rpc
+     *
+     * @param invoker
+     * @return
+     */
+    abstract String getInterfaceName(Invoker invoker, String prefix);
+
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboAppContextFilter.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboAppContextFilter.java
new file mode 100644
index 00000000..b3f92575
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboAppContextFilter.java
@@ -0,0 +1,49 @@
+/*
+ * 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.dubbo3;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
+
+/**
+ * Puts current consumer's application name in the attachment of each invocation.
+ *
+ * @author Eric Zhao
+ */
+@Activate(group = CONSUMER)
+public class DubboAppContextFilter implements ClusterFilter {
+
+    private final String applicationName;
+
+    public DubboAppContextFilter(ApplicationModel applicationModel) {
+        this.applicationName = applicationModel.tryGetApplicationName();
+    }
+
+    @Override
+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+        if (applicationName != null && !applicationName.isEmpty()) {
+            invocation.setAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, applicationName);
+        }
+        return invoker.invoke(invocation);
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboUtils.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboUtils.java
new file mode 100644
index 00000000..b0e57edb
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboUtils.java
@@ -0,0 +1,109 @@
+/*
+ * 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.dubbo3;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.csp.sentinel.util.StringUtil;
+
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcContext;
+
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY;
+
+/**
+ * @author Eric Zhao
+ */
+public final class DubboUtils {
+
+    public static final String SENTINEL_DUBBO_APPLICATION_KEY = "dubboApplication";
+
+    public static String getApplication(Invocation invocation, String defaultValue) {
+        if (invocation == null || invocation.getAttachments() == null) {
+            throw new IllegalArgumentException("Bad invocation instance");
+        }
+        // 1. try to get application from dubbo context
+        String remoteApplication = invocation.getAttachment(REMOTE_APPLICATION_KEY);
+        if (StringUtils.isEmpty(remoteApplication)) {
+            remoteApplication = RpcContext.getServerAttachment().getAttachment(REMOTE_APPLICATION_KEY);
+        }
+        if (StringUtils.isNotEmpty(remoteApplication)) {
+            return remoteApplication;
+        }
+        // 2. fallback to sentinel application
+        return invocation.getAttachment(SENTINEL_DUBBO_APPLICATION_KEY, defaultValue);
+    }
+
+    public static String getMethodResourceName(Invoker<?> invoker, Invocation invocation){
+        return getMethodResourceName(invoker, invocation, false);
+    }
+
+    public static String getMethodResourceName(Invoker<?> invoker, Invocation invocation, Boolean useGroupAndVersion) {
+        StringBuilder buf = new StringBuilder(64);
+        String interfaceResource = useGroupAndVersion ? invoker.getUrl().getColonSeparatedKey() : invoker.getInterface().getName();
+        buf.append(interfaceResource)
+            .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();
+    }
+
+    public static String getMethodResourceName(Invoker<?> invoker, Invocation invocation, String prefix) {
+        if (StringUtil.isNotBlank(prefix)) {
+            return new StringBuilder(64)
+                    .append(prefix)
+                    .append(getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboInterfaceGroupAndVersionEnabled()))
+                    .toString();
+        } else {
+            return getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboInterfaceGroupAndVersionEnabled());
+        }
+    }
+
+
+    public static String getInterfaceName(Invoker invoker) {
+        return getInterfaceName(invoker, false);
+    }
+
+    public static String getInterfaceName(Invoker<?> invoker, Boolean useGroupAndVersion) {
+        StringBuilder buf = new StringBuilder(64);
+        return useGroupAndVersion ? invoker.getUrl().getColonSeparatedKey() : invoker.getInterface().getName();
+    }
+
+    public static String getInterfaceName(Invoker<?> invoker, String prefix) {
+        if (StringUtil.isNotBlank(prefix)) {
+            return new StringBuilder(64)
+                    .append(prefix)
+                    .append(getInterfaceName(invoker, DubboAdapterGlobalConfig.getDubboInterfaceGroupAndVersionEnabled()))
+                    .toString();
+        } else {
+            return getInterfaceName(invoker, DubboAdapterGlobalConfig.getDubboInterfaceGroupAndVersionEnabled());
+        }
+    }
+
+
+    private DubboUtils() {
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboConsumerFilter.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboConsumerFilter.java
new file mode 100644
index 00000000..34306bde
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboConsumerFilter.java
@@ -0,0 +1,154 @@
+/*
+ * 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.dubbo3;
+
+import com.alibaba.csp.sentinel.*;
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.*;
+import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
+import org.apache.dubbo.rpc.support.RpcUtils;
+
+import java.util.LinkedList;
+import java.util.Optional;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
+
+/**
+ * <p>Dubbo service consumer filter for Sentinel. Auto activated by default.</p>
+ * <p>
+ * If you want to disable the consumer filter, you can configure:
+ * <pre>
+ * &lt;dubbo:consumer filter="-sentinel.dubbo.consumer.filter"/&gt;
+ * </pre>
+ *
+ * @author Carpenter Lee
+ * @author Eric Zhao
+ * @author Lin Liang
+ */
+@Activate(group = CONSUMER)
+public class SentinelDubboConsumerFilter extends BaseSentinelDubboFilter implements ClusterFilter {
+
+    public SentinelDubboConsumerFilter() {
+        RecordLog.info("Sentinel Apache Dubbo3 consumer filter initialized");
+    }
+
+    @Override
+    String getMethodName(Invoker invoker, Invocation invocation, String prefix) {
+        return DubboUtils.getMethodResourceName(invoker, invocation, prefix);
+    }
+
+    @Override
+    String getInterfaceName(Invoker invoker, String prefix) {
+        return DubboUtils.getInterfaceName(invoker, prefix);
+    }
+
+    @Override
+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+        InvokeMode invokeMode = RpcUtils.getInvokeMode(invoker.getUrl(), invocation);
+        if (InvokeMode.SYNC == invokeMode) {
+            return syncInvoke(invoker, invocation);
+        } else {
+            return asyncInvoke(invoker, invocation);
+        }
+    }
+
+    private Result syncInvoke(Invoker<?> invoker, Invocation invocation) {
+        Entry interfaceEntry = null;
+        Entry methodEntry = null;
+        String prefix = DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey();
+        String interfaceResourceName = getInterfaceName(invoker, prefix);
+        String methodResourceName = getMethodName(invoker, invocation, prefix);
+        try {
+            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()) {
+                Tracer.traceEntry(result.getException(), interfaceEntry);
+                Tracer.traceEntry(result.getException(), methodEntry);
+            }
+            return result;
+        } catch (BlockException e) {
+            return DubboAdapterGlobalConfig.getConsumerFallback().handle(invoker, invocation, e);
+        } catch (RpcException e) {
+            Tracer.traceEntry(e, interfaceEntry);
+            Tracer.traceEntry(e, methodEntry);
+            throw e;
+        } finally {
+            if (methodEntry != null) {
+                methodEntry.exit(1, invocation.getArguments());
+            }
+            if (interfaceEntry != null) {
+                interfaceEntry.exit();
+            }
+        }
+    }
+
+    private Result asyncInvoke(Invoker<?> invoker, Invocation invocation) {
+        LinkedList<EntryHolder> queue = new LinkedList<>();
+        String prefix = DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey();
+        String interfaceResourceName = getInterfaceName(invoker, prefix);
+        String methodResourceName = getMethodName(invoker, invocation, prefix);
+        try {
+            queue.push(new EntryHolder(
+                SphU.asyncEntry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.OUT), null));
+            queue.push(new EntryHolder(
+                SphU.asyncEntry(methodResourceName, ResourceTypeConstants.COMMON_RPC,
+                    EntryType.OUT, 1, invocation.getArguments()), invocation.getArguments()));
+            Result result = invoker.invoke(invocation);
+            result.whenCompleteWithContext((r, throwable) -> {
+                Throwable error = throwable;
+                if (error == null) {
+                    error = Optional.ofNullable(r).map(Result::getException).orElse(null);
+                }
+                while (!queue.isEmpty()) {
+                    EntryHolder holder = queue.pop();
+                    Tracer.traceEntry(error, holder.entry);
+                    exitEntry(holder);
+                }
+            });
+            return result;
+        } catch (BlockException e) {
+            while (!queue.isEmpty()) {
+                exitEntry(queue.pop());
+            }
+            return DubboAdapterGlobalConfig.getConsumerFallback().handle(invoker, invocation, e);
+        }
+    }
+
+    static class EntryHolder {
+
+        final private Entry entry;
+        final private Object[] params;
+
+        public EntryHolder(Entry entry, Object[] params) {
+            this.entry = entry;
+            this.params = params;
+        }
+    }
+
+    private void exitEntry(EntryHolder holder) {
+        if (holder.params != null) {
+            holder.entry.exit(1, holder.params);
+        } else {
+            holder.entry.exit();
+        }
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboProviderFilter.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboProviderFilter.java
new file mode 100644
index 00000000..6d73afed
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboProviderFilter.java
@@ -0,0 +1,105 @@
+/*
+ * 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.dubbo3;
+
+import com.alibaba.csp.sentinel.*;
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
+
+/**
+ * <p>Apache Dubbo service provider filter that enables integration with Sentinel. Auto activated by default.</p>
+ * <p>Note: this only works for Apache Dubbo 2.7.x or above version.</p>
+ * <p>
+ * If you want to disable the provider filter, you can configure:
+ * <pre>
+ * &lt;dubbo:provider filter="-sentinel.dubbo.provider.filter"/&gt;
+ * </pre>
+ *
+ * @author Carpenter Lee
+ * @author Eric Zhao
+ */
+@Activate(group = PROVIDER)
+public class SentinelDubboProviderFilter extends BaseSentinelDubboFilter implements Filter {
+
+    public SentinelDubboProviderFilter() {
+        RecordLog.info("Sentinel Apache Dubbo3 provider filter initialized");
+    }
+
+    @Override
+    String getMethodName(Invoker invoker, Invocation invocation, String prefix) {
+        return DubboUtils.getMethodResourceName(invoker, invocation, prefix);
+    }
+
+    @Override
+    String getInterfaceName(Invoker invoker, String prefix) {
+        return DubboUtils.getInterfaceName(invoker, prefix);
+    }
+
+    @Override
+    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+        // Get origin caller.
+        String origin = DubboAdapterGlobalConfig.getOriginParser().parse(invoker, invocation);
+        if (null == origin) {
+            origin = "";
+        }
+        Entry interfaceEntry = null;
+        Entry methodEntry = null;
+        String prefix = DubboAdapterGlobalConfig.getDubboProviderResNamePrefixKey();
+        String interfaceResourceName = getInterfaceName(invoker, prefix);
+        String methodResourceName = getMethodName(invoker, invocation, prefix);
+        try {
+            // Only need to create entrance context at provider side, as context will take effect
+            // at entrance of invocation chain only (for inbound traffic).
+            ContextUtil.enter(methodResourceName, origin);
+            interfaceEntry = SphU.entry(interfaceResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN);
+            methodEntry = SphU.entry(methodResourceName, ResourceTypeConstants.COMMON_RPC, EntryType.IN,
+                invocation.getArguments());
+            Result result = invoker.invoke(invocation);
+            if (result.hasException()) {
+                Tracer.traceEntry(result.getException(), interfaceEntry);
+                Tracer.traceEntry(result.getException(), methodEntry);
+            }
+            return result;
+        } catch (BlockException e) {
+            return DubboAdapterGlobalConfig.getProviderFallback().handle(invoker, invocation, e);
+        } catch (RpcException e) {
+            Tracer.traceEntry(e, interfaceEntry);
+            Tracer.traceEntry(e, methodEntry);
+            throw e;
+        } finally {
+            if (methodEntry != null) {
+                methodEntry.exit(1, invocation.getArguments());
+            }
+            if (interfaceEntry != null) {
+                interfaceEntry.exit();
+            }
+            ContextUtil.exit();
+        }
+    }
+
+}
+
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/config/DubboAdapterGlobalConfig.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/config/DubboAdapterGlobalConfig.java
new file mode 100644
index 00000000..87f7da13
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/config/DubboAdapterGlobalConfig.java
@@ -0,0 +1,116 @@
+/*
+ * 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.dubbo3.config;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.fallback.DefaultDubboFallback;
+import com.alibaba.csp.sentinel.adapter.dubbo3.fallback.DubboFallback;
+import com.alibaba.csp.sentinel.adapter.dubbo3.origin.DefaultDubboOriginParser;
+import com.alibaba.csp.sentinel.adapter.dubbo3.origin.DubboOriginParser;
+import com.alibaba.csp.sentinel.config.SentinelConfig;
+import com.alibaba.csp.sentinel.util.AssertUtil;
+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 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:";
+
+    public static final String DUBBO_INTERFACE_GROUP_VERSION_ENABLED = "csp.sentinel.dubbo.interface.group.version.enabled";
+
+    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 getDubboProviderResNamePrefixKey() {
+        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 getDubboConsumerResNamePrefixKey() {
+        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 Boolean getDubboInterfaceGroupAndVersionEnabled() {
+        return TRUE_STR.equalsIgnoreCase(SentinelConfig.getConfig(DUBBO_INTERFACE_GROUP_VERSION_ENABLED));
+    }
+
+    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() {}
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DefaultDubboFallback.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DefaultDubboFallback.java
new file mode 100644
index 00000000..1d72308d
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DefaultDubboFallback.java
@@ -0,0 +1,35 @@
+/*
+ * 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.dubbo3.fallback;
+
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+
+import org.apache.dubbo.rpc.AsyncRpcResult;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+
+/**
+ * @author Eric Zhao
+ */
+public class DefaultDubboFallback implements DubboFallback {
+
+    @Override
+    public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) {
+        // Just wrap the exception.
+        return AsyncRpcResult.newDefaultAsyncResult(ex.toRuntimeException(), invocation);
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallback.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallback.java
new file mode 100644
index 00000000..7545fae3
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallback.java
@@ -0,0 +1,41 @@
+/*
+ * 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.dubbo3.fallback;
+
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+
+/**
+ * Fallback handler for Dubbo services.
+ *
+ * @author Eric Zhao
+ */
+@FunctionalInterface
+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);
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallbackRegistry.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallbackRegistry.java
new file mode 100644
index 00000000..5879c14e
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallbackRegistry.java
@@ -0,0 +1,46 @@
+/*
+ * 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.dubbo3.fallback;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+
+/**
+ * <p>Global fallback registry for Dubbo.</p>
+ *
+ * @author Eric Zhao
+ * @deprecated use {@link DubboAdapterGlobalConfig} instead since 1.8.0.
+ */
+@Deprecated
+public final class DubboFallbackRegistry {
+
+    public static DubboFallback getConsumerFallback() {
+        return DubboAdapterGlobalConfig.getConsumerFallback();
+    }
+
+    public static void setConsumerFallback(DubboFallback consumerFallback) {
+        DubboAdapterGlobalConfig.setConsumerFallback(consumerFallback);
+    }
+
+    public static DubboFallback getProviderFallback() {
+        return DubboAdapterGlobalConfig.getProviderFallback();
+    }
+
+    public static void setProviderFallback(DubboFallback providerFallback) {
+        DubboAdapterGlobalConfig.setProviderFallback(providerFallback);
+    }
+
+    private DubboFallbackRegistry() {}
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DefaultDubboOriginParser.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DefaultDubboOriginParser.java
new file mode 100644
index 00000000..d2c9474c
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DefaultDubboOriginParser.java
@@ -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.dubbo3.origin;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.DubboUtils;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+
+/**
+ * Default Dubbo origin parser.
+ *
+ * @author jingzian
+ */
+public class DefaultDubboOriginParser implements DubboOriginParser {
+
+    @Override
+    public String parse(Invoker<?> invoker, Invocation invocation) {
+        return DubboUtils.getApplication(invocation, "");
+    }
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DubboOriginParser.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DubboOriginParser.java
new file mode 100644
index 00000000..3ed312a4
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DubboOriginParser.java
@@ -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.dubbo3.origin;
+
+import com.alibaba.csp.sentinel.context.Context;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+
+/**
+ * Customized origin parser for Dubbo provider filter.{@link Context#getOrigin()}
+ *
+ * @author jingzian
+ */
+public interface DubboOriginParser {
+
+    /**
+     * Parses the origin (caller) from Dubbo invocation.
+     *
+     * @param invoker    Dubbo invoker
+     * @param invocation Dubbo invocation
+     * @return the parsed origin
+     */
+    String parse(Invoker<?> invoker, Invocation invocation);
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter
new file mode 100755
index 00000000..3773b33c
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter
@@ -0,0 +1,1 @@
+sentinel.dubbo.provider.filter=com.alibaba.csp.sentinel.adapter.dubbo3.SentinelDubboProviderFilter
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.filter.ClusterFilter b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
new file mode 100644
index 00000000..b46b3f1e
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
@@ -0,0 +1,2 @@
+dubbo.application.context.name.filter=com.alibaba.csp.sentinel.adapter.dubbo3.DubboAppContextFilter
+sentinel.dubbo.consumer.filter=com.alibaba.csp.sentinel.adapter.dubbo3.SentinelDubboConsumerFilter
diff --git a/sentinel-adapter/sentinel-apache-httpclient-adapter/pom.xml b/sentinel-adapter/sentinel-apache-httpclient-adapter/pom.xml
index c3b8d650..14f8dfcf 100644
--- a/sentinel-adapter/sentinel-apache-httpclient-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-apache-httpclient-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-api-gateway-adapter-common/pom.xml b/sentinel-adapter/sentinel-api-gateway-adapter-common/pom.xml
index 05c03e15..d56fd3fe 100644
--- a/sentinel-adapter/sentinel-api-gateway-adapter-common/pom.xml
+++ b/sentinel-adapter/sentinel-api-gateway-adapter-common/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-dubbo-adapter/pom.xml b/sentinel-adapter/sentinel-dubbo-adapter/pom.xml
index bc7360c1..18fb4c50 100755
--- a/sentinel-adapter/sentinel-dubbo-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-dubbo-adapter/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-adapter</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>sentinel-dubbo-adapter</artifactId>
diff --git a/sentinel-adapter/sentinel-grpc-adapter/pom.xml b/sentinel-adapter/sentinel-grpc-adapter/pom.xml
index 02f24117..04566d53 100755
--- a/sentinel-adapter/sentinel-grpc-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-grpc-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>sentinel-grpc-adapter</artifactId>
diff --git a/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml b/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml
index 8a4a3e6f..6bc1d62e 100755
--- a/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-jax-rs-adapter/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-adapter</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>sentinel-jax-rs-adapter</artifactId>
diff --git a/sentinel-adapter/sentinel-motan-adapter/pom.xml b/sentinel-adapter/sentinel-motan-adapter/pom.xml
index 3ce19026..ff721678 100644
--- a/sentinel-adapter/sentinel-motan-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-motan-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>sentinel-motan-adapter</artifactId>
diff --git a/sentinel-adapter/sentinel-okhttp-adapter/pom.xml b/sentinel-adapter/sentinel-okhttp-adapter/pom.xml
index 2e2be2d1..99626ff6 100644
--- a/sentinel-adapter/sentinel-okhttp-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-okhttp-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-quarkus-adapter/pom.xml b/sentinel-adapter/sentinel-quarkus-adapter/pom.xml
index d2daeaa0..ae46cc6d 100755
--- a/sentinel-adapter/sentinel-quarkus-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-quarkus-adapter/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-adapter</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>sentinel-quarkus-adapter-parent</artifactId>
diff --git a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-deployment/pom.xml b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-deployment/pom.xml
index 21259ae6..7255f9da 100644
--- a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-deployment/pom.xml
+++ b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-deployment/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-quarkus-adapter-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-runtime/pom.xml b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-runtime/pom.xml
index ea6f3f0e..6f785d50 100644
--- a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-runtime/pom.xml
+++ b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-annotation-quarkus-adapter-runtime/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-quarkus-adapter-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-deployment/pom.xml b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-deployment/pom.xml
index d779c579..997fe16d 100644
--- a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-deployment/pom.xml
+++ b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-deployment/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-quarkus-adapter-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-runtime/pom.xml b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-runtime/pom.xml
index d9232479..bd511cde 100644
--- a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-runtime/pom.xml
+++ b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-jax-rs-quarkus-adapter-runtime/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-quarkus-adapter-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-deployment/pom.xml b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-deployment/pom.xml
index 1a32d3c2..5305ffc2 100644
--- a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-deployment/pom.xml
+++ b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-deployment/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-quarkus-adapter-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-runtime/pom.xml b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-runtime/pom.xml
index ab15538c..4258e958 100644
--- a/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-runtime/pom.xml
+++ b/sentinel-adapter/sentinel-quarkus-adapter/sentinel-native-image-quarkus-adapter-runtime/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-quarkus-adapter-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/sentinel-adapter/sentinel-reactor-adapter/pom.xml b/sentinel-adapter/sentinel-reactor-adapter/pom.xml
index ca717265..66f87827 100644
--- a/sentinel-adapter/sentinel-reactor-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-reactor-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-sofa-rpc-adapter/pom.xml b/sentinel-adapter/sentinel-sofa-rpc-adapter/pom.xml
index 1c72276b..b3939ed4 100644
--- a/sentinel-adapter/sentinel-sofa-rpc-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-sofa-rpc-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-spring-cloud-gateway-adapter/pom.xml b/sentinel-adapter/sentinel-spring-cloud-gateway-adapter/pom.xml
index 32b26d7e..39f2abc0 100644
--- a/sentinel-adapter/sentinel-spring-cloud-gateway-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-spring-cloud-gateway-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-spring-webflux-adapter/pom.xml b/sentinel-adapter/sentinel-spring-webflux-adapter/pom.xml
index 9dd0738f..63798508 100644
--- a/sentinel-adapter/sentinel-spring-webflux-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-spring-webflux-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-spring-webmvc-adapter/pom.xml b/sentinel-adapter/sentinel-spring-webmvc-adapter/pom.xml
index e92189e2..0e3cd405 100644
--- a/sentinel-adapter/sentinel-spring-webmvc-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-spring-webmvc-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-adapter</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-adapter/sentinel-web-servlet/pom.xml b/sentinel-adapter/sentinel-web-servlet/pom.xml
index ebb78df9..8718d8ec 100755
--- a/sentinel-adapter/sentinel-web-servlet/pom.xml
+++ b/sentinel-adapter/sentinel-web-servlet/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-adapter</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>sentinel-web-servlet</artifactId>
diff --git a/sentinel-adapter/sentinel-zuul-adapter/pom.xml b/sentinel-adapter/sentinel-zuul-adapter/pom.xml
index 3065d4af..6a806e81 100755
--- a/sentinel-adapter/sentinel-zuul-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-zuul-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>sentinel-zuul-adapter</artifactId>
diff --git a/sentinel-adapter/sentinel-zuul2-adapter/pom.xml b/sentinel-adapter/sentinel-zuul2-adapter/pom.xml
index 010acb5a..5ca3cf1f 100644
--- a/sentinel-adapter/sentinel-zuul2-adapter/pom.xml
+++ b/sentinel-adapter/sentinel-zuul2-adapter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-adapter</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-benchmark/pom.xml b/sentinel-benchmark/pom.xml
index bffac956..a8a3d0fe 100644
--- a/sentinel-benchmark/pom.xml
+++ b/sentinel-benchmark/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-parent</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-cluster/pom.xml b/sentinel-cluster/pom.xml
index ae11700f..e65a9587 100644
--- a/sentinel-cluster/pom.xml
+++ b/sentinel-cluster/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-parent</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>pom</packaging>
diff --git a/sentinel-cluster/sentinel-cluster-client-default/pom.xml b/sentinel-cluster/sentinel-cluster-client-default/pom.xml
index 1b3c5b37..83f2bd26 100644
--- a/sentinel-cluster/sentinel-cluster-client-default/pom.xml
+++ b/sentinel-cluster/sentinel-cluster-client-default/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-cluster</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-cluster/sentinel-cluster-common-default/pom.xml b/sentinel-cluster/sentinel-cluster-common-default/pom.xml
index ce6ab069..73f38832 100644
--- a/sentinel-cluster/sentinel-cluster-common-default/pom.xml
+++ b/sentinel-cluster/sentinel-cluster-common-default/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-cluster</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-cluster/sentinel-cluster-server-default/pom.xml b/sentinel-cluster/sentinel-cluster-server-default/pom.xml
index bb3aa6a5..e4890ebf 100644
--- a/sentinel-cluster/sentinel-cluster-server-default/pom.xml
+++ b/sentinel-cluster/sentinel-cluster-server-default/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-cluster</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-cluster/sentinel-cluster-server-envoy-rls/pom.xml b/sentinel-cluster/sentinel-cluster-server-envoy-rls/pom.xml
index d7a7efa7..09231216 100644
--- a/sentinel-cluster/sentinel-cluster-server-envoy-rls/pom.xml
+++ b/sentinel-cluster/sentinel-cluster-server-envoy-rls/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-cluster</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -65,7 +65,7 @@
         <dependency>
             <groupId>org.yaml</groupId>
             <artifactId>snakeyaml</artifactId>
-            <version>1.26</version>
+            <version>1.32</version>
         </dependency>
 
         <dependency>
diff --git a/sentinel-core/pom.xml b/sentinel-core/pom.xml
index 592b088d..ed8b8d79 100755
--- a/sentinel-core/pom.xml
+++ b/sentinel-core/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-core</artifactId>
     <packaging>jar</packaging>
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java
index 7d956b18..cddc8c4d 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/Constants.java
@@ -31,7 +31,7 @@ import com.alibaba.csp.sentinel.util.VersionUtil;
  */
 public final class Constants {
 
-    public static final String SENTINEL_VERSION = VersionUtil.getVersion("1.8.4");
+    public static final String SENTINEL_VERSION = VersionUtil.getVersion("2.0.0");
 
     public final static int MAX_CONTEXT_NAME_SIZE = 2000;
     public final static int MAX_SLOT_CHAIN_SIZE = 6000;
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/AbstractRule.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/AbstractRule.java
index f6f10a76..befec3bc 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/AbstractRule.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/AbstractRule.java
@@ -23,6 +23,11 @@ package com.alibaba.csp.sentinel.slots.block;
  */
 public abstract class AbstractRule implements Rule {
 
+    /**
+     * rule id.
+     */
+    private Long id;
+
     /**
      * Resource name.
      */
@@ -39,6 +44,15 @@ public abstract class AbstractRule implements Rule {
      */
     private String limitApp;
 
+    public Long getId() {
+        return id;
+    }
+
+    public AbstractRule setId(Long id) {
+        this.id = id;
+        return this;
+    }
+
     @Override
     public String getResource() {
         return resource;
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/DefaultDegradeRuleManager.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/DefaultDegradeRuleManager.java
new file mode 100644
index 00000000..06214c3d
--- /dev/null
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/DefaultDegradeRuleManager.java
@@ -0,0 +1,134 @@
+package com.alibaba.csp.sentinel.slots.block.degrade;
+
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.property.DynamicSentinelProperty;
+import com.alibaba.csp.sentinel.property.PropertyListener;
+import com.alibaba.csp.sentinel.property.SentinelProperty;
+import com.alibaba.csp.sentinel.slots.block.RuleConstant;
+import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreaker;
+import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.ExceptionCircuitBreaker;
+import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.ResponseTimeCircuitBreaker;
+import com.alibaba.csp.sentinel.util.StringUtil;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
+/**
+ * @author wuwen
+ */
+public class DefaultDegradeRuleManager {
+
+    public static final String DEFAULT_KEY = "*";
+
+    private static volatile Map<String, List<CircuitBreaker>> circuitBreakers = new ConcurrentHashMap<>();
+    private static volatile Set<DegradeRule> rules = new HashSet<>();
+
+    private static final DefaultDegradeRuleManager.RulePropertyListener LISTENER = new DefaultDegradeRuleManager.RulePropertyListener();
+    private static SentinelProperty<List<DegradeRule>> currentProperty
+            = new DynamicSentinelProperty<>();
+
+    static {
+        currentProperty.addListener(LISTENER);
+    }
+
+
+    static List<CircuitBreaker> getDefaultCircuitBreakers(String resourceName) {
+        List<CircuitBreaker> circuitBreakers = DefaultDegradeRuleManager.circuitBreakers.get(resourceName);
+        if (circuitBreakers == null && !rules.isEmpty()) {
+            return DefaultDegradeRuleManager.circuitBreakers.computeIfAbsent(resourceName,
+                    r -> rules.stream().map(DefaultDegradeRuleManager::newCircuitBreakerFrom).collect(Collectors.toList()));
+        }
+        return circuitBreakers;
+    }
+
+    /**
+     * Load {@link DegradeRule}s, former rules will be replaced.
+     *
+     * @param rules new rules to load.
+     */
+    public static void loadRules(List<DegradeRule> rules) {
+        try {
+            currentProperty.updateValue(rules);
+        } catch (Throwable e) {
+            RecordLog.error("[DefaultDegradeRuleManager] Unexpected error when loading degrade rules", e);
+        }
+    }
+
+    public static boolean isValidDefaultRule(DegradeRule rule) {
+        if (!DegradeRuleManager.isValidRule(rule)) {
+            return false;
+        }
+
+        return rule.getResource().equals(DEFAULT_KEY);
+    }
+
+    /**
+     * Create a circuit breaker instance from provided circuit breaking rule.
+     *
+     * @param rule a valid circuit breaking rule
+     * @return new circuit breaker based on provided rule; null if rule is invalid or unsupported type
+     */
+    private static CircuitBreaker newCircuitBreakerFrom(/*@Valid*/ DegradeRule rule) {
+        switch (rule.getGrade()) {
+            case RuleConstant.DEGRADE_GRADE_RT:
+                return new ResponseTimeCircuitBreaker(rule);
+            case RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO:
+            case RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT:
+                return new ExceptionCircuitBreaker(rule);
+            default:
+                return null;
+        }
+    }
+
+
+    private static class RulePropertyListener implements PropertyListener<List<DegradeRule>> {
+
+        private synchronized void reloadFrom(List<DegradeRule> list) {
+
+            if (list == null) {
+                return;
+            }
+
+            Set<DegradeRule> rules = new HashSet<>();
+            List<CircuitBreaker> cbs = new ArrayList<>();
+
+            for (DegradeRule rule : list) {
+                if (!isValidDefaultRule(rule)) {
+                    RecordLog.warn("[DefaultDegradeRuleManager] Ignoring invalid rule when loading new rules: {}", rule);
+                } else {
+
+                    if (StringUtil.isBlank(rule.getLimitApp())) {
+                        rule.setLimitApp(RuleConstant.LIMIT_APP_DEFAULT);
+                    }
+                    CircuitBreaker cb = newCircuitBreakerFrom(rule);
+                    cbs.add(cb);
+                    rules.add(rule);
+                }
+            }
+
+            Map<String, List<CircuitBreaker>> cbMap = new ConcurrentHashMap<>(8);
+
+            DefaultDegradeRuleManager.circuitBreakers.forEach((k, v) -> cbMap.put(k, cbs));
+
+            DefaultDegradeRuleManager.rules = rules;
+            DefaultDegradeRuleManager.circuitBreakers = cbMap;
+        }
+
+        @Override
+        public void configUpdate(List<DegradeRule> conf) {
+            reloadFrom(conf);
+            RecordLog.info("[DefaultDegradeRuleManager] Degrade rules has been updated to: {}", rules);
+        }
+
+        @Override
+        public void configLoad(List<DegradeRule> conf) {
+            reloadFrom(conf);
+            RecordLog.info("[DefaultDegradeRuleManager] Degrade rules loaded: {}", rules);
+        }
+    }
+}
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/DefaultDegradeSlot.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/DefaultDegradeSlot.java
new file mode 100644
index 00000000..4d2c97fc
--- /dev/null
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/block/degrade/DefaultDegradeSlot.java
@@ -0,0 +1,76 @@
+package com.alibaba.csp.sentinel.slots.block.degrade;
+
+import com.alibaba.csp.sentinel.Constants;
+import com.alibaba.csp.sentinel.Entry;
+import com.alibaba.csp.sentinel.context.Context;
+import com.alibaba.csp.sentinel.node.DefaultNode;
+import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
+import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreaker;
+import com.alibaba.csp.sentinel.spi.Spi;
+
+import java.util.List;
+
+/**
+ * @author wuwen
+ */
+@Spi(order = Constants.ORDER_DEGRADE_SLOT + 100)
+public class DefaultDegradeSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
+
+    @Override
+    public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,
+                      boolean prioritized, Object... args) throws Throwable {
+        performChecking(context, resourceWrapper);
+
+        fireEntry(context, resourceWrapper, node, count, prioritized, args);
+    }
+
+    private void performChecking(Context context, ResourceWrapper r) throws BlockException {
+
+        if (DegradeRuleManager.hasConfig(r.getName())) {
+            return;
+        }
+
+        List<CircuitBreaker> circuitBreakers = DefaultDegradeRuleManager.getDefaultCircuitBreakers(r.getName());
+
+        if (circuitBreakers == null || circuitBreakers.isEmpty()) {
+            return;
+        }
+
+        for (CircuitBreaker cb : circuitBreakers) {
+            if (!cb.tryPass(context)) {
+                throw new DegradeException(cb.getRule().getLimitApp(), cb.getRule());
+            }
+        }
+    }
+
+    @Override
+    public void exit(Context context, ResourceWrapper r, int count, Object... args) {
+        Entry curEntry = context.getCurEntry();
+        if (curEntry.getBlockError() != null) {
+            fireExit(context, r, count, args);
+            return;
+        }
+
+        if (DegradeRuleManager.hasConfig(r.getName())) {
+            fireExit(context, r, count, args);
+            return;
+        }
+
+        List<CircuitBreaker> circuitBreakers = DefaultDegradeRuleManager.getDefaultCircuitBreakers(r.getName());
+
+        if (circuitBreakers == null || circuitBreakers.isEmpty()) {
+            return;
+        }
+
+        if (curEntry.getBlockError() == null) {
+            // passed request
+            for (CircuitBreaker circuitBreaker : circuitBreakers) {
+                circuitBreaker.onRequestComplete(context);
+            }
+        }
+
+        fireExit(context, r, count, args);
+    }
+}
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtil.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtil.java
index c599bb8f..7c3ad4d2 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtil.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtil.java
@@ -18,6 +18,7 @@ package com.alibaba.csp.sentinel.slots.logger;
 import com.alibaba.csp.sentinel.eagleeye.EagleEye;
 import com.alibaba.csp.sentinel.eagleeye.StatLogger;
 import com.alibaba.csp.sentinel.log.LogBase;
+import com.alibaba.csp.sentinel.util.StringUtil;
 
 public class EagleEyeLogUtil {
 
@@ -40,7 +41,11 @@ public class EagleEyeLogUtil {
             .buildSingleton();
     }
 
-    public static void log(String resource, String exceptionName, String ruleLimitApp, String origin, int count) {
-        statLogger.stat(resource, exceptionName, ruleLimitApp, origin).count(count);
+    public static void log(String resource, String exceptionName, String ruleLimitApp, String origin, Long ruleId, int count) {
+        String ruleIdString = StringUtil.EMPTY;
+        if (ruleId != null) {
+            ruleIdString = String.valueOf(ruleId);
+        }
+        statLogger.stat(resource, exceptionName, ruleLimitApp, origin, ruleIdString).count(count);
     }
 }
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/LogSlot.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/LogSlot.java
index 948b9101..e70457f5 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/LogSlot.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/logger/LogSlot.java
@@ -38,7 +38,7 @@ public class LogSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
             fireEntry(context, resourceWrapper, obj, count, prioritized, args);
         } catch (BlockException e) {
             EagleEyeLogUtil.log(resourceWrapper.getName(), e.getClass().getSimpleName(), e.getRuleLimitApp(),
-                context.getOrigin(), count);
+                context.getOrigin(), e.getRule().getId(), count);
             throw e;
         } catch (Throwable e) {
             RecordLog.warn("Unexpected entry exception", e);
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java
index 32b854e8..e67b40e9 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/statistic/base/LeapArray.java
@@ -127,7 +127,7 @@ public abstract class LeapArray<T> {
          *
          * (1) Bucket is absent, then just create a new bucket and CAS update to circular array.
          * (2) Bucket is up-to-date, then just return the bucket.
-         * (3) Bucket is deprecated, then reset current bucket and clean all deprecated buckets.
+         * (3) Bucket is deprecated, then reset current bucket.
          */
         while (true) {
             WindowWrap<T> old = array.get(idx);
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java
index 4ee5f17c..64d54be9 100755
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/slots/system/SystemRuleManager.java
@@ -302,18 +302,18 @@ public final class SystemRuleManager {
         }
 
         // total qps
-        double currentQps = Constants.ENTRY_NODE == null ? 0.0 : Constants.ENTRY_NODE.passQps();
+        double currentQps = Constants.ENTRY_NODE.passQps();
         if (currentQps + count > qps) {
             throw new SystemBlockException(resourceWrapper.getName(), "qps");
         }
 
         // total thread
-        int currentThread = Constants.ENTRY_NODE == null ? 0 : Constants.ENTRY_NODE.curThreadNum();
+        int currentThread = Constants.ENTRY_NODE.curThreadNum();
         if (currentThread > maxThread) {
             throw new SystemBlockException(resourceWrapper.getName(), "thread");
         }
 
-        double rt = Constants.ENTRY_NODE == null ? 0 : Constants.ENTRY_NODE.avgRt();
+        double rt = Constants.ENTRY_NODE.avgRt();
         if (rt > maxRt) {
             throw new SystemBlockException(resourceWrapper.getName(), "rt");
         }
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/spi/SpiLoader.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/spi/SpiLoader.java
index 4b78fb10..ffeeaa3e 100644
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/spi/SpiLoader.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/spi/SpiLoader.java
@@ -505,7 +505,7 @@ public final class SpiLoader<S> {
             try {
                 closeable.close();
             } catch (Exception e) {
-                if (firstException != null) {
+                if (firstException == null) {
                     firstException = e;
                 }
             }
diff --git a/sentinel-core/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.slotchain.ProcessorSlot b/sentinel-core/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.slotchain.ProcessorSlot
index afd97771..2e887a93 100644
--- a/sentinel-core/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.slotchain.ProcessorSlot
+++ b/sentinel-core/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.slotchain.ProcessorSlot
@@ -6,4 +6,5 @@ com.alibaba.csp.sentinel.slots.statistic.StatisticSlot
 com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot
 com.alibaba.csp.sentinel.slots.system.SystemSlot
 com.alibaba.csp.sentinel.slots.block.flow.FlowSlot
-com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot
\ No newline at end of file
+com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot
+com.alibaba.csp.sentinel.slots.block.degrade.DefaultDegradeSlot
\ No newline at end of file
diff --git a/sentinel-dashboard/pom.xml b/sentinel-dashboard/pom.xml
index 52bdcc7d..8d02cdc8 100644
--- a/sentinel-dashboard/pom.xml
+++ b/sentinel-dashboard/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>sentinel-dashboard</artifactId>
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java
index e013f89f..7813f811 100755
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/client/SentinelApiClient.java
@@ -71,6 +71,7 @@ import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.client.utils.URLEncodedUtils;
 import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.conn.util.InetAddressUtils;
 import org.apache.http.entity.ContentType;
 import org.apache.http.impl.client.DefaultRedirectStrategy;
 import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
@@ -282,6 +283,14 @@ public class SentinelApiClient {
             future.completeExceptionally(new IllegalArgumentException("Bad URL or command name"));
             return future;
         }
+        if (!InetAddressUtils.isIPv4Address(ip) && !InetAddressUtils.isIPv6Address(ip)) {
+            future.completeExceptionally(new IllegalArgumentException("Bad IP"));
+            return future;
+        }
+        if (!StringUtil.isEmpty(app) && !appManagement.isValidMachineOfApp(app, ip)) {
+            future.completeExceptionally(new IllegalArgumentException("Given ip does not belong to given app"));
+            return future;
+        }
         StringBuilder urlBuilder = new StringBuilder();
         urlBuilder.append("http://");
         urlBuilder.append(ip).append(':').append(port).append('/').append(api);
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java
index 294455f0..df6c90e5 100644
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AuthorityRuleController.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
 import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
+import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
 import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
 import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
 import com.alibaba.csp.sentinel.slots.block.RuleConstant;
@@ -56,6 +57,8 @@ public class AuthorityRuleController {
     private SentinelApiClient sentinelApiClient;
     @Autowired
     private RuleRepository<AuthorityRuleEntity, Long> repository;
+    @Autowired
+    private AppManagement appManagement;
 
     @GetMapping("/rules")
     @AuthAction(PrivilegeType.READ_RULE)
@@ -71,6 +74,9 @@ public class AuthorityRuleController {
         if (port == null || port <= 0) {
             return Result.ofFail(-1, "Invalid parameter: port");
         }
+        if (!appManagement.isValidMachineOfApp(app, ip)) {
+            return Result.ofFail(-1, "given ip does not belong to given app");
+        }
         try {
             List<AuthorityRuleEntity> rules = sentinelApiClient.fetchAuthorityRulesOfMachine(app, ip, port);
             rules = repository.saveAll(rules);
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java
index b5a72b06..4668f55c 100755
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/DegradeController.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
 import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
+import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
 import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
 import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
 import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
@@ -58,6 +59,8 @@ public class DegradeController {
     private RuleRepository<DegradeRuleEntity, Long> repository;
     @Autowired
     private SentinelApiClient sentinelApiClient;
+    @Autowired
+    private AppManagement appManagement;
 
     @GetMapping("/rules.json")
     @AuthAction(PrivilegeType.READ_RULE)
@@ -71,6 +74,9 @@ public class DegradeController {
         if (port == null) {
             return Result.ofFail(-1, "port can't be null");
         }
+        if (!appManagement.isValidMachineOfApp(app, ip)) {
+            return Result.ofFail(-1, "given ip does not belong to given app");
+        }
         try {
             List<DegradeRuleEntity> rules = sentinelApiClient.fetchDegradeRuleOfMachine(app, ip, port);
             rules = repository.saveAll(rules);
@@ -173,6 +179,9 @@ public class DegradeController {
         if (StringUtil.isBlank(entity.getIp())) {
             return Result.ofFail(-1, "ip can't be null or empty");
         }
+        if (!appManagement.isValidMachineOfApp(entity.getApp(), entity.getIp())) {
+            return Result.ofFail(-1, "given ip does not belong to given app");
+        }
         if (entity.getPort() == null || entity.getPort() <= 0) {
             return Result.ofFail(-1, "invalid port: " + entity.getPort());
         }
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java
index 50c4e32f..3806fd76 100755
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/FlowControllerV1.java
@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
 
 import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
 import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
+import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
 import com.alibaba.csp.sentinel.util.StringUtil;
 
 import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
@@ -57,6 +58,8 @@ public class FlowControllerV1 {
 
     @Autowired
     private InMemoryRuleRepositoryAdapter<FlowRuleEntity> repository;
+    @Autowired
+    private AppManagement appManagement;
 
     @Autowired
     private SentinelApiClient sentinelApiClient;
@@ -66,7 +69,6 @@ public class FlowControllerV1 {
     public Result<List<FlowRuleEntity>> apiQueryMachineRules(@RequestParam String app,
                                                              @RequestParam String ip,
                                                              @RequestParam Integer port) {
-
         if (StringUtil.isEmpty(app)) {
             return Result.ofFail(-1, "app can't be null or empty");
         }
@@ -76,6 +78,9 @@ public class FlowControllerV1 {
         if (port == null) {
             return Result.ofFail(-1, "port can't be null");
         }
+        if (!appManagement.isValidMachineOfApp(app, ip)) {
+            return Result.ofFail(-1, "given ip does not belong to given app");
+        }
         try {
             List<FlowRuleEntity> rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);
             rules = repository.saveAll(rules);
@@ -96,6 +101,9 @@ public class FlowControllerV1 {
         if (entity.getPort() == null) {
             return Result.ofFail(-1, "port can't be null");
         }
+        if (!appManagement.isValidMachineOfApp(entity.getApp(), entity.getIp())) {
+            return Result.ofFail(-1, "given ip does not belong to given app");
+        }
         if (StringUtil.isBlank(entity.getLimitApp())) {
             return Result.ofFail(-1, "limitApp can't be null or empty");
         }
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java
index 4039ca67..513b44dd 100644
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ParamFlowRuleController.java
@@ -93,6 +93,9 @@ public class ParamFlowRuleController {
         if (port == null || port <= 0) {
             return Result.ofFail(-1, "Invalid parameter: port");
         }
+        if (!appManagement.isValidMachineOfApp(app, ip)) {
+            return Result.ofFail(-1, "given ip does not belong to given app");
+        }
         if (!checkIfSupported(app, ip, port)) {
             return unsupportedVersion();
         }
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java
index daa0b98b..b3f3577e 100755
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/SystemController.java
@@ -20,6 +20,7 @@ import java.util.List;
 
 import com.alibaba.csp.sentinel.dashboard.auth.AuthAction;
 import com.alibaba.csp.sentinel.dashboard.auth.AuthService.PrivilegeType;
+import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
 import com.alibaba.csp.sentinel.dashboard.repository.rule.RuleRepository;
 import com.alibaba.csp.sentinel.util.StringUtil;
 
@@ -48,6 +49,8 @@ public class SystemController {
     private RuleRepository<SystemRuleEntity, Long> repository;
     @Autowired
     private SentinelApiClient sentinelApiClient;
+    @Autowired
+    private AppManagement appManagement;
 
     private <R> Result<R> checkBasicParams(String app, String ip, Integer port) {
         if (StringUtil.isEmpty(app)) {
@@ -59,6 +62,9 @@ public class SystemController {
         if (port == null) {
             return Result.ofFail(-1, "port can't be null");
         }
+        if (!appManagement.isValidMachineOfApp(app, ip)) {
+            return Result.ofFail(-1, "given ip does not belong to given app");
+        }
         if (port <= 0 || port > 65535) {
             return Result.ofFail(-1, "port should be in (0, 65535)");
         }
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfo.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfo.java
index f7697698..52be4d43 100755
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfo.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfo.java
@@ -96,6 +96,12 @@ public class AppInfo {
             .findFirst();
     }
 
+    public Optional<MachineInfo> getMachine(String ip) {
+        return machines.stream()
+            .filter(e -> e.getIp().equals(ip))
+            .findFirst();
+    }
+
     private boolean heartbeatJudge(final int threshold) {
         if (machines.size() == 0) {
             return false;
diff --git a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppManagement.java b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppManagement.java
index 9e44336f..a6d7653c 100755
--- a/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppManagement.java
+++ b/sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppManagement.java
@@ -16,10 +16,13 @@
 package com.alibaba.csp.sentinel.dashboard.discovery;
 
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 import javax.annotation.PostConstruct;
 
+import com.alibaba.csp.sentinel.util.StringUtil;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.stereotype.Component;
@@ -67,4 +70,13 @@ public class AppManagement implements MachineDiscovery {
         machineDiscovery.removeApp(app);
     }
 
+    public boolean isValidMachineOfApp(String app, String ip) {
+        if (StringUtil.isEmpty(app)) {
+            return false;
+        }
+        return Optional.ofNullable(getDetailApp(app))
+            .flatMap(a -> a.getMachine(ip))
+            .isPresent();
+    }
+
 }
diff --git a/sentinel-dashboard/src/main/resources/application.properties b/sentinel-dashboard/src/main/resources/application.properties
index 20ae4010..1bbb0819 100755
--- a/sentinel-dashboard/src/main/resources/application.properties
+++ b/sentinel-dashboard/src/main/resources/application.properties
@@ -1,14 +1,14 @@
 #spring settings
-spring.http.encoding.force=true
-spring.http.encoding.charset=UTF-8
-spring.http.encoding.enabled=true
+server.servlet.encoding.force=true
+server.servlet.encoding.charset=UTF-8
+server.servlet.encoding.enabled=true
 
 #cookie name setting
 server.servlet.session.cookie.name=sentinel_dashboard_cookie
 
 #logging settings
 logging.level.org.springframework.web=INFO
-logging.file=${user.home}/logs/csp/sentinel-dashboard.log
+logging.file.name=${user.home}/logs/csp/sentinel-dashboard.log
 logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
 #logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
 
diff --git a/sentinel-dashboard/src/main/webapp/resources/README.md b/sentinel-dashboard/src/main/webapp/resources/README.md
index c88ea68c..20f0de67 100755
--- a/sentinel-dashboard/src/main/webapp/resources/README.md
+++ b/sentinel-dashboard/src/main/webapp/resources/README.md
@@ -3,6 +3,7 @@
 ## Env Requirement
 
 - Node.js > 6.x
+- Node.js < 12.x
 
 ## Code Guide
 
diff --git a/sentinel-dashboard/src/main/webapp/resources/README_zh.md b/sentinel-dashboard/src/main/webapp/resources/README_zh.md
index 5daf33ef..48dae745 100644
--- a/sentinel-dashboard/src/main/webapp/resources/README_zh.md
+++ b/sentinel-dashboard/src/main/webapp/resources/README_zh.md
@@ -3,6 +3,7 @@
 ## 环境要求
 
 - Node.js > 6.x
+- Node.js < 12.x
 
 ## 编码规范
 
diff --git a/sentinel-demo/pom.xml b/sentinel-demo/pom.xml
index f7572c7f..847dcda1 100755
--- a/sentinel-demo/pom.xml
+++ b/sentinel-demo/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-demo</artifactId>
     <packaging>pom</packaging>
diff --git a/sentinel-demo/sentinel-demo-annotation-cdi-interceptor/pom.xml b/sentinel-demo/sentinel-demo-annotation-cdi-interceptor/pom.xml
index 7458c6c8..111d3016 100644
--- a/sentinel-demo/sentinel-demo-annotation-cdi-interceptor/pom.xml
+++ b/sentinel-demo/sentinel-demo-annotation-cdi-interceptor/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-annotation-spring-aop/pom.xml b/sentinel-demo/sentinel-demo-annotation-spring-aop/pom.xml
index dbc877aa..9cff0271 100644
--- a/sentinel-demo/sentinel-demo-annotation-spring-aop/pom.xml
+++ b/sentinel-demo/sentinel-demo-annotation-spring-aop/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-apache-dubbo/pom.xml b/sentinel-demo/sentinel-demo-apache-dubbo/pom.xml
index 51dbbc89..ccc1203f 100644
--- a/sentinel-demo/sentinel-demo-apache-dubbo/pom.xml
+++ b/sentinel-demo/sentinel-demo-apache-dubbo/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-apache-httpclient/pom.xml b/sentinel-demo/sentinel-demo-apache-httpclient/pom.xml
index addb0312..9d319940 100644
--- a/sentinel-demo/sentinel-demo-apache-httpclient/pom.xml
+++ b/sentinel-demo/sentinel-demo-apache-httpclient/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-apollo-datasource/pom.xml b/sentinel-demo/sentinel-demo-apollo-datasource/pom.xml
index 0f6b94e1..69b6e886 100644
--- a/sentinel-demo/sentinel-demo-apollo-datasource/pom.xml
+++ b/sentinel-demo/sentinel-demo-apollo-datasource/pom.xml
@@ -5,7 +5,7 @@
   <parent>
     <artifactId>sentinel-demo</artifactId>
     <groupId>com.alibaba.csp</groupId>
-    <version>1.8.4</version>
+    <version>2.0.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-basic/pom.xml b/sentinel-demo/sentinel-demo-basic/pom.xml
index 20ef4fda..69fa8966 100755
--- a/sentinel-demo/sentinel-demo-basic/pom.xml
+++ b/sentinel-demo/sentinel-demo-basic/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-demo</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-demo-basic</artifactId>
 
diff --git a/sentinel-demo/sentinel-demo-cluster/pom.xml b/sentinel-demo/sentinel-demo-cluster/pom.xml
index c9421b3f..5b6f0e0f 100644
--- a/sentinel-demo/sentinel-demo-cluster/pom.xml
+++ b/sentinel-demo/sentinel-demo-cluster/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/pom.xml b/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/pom.xml
index 8f95fecc..0c20d9e2 100644
--- a/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/pom.xml
+++ b/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-embedded/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo-cluster</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-server-alone/pom.xml b/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-server-alone/pom.xml
index bc8a6cee..7a6f4790 100644
--- a/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-server-alone/pom.xml
+++ b/sentinel-demo/sentinel-demo-cluster/sentinel-demo-cluster-server-alone/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo-cluster</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-command-handler/pom.xml b/sentinel-demo/sentinel-demo-command-handler/pom.xml
index a3282776..d4ccbe9e 100644
--- a/sentinel-demo/sentinel-demo-command-handler/pom.xml
+++ b/sentinel-demo/sentinel-demo-command-handler/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-dubbo/pom.xml b/sentinel-demo/sentinel-demo-dubbo/pom.xml
index 0984e02d..206c98ff 100644
--- a/sentinel-demo/sentinel-demo-dubbo/pom.xml
+++ b/sentinel-demo/sentinel-demo-dubbo/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-dynamic-file-rule/pom.xml b/sentinel-demo/sentinel-demo-dynamic-file-rule/pom.xml
index de46275e..cf88eb07 100755
--- a/sentinel-demo/sentinel-demo-dynamic-file-rule/pom.xml
+++ b/sentinel-demo/sentinel-demo-dynamic-file-rule/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-demo</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-demo-dynamic-file-rule</artifactId>
 
diff --git a/sentinel-demo/sentinel-demo-etcd-datasource/pom.xml b/sentinel-demo/sentinel-demo-etcd-datasource/pom.xml
index 9682d347..bbb9ea1a 100644
--- a/sentinel-demo/sentinel-demo-etcd-datasource/pom.xml
+++ b/sentinel-demo/sentinel-demo-etcd-datasource/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-jax-rs/pom.xml b/sentinel-demo/sentinel-demo-jax-rs/pom.xml
index 320e2d89..1249061a 100644
--- a/sentinel-demo/sentinel-demo-jax-rs/pom.xml
+++ b/sentinel-demo/sentinel-demo-jax-rs/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-log-logback/pom.xml b/sentinel-demo/sentinel-demo-log-logback/pom.xml
index d2c286a6..4bbac84b 100644
--- a/sentinel-demo/sentinel-demo-log-logback/pom.xml
+++ b/sentinel-demo/sentinel-demo-log-logback/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-motan/pom.xml b/sentinel-demo/sentinel-demo-motan/pom.xml
index 7020b801..ec3a5c25 100644
--- a/sentinel-demo/sentinel-demo-motan/pom.xml
+++ b/sentinel-demo/sentinel-demo-motan/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>sentinel-demo-motan</artifactId>
diff --git a/sentinel-demo/sentinel-demo-nacos-datasource/pom.xml b/sentinel-demo/sentinel-demo-nacos-datasource/pom.xml
index 26fe115e..112a1edc 100644
--- a/sentinel-demo/sentinel-demo-nacos-datasource/pom.xml
+++ b/sentinel-demo/sentinel-demo-nacos-datasource/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-okhttp/pom.xml b/sentinel-demo/sentinel-demo-okhttp/pom.xml
index 0f8018aa..aacba35c 100644
--- a/sentinel-demo/sentinel-demo-okhttp/pom.xml
+++ b/sentinel-demo/sentinel-demo-okhttp/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-parameter-flow-control/pom.xml b/sentinel-demo/sentinel-demo-parameter-flow-control/pom.xml
index 7ae99c36..e1bd52d4 100644
--- a/sentinel-demo/sentinel-demo-parameter-flow-control/pom.xml
+++ b/sentinel-demo/sentinel-demo-parameter-flow-control/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-quarkus/pom.xml b/sentinel-demo/sentinel-demo-quarkus/pom.xml
index a405a642..2ba49746 100644
--- a/sentinel-demo/sentinel-demo-quarkus/pom.xml
+++ b/sentinel-demo/sentinel-demo-quarkus/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-rocketmq/pom.xml b/sentinel-demo/sentinel-demo-rocketmq/pom.xml
index c4f5fced..9c59fb87 100755
--- a/sentinel-demo/sentinel-demo-rocketmq/pom.xml
+++ b/sentinel-demo/sentinel-demo-rocketmq/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-demo</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-slot-spi/pom.xml b/sentinel-demo/sentinel-demo-slot-spi/pom.xml
index e591fa60..5b30cdda 100644
--- a/sentinel-demo/sentinel-demo-slot-spi/pom.xml
+++ b/sentinel-demo/sentinel-demo-slot-spi/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-slotchain-spi/pom.xml b/sentinel-demo/sentinel-demo-slotchain-spi/pom.xml
index 24f50f68..90b30d0e 100644
--- a/sentinel-demo/sentinel-demo-slotchain-spi/pom.xml
+++ b/sentinel-demo/sentinel-demo-slotchain-spi/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-sofa-rpc/pom.xml b/sentinel-demo/sentinel-demo-sofa-rpc/pom.xml
index c1794144..f7584cb6 100644
--- a/sentinel-demo/sentinel-demo-sofa-rpc/pom.xml
+++ b/sentinel-demo/sentinel-demo-sofa-rpc/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-spring-cloud-gateway/pom.xml b/sentinel-demo/sentinel-demo-spring-cloud-gateway/pom.xml
index 6055c5dc..d5d3e4e8 100644
--- a/sentinel-demo/sentinel-demo-spring-cloud-gateway/pom.xml
+++ b/sentinel-demo/sentinel-demo-spring-cloud-gateway/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-spring-webflux/pom.xml b/sentinel-demo/sentinel-demo-spring-webflux/pom.xml
index 11267e97..36a3a0a6 100644
--- a/sentinel-demo/sentinel-demo-spring-webflux/pom.xml
+++ b/sentinel-demo/sentinel-demo-spring-webflux/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-spring-webmvc/pom.xml b/sentinel-demo/sentinel-demo-spring-webmvc/pom.xml
index b7dd9c69..c0bb7ef7 100644
--- a/sentinel-demo/sentinel-demo-spring-webmvc/pom.xml
+++ b/sentinel-demo/sentinel-demo-spring-webmvc/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-transport-spring-mvc/pom.xml b/sentinel-demo/sentinel-demo-transport-spring-mvc/pom.xml
index 573013d0..0064ae84 100644
--- a/sentinel-demo/sentinel-demo-transport-spring-mvc/pom.xml
+++ b/sentinel-demo/sentinel-demo-transport-spring-mvc/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-zookeeper-datasource/pom.xml b/sentinel-demo/sentinel-demo-zookeeper-datasource/pom.xml
index 64b730dd..08207937 100644
--- a/sentinel-demo/sentinel-demo-zookeeper-datasource/pom.xml
+++ b/sentinel-demo/sentinel-demo-zookeeper-datasource/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-zuul-gateway/pom.xml b/sentinel-demo/sentinel-demo-zuul-gateway/pom.xml
index 09a99a90..cd84b382 100644
--- a/sentinel-demo/sentinel-demo-zuul-gateway/pom.xml
+++ b/sentinel-demo/sentinel-demo-zuul-gateway/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-demo/sentinel-demo-zuul2-gateway/pom.xml b/sentinel-demo/sentinel-demo-zuul2-gateway/pom.xml
index 44b3a37a..a3e110d9 100644
--- a/sentinel-demo/sentinel-demo-zuul2-gateway/pom.xml
+++ b/sentinel-demo/sentinel-demo-zuul2-gateway/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-demo</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/pom.xml b/sentinel-extension/pom.xml
index b1ddb58b..e90a39a3 100755
--- a/sentinel-extension/pom.xml
+++ b/sentinel-extension/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-extension</artifactId>
     <packaging>pom</packaging>
@@ -25,6 +25,7 @@
         <module>sentinel-datasource-eureka</module>
         <module>sentinel-annotation-cdi-interceptor</module>
         <module>sentinel-metric-exporter</module>
+        <module>sentinel-datasource-opensergo</module>
     </modules>
 
 </project>
diff --git a/sentinel-extension/sentinel-annotation-aspectj/pom.xml b/sentinel-extension/sentinel-annotation-aspectj/pom.xml
index 740b4492..46dcc284 100644
--- a/sentinel-extension/sentinel-annotation-aspectj/pom.xml
+++ b/sentinel-extension/sentinel-annotation-aspectj/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-annotation-cdi-interceptor/pom.xml b/sentinel-extension/sentinel-annotation-cdi-interceptor/pom.xml
index 03b12492..4489c92f 100644
--- a/sentinel-extension/sentinel-annotation-cdi-interceptor/pom.xml
+++ b/sentinel-extension/sentinel-annotation-cdi-interceptor/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-apollo/pom.xml b/sentinel-extension/sentinel-datasource-apollo/pom.xml
index be5337ad..56ef112b 100644
--- a/sentinel-extension/sentinel-datasource-apollo/pom.xml
+++ b/sentinel-extension/sentinel-datasource-apollo/pom.xml
@@ -5,7 +5,7 @@
   <parent>
     <artifactId>sentinel-extension</artifactId>
     <groupId>com.alibaba.csp</groupId>
-    <version>1.8.4</version>
+    <version>2.0.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-consul/pom.xml b/sentinel-extension/sentinel-datasource-consul/pom.xml
index 9e5dcfec..05e64cdd 100644
--- a/sentinel-extension/sentinel-datasource-consul/pom.xml
+++ b/sentinel-extension/sentinel-datasource-consul/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-etcd/pom.xml b/sentinel-extension/sentinel-datasource-etcd/pom.xml
index 36b5f16c..d14c93da 100644
--- a/sentinel-extension/sentinel-datasource-etcd/pom.xml
+++ b/sentinel-extension/sentinel-datasource-etcd/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-eureka/pom.xml b/sentinel-extension/sentinel-datasource-eureka/pom.xml
index b3baca97..01811011 100644
--- a/sentinel-extension/sentinel-datasource-eureka/pom.xml
+++ b/sentinel-extension/sentinel-datasource-eureka/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-extension/pom.xml b/sentinel-extension/sentinel-datasource-extension/pom.xml
index eeb71937..bc0fce99 100755
--- a/sentinel-extension/sentinel-datasource-extension/pom.xml
+++ b/sentinel-extension/sentinel-datasource-extension/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-extension</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
 
     <artifactId>sentinel-datasource-extension</artifactId>
diff --git a/sentinel-extension/sentinel-datasource-nacos/pom.xml b/sentinel-extension/sentinel-datasource-nacos/pom.xml
index 2175b3e1..effad922 100644
--- a/sentinel-extension/sentinel-datasource-nacos/pom.xml
+++ b/sentinel-extension/sentinel-datasource-nacos/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-opensergo/README.md b/sentinel-extension/sentinel-datasource-opensergo/README.md
new file mode 100644
index 00000000..f28f287c
--- /dev/null
+++ b/sentinel-extension/sentinel-datasource-opensergo/README.md
@@ -0,0 +1,26 @@
+# Sentinel OpenSergo data-source
+
+Sentinel OpenSergo data-source provides integration with OpenSergo.
+The data source leverages [OpenSergo Java SDK](https://github.com/opensergo/opensergo-java-sdk) to implement subscribe (push) model.
+
+## Usage
+
+To use Sentinel OpenSergo data-source, you'll need to add the following Maven dependency:
+
+```xml
+<dependency>
+    <groupId>com.alibaba.csp</groupId>
+    <artifactId>sentinel-datasource-opensergo</artifactId>
+    <version>x.y.z</version>
+</dependency>
+```
+
+Then you can create an `OpenSergoDataSourceGroup` and subscribe Sentinel rules. For example:
+
+```java
+OpenSergoDataSourceGroup openSergo = new OpenSergoDataSourceGroup(host, port, namespace, appName);
+openSergo.start();
+
+// Subscribe flow rules from OpenSergo control plane, and propagate to Sentinel rule manager.
+FlowRuleManager.register2Property(openSergo.subscribeFlowRules());
+```
\ No newline at end of file
diff --git a/sentinel-extension/sentinel-datasource-opensergo/pom.xml b/sentinel-extension/sentinel-datasource-opensergo/pom.xml
new file mode 100644
index 00000000..a074d8e0
--- /dev/null
+++ b/sentinel-extension/sentinel-datasource-opensergo/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">
+    <parent>
+        <artifactId>sentinel-extension</artifactId>
+        <groupId>com.alibaba.csp</groupId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sentinel-datasource-opensergo</artifactId>
+
+    <properties>
+        <java.source.version>1.8</java.source.version>
+        <java.target.version>1.8</java.target.version>
+
+        <opensergo.sdk.version>0.1.0-beta1</opensergo.sdk.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba.csp</groupId>
+            <artifactId>sentinel-datasource-extension</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.opensergo</groupId>
+            <artifactId>opensergo-java-sdk</artifactId>
+            <version>${opensergo.sdk.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoDataSourceGroup.java b/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoDataSourceGroup.java
new file mode 100644
index 00000000..c07c6a5e
--- /dev/null
+++ b/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoDataSourceGroup.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright 1999-2022 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.datasource;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.property.DynamicSentinelProperty;
+import com.alibaba.csp.sentinel.property.SentinelProperty;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
+import com.alibaba.csp.sentinel.util.AssertUtil;
+
+import io.opensergo.ConfigKind;
+import io.opensergo.OpenSergoClient;
+import io.opensergo.proto.fault_tolerance.v1.CircuitBreakerStrategy;
+import io.opensergo.proto.fault_tolerance.v1.FaultToleranceRule;
+import io.opensergo.proto.fault_tolerance.v1.RateLimitStrategy;
+import io.opensergo.proto.fault_tolerance.v1.ThrottlingStrategy;
+import io.opensergo.subscribe.OpenSergoConfigSubscriber;
+import io.opensergo.subscribe.SubscribeKey;
+
+/**
+ * <p>Data-source group for subscribing Sentinel rules from OpenSergo control plane.</p>
+ *
+ * @author Eric Zhao
+ */
+public class OpenSergoDataSourceGroup {
+
+    private final OpenSergoClient openSergoClient;
+
+    private final String namespace;
+    private final String app;
+
+    /**
+     * (SentinelRuleKind, SentinelProperty)
+     */
+    private final ConcurrentMap<String, SentinelProperty> dataSourceMap = new ConcurrentHashMap<>();
+
+    private final ConcurrentMap<ConfigKind, SubscribeKey> subscribeKeyMap = new ConcurrentHashMap<>();
+    private final ConcurrentMap<String, Boolean> sentinelRuleSubscribeMap = new ConcurrentHashMap<>();
+
+    private final OpenSergoRuleAggregator ruleAggregator;
+
+    private final AtomicBoolean started = new AtomicBoolean(false);
+
+    /**
+     * @param host      host of OpenSergo Control Plane
+     * @param port      port of OpenSergo Control Plane
+     * @param namespace namespace to subscribe
+     * @param app       appName to subscribe
+     */
+    public OpenSergoDataSourceGroup(String host, int port, String namespace, String app) {
+        AssertUtil.notEmpty(namespace, "namespace cannot be empty");
+        AssertUtil.notEmpty(app, "app cannot be empty");
+        this.openSergoClient = new OpenSergoClient(host, port);
+        this.namespace = namespace;
+        this.app = app;
+        this.ruleAggregator = new OpenSergoRuleAggregator(dataSourceMap);
+
+        initializeDataSourceMap();
+    }
+
+    private void initializeDataSourceMap() {
+        dataSourceMap.put(OpenSergoSentinelConstants.KIND_FLOW_RULE, new DynamicSentinelProperty<List<FlowRule>>());
+        dataSourceMap.put(OpenSergoSentinelConstants.KIND_CIRCUIT_BREAKER_RULE,
+            new DynamicSentinelProperty<List<DegradeRule>>());
+    }
+
+    public void start() throws Exception {
+        if (started.compareAndSet(false, true)) {
+            openSergoClient.start();
+
+            prepareForBaseSubscription();
+        }
+    }
+
+    public void close() throws Exception {
+        if (started.compareAndSet(true, false)) {
+            for (Entry<ConfigKind, SubscribeKey> e : subscribeKeyMap.entrySet()) {
+                openSergoClient.unsubscribeConfig(e.getValue());
+                RecordLog.info("Unsubscribing OpenSergo config for target: {}", e.getValue());
+            }
+
+            openSergoClient.close();
+        }
+    }
+
+    private void prepareForBaseSubscription() {
+        SubscribeKey key = new SubscribeKey(namespace, app, ConfigKind.FAULT_TOLERANCE_RULE);
+
+        openSergoClient.subscribeConfig(key, new OpenSergoFaultToleranceRuleSubscriber(ruleAggregator));
+        subscribeKeyMap.put(ConfigKind.FAULT_TOLERANCE_RULE, key);
+
+        RecordLog.info("Subscribing OpenSergo base fault-tolerance rules for target <{}, {}>", namespace, app);
+    }
+
+    public boolean hasSubscribedFor(String sentinelRuleKind) {
+        if (sentinelRuleKind == null) {
+            return false;
+        }
+        return sentinelRuleSubscribeMap.getOrDefault(sentinelRuleKind, false);
+    }
+
+    /**
+     * <p>Subscribe Sentinel flow rules from OpenSergo control plane.</p>
+     *
+     * @return {@link SentinelProperty} of Sentinel flow rules
+     */
+    public synchronized SentinelProperty<List<FlowRule>> subscribeFlowRules() {
+        if (!started.get()) {
+            throw new IllegalStateException("OpenSergo data-source not started");
+        }
+
+        boolean subscribed = hasSubscribedFor(OpenSergoSentinelConstants.KIND_FLOW_RULE);
+        SentinelProperty<List<FlowRule>> property = dataSourceMap.get(OpenSergoSentinelConstants.KIND_FLOW_RULE);
+        if (subscribed) {
+            return property;
+        }
+
+        OpenSergoSentinelFlowRuleSubscriber subscriber = new OpenSergoSentinelFlowRuleSubscriber(ruleAggregator);
+
+        SubscribeKey rlsKey = new SubscribeKey(namespace, app, ConfigKind.RATE_LIMIT_STRATEGY);
+        openSergoClient.subscribeConfig(rlsKey, subscriber);
+        subscribeKeyMap.put(ConfigKind.RATE_LIMIT_STRATEGY, rlsKey);
+        RecordLog.info("Subscribing OpenSergo config for target: {}", rlsKey);
+
+        SubscribeKey tsKey = new SubscribeKey(namespace, app, ConfigKind.THROTTLING_STRATEGY);
+        openSergoClient.subscribeConfig(tsKey, subscriber);
+        subscribeKeyMap.put(ConfigKind.THROTTLING_STRATEGY, tsKey);
+        RecordLog.info("Subscribing OpenSergo config for target: {}", tsKey);
+
+        SubscribeKey concurrencyLimitKey = new SubscribeKey(namespace, app, ConfigKind.CONCURRENCY_LIMIT_STRATEGY);
+        openSergoClient.subscribeConfig(concurrencyLimitKey, subscriber);
+        subscribeKeyMap.put(ConfigKind.CONCURRENCY_LIMIT_STRATEGY, concurrencyLimitKey);
+        RecordLog.info("Subscribing OpenSergo config for target: {}", concurrencyLimitKey);
+
+        sentinelRuleSubscribeMap.put(OpenSergoSentinelConstants.KIND_FLOW_RULE, true);
+
+        return property;
+    }
+
+    /**
+     * <p>Subscribe Sentinel degrade rules from OpenSergo control plane.</p>
+     *
+     * @return {@link SentinelProperty} of Sentinel degrade rules
+     */
+    public synchronized SentinelProperty<List<DegradeRule>> subscribeDegradeRules() {
+        if (!started.get()) {
+            throw new IllegalStateException("OpenSergo data-source not started");
+        }
+
+        boolean subscribed = hasSubscribedFor(OpenSergoSentinelConstants.KIND_CIRCUIT_BREAKER_RULE);
+        SentinelProperty<List<DegradeRule>> property = dataSourceMap.get(
+            OpenSergoSentinelConstants.KIND_CIRCUIT_BREAKER_RULE);
+        if (subscribed) {
+            return property;
+        }
+
+        SubscribeKey subscribeKey = new SubscribeKey(namespace, app, ConfigKind.CIRCUIT_BREAKER_STRATEGY);
+        openSergoClient.subscribeConfig(subscribeKey,
+            new OpenSergoSentinelCircuitBreakerRuleSubscriber(ruleAggregator));
+        subscribeKeyMap.put(ConfigKind.CIRCUIT_BREAKER_STRATEGY, subscribeKey);
+        RecordLog.info("Subscribing OpenSergo config for target: {}", subscribeKey);
+
+        sentinelRuleSubscribeMap.put(OpenSergoSentinelConstants.KIND_CIRCUIT_BREAKER_RULE, true);
+
+        return property;
+    }
+
+    /**
+     * <p>Subscribe Sentinel flow rules from OpenSergo control plane.</p>
+     */
+    public synchronized void unsubscribeFlowRules() {
+        boolean subscribed = hasSubscribedFor(OpenSergoSentinelConstants.KIND_FLOW_RULE);
+        if (!subscribed) {
+            return;
+        }
+
+        SubscribeKey rlsKey = subscribeKeyMap.remove(ConfigKind.RATE_LIMIT_STRATEGY);
+        boolean rlRemoved = openSergoClient.unsubscribeConfig(rlsKey);
+        SubscribeKey tsKey = subscribeKeyMap.remove(ConfigKind.THROTTLING_STRATEGY);
+        boolean tsRemoved = openSergoClient.unsubscribeConfig(tsKey);
+        SubscribeKey concurrencyLimitKey = subscribeKeyMap.remove(ConfigKind.CONCURRENCY_LIMIT_STRATEGY);
+        boolean clRemoved = openSergoClient.unsubscribeConfig(concurrencyLimitKey);
+
+        sentinelRuleSubscribeMap.remove(OpenSergoSentinelConstants.KIND_FLOW_RULE);
+
+        // NOTE: unsubscribe operation does not affect existing rules in SentinelProperty.
+    }
+
+    public synchronized void unsubscribeDegradeRules() {
+        boolean subscribed = hasSubscribedFor(OpenSergoSentinelConstants.KIND_CIRCUIT_BREAKER_RULE);
+        if (!subscribed) {
+            return;
+        }
+
+        SubscribeKey cbKey = subscribeKeyMap.remove(ConfigKind.CIRCUIT_BREAKER_STRATEGY);
+        boolean cbRemoved = openSergoClient.unsubscribeConfig(cbKey);
+
+        sentinelRuleSubscribeMap.remove(OpenSergoSentinelConstants.KIND_CIRCUIT_BREAKER_RULE);
+
+        // NOTE: unsubscribe operation does not affect existing rules in SentinelProperty.
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public String getApp() {
+        return app;
+    }
+
+    static class OpenSergoFaultToleranceRuleSubscriber implements OpenSergoConfigSubscriber {
+
+        private final OpenSergoRuleAggregator ruleAggregator;
+
+        public OpenSergoFaultToleranceRuleSubscriber(OpenSergoRuleAggregator ruleAggregator) {
+            this.ruleAggregator = ruleAggregator;
+        }
+
+        @Override
+        public boolean onConfigUpdate(SubscribeKey subscribeKey, Object data) {
+            if (subscribeKey.getKind() != ConfigKind.FAULT_TOLERANCE_RULE || !(data instanceof List)) {
+                // type or data mismatch
+                return false;
+            }
+            return ruleAggregator.updateFaultToleranceRuleList((List<FaultToleranceRule>) data);
+        }
+    }
+
+    /**
+     * Subscriber for OpenSergo strategies related to Sentinel flow rules.
+     */
+    static class OpenSergoSentinelFlowRuleSubscriber implements OpenSergoConfigSubscriber {
+
+        private final OpenSergoRuleAggregator ruleAggregator;
+
+        public OpenSergoSentinelFlowRuleSubscriber(OpenSergoRuleAggregator ruleAggregator) {
+            this.ruleAggregator = ruleAggregator;
+        }
+
+        @Override
+        public boolean onConfigUpdate(SubscribeKey subscribeKey, Object data) {
+            if (!(data instanceof List)) {
+                // data mismatch
+                return false;
+            }
+
+            switch (subscribeKey.getKind()) {
+                case RATE_LIMIT_STRATEGY:
+                    return ruleAggregator.updateRateLimitStrategy((List<RateLimitStrategy>) data);
+                case THROTTLING_STRATEGY:
+                    return ruleAggregator.updateThrottlingStrategy((List<ThrottlingStrategy>) data);
+                case CONCURRENCY_LIMIT_STRATEGY:
+                    // TODO
+                    return false;
+                default:
+                    // Type mismatch
+                    return false;
+            }
+        }
+    }
+
+    static class OpenSergoSentinelCircuitBreakerRuleSubscriber implements OpenSergoConfigSubscriber {
+
+        private final OpenSergoRuleAggregator ruleAggregator;
+
+        public OpenSergoSentinelCircuitBreakerRuleSubscriber(OpenSergoRuleAggregator ruleAggregator) {
+            this.ruleAggregator = ruleAggregator;
+        }
+
+        @Override
+        public boolean onConfigUpdate(SubscribeKey subscribeKey, Object data) {
+            if (subscribeKey.getKind() != ConfigKind.CIRCUIT_BREAKER_STRATEGY || !(data instanceof List)) {
+                // type or data mismatch
+                return false;
+            }
+            return ruleAggregator.updateCircuitBreakerStrategy((List<CircuitBreakerStrategy>) data);
+        }
+    }
+}
diff --git a/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoRuleAggregator.java b/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoRuleAggregator.java
new file mode 100644
index 00000000..cc0390ee
--- /dev/null
+++ b/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoRuleAggregator.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright 1999-2022 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.datasource;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.property.SentinelProperty;
+import com.alibaba.csp.sentinel.slots.block.RuleConstant;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
+
+import io.opensergo.ConfigKind;
+import io.opensergo.proto.fault_tolerance.v1.CircuitBreakerStrategy;
+import io.opensergo.proto.fault_tolerance.v1.ConcurrencyLimitStrategy;
+import io.opensergo.proto.fault_tolerance.v1.FaultToleranceRule;
+import io.opensergo.proto.fault_tolerance.v1.FaultToleranceRule.FaultToleranceRuleTargetRef;
+import io.opensergo.proto.fault_tolerance.v1.RateLimitStrategy;
+import io.opensergo.proto.fault_tolerance.v1.ThrottlingStrategy;
+import io.opensergo.util.TimeUnitUtils;
+
+/**
+ * @author Eric Zhao
+ */
+public class OpenSergoRuleAggregator {
+
+    /**
+     * (SentinelRuleKind, SentinelProperty)
+     */
+    private final Map<String, SentinelProperty> dataSourceMap;
+
+    public OpenSergoRuleAggregator(Map<String, SentinelProperty> dataSourceMap) {
+        this.dataSourceMap = Collections.unmodifiableMap(dataSourceMap);
+    }
+
+    /**
+     * (strategyKindSimpleName, [rules that contain this kind of strategy])
+     */
+    private volatile Map<String, List<FaultToleranceRule>> ftRuleMapByStrategyKind = new HashMap<>();
+    /**
+     * (name, rateLimitStrategy)
+     */
+    private volatile Map<String, RateLimitStrategy> rateLimitStrategyMap = new HashMap<>();
+    private volatile Map<String, ThrottlingStrategy> throttlingStrategyMap = new HashMap<>();
+    private volatile Map<String, ConcurrencyLimitStrategy> concurrencyLimitStrategyMap = new HashMap<>();
+    private volatile Map<String, CircuitBreakerStrategy> circuitBreakerStrategyMap = new HashMap<>();
+
+    public synchronized boolean updateFaultToleranceRuleList(List<FaultToleranceRule> rules) {
+        Map<String, List<FaultToleranceRule>> map = new HashMap<>(4);
+
+        if (rules != null && !rules.isEmpty()) {
+            for (FaultToleranceRule rule : rules) {
+                Set<String> kinds = rule.getStrategiesList().stream()
+                    .map(e -> e.getKind()).collect(Collectors.toSet());
+                kinds.forEach(kindName -> map.computeIfAbsent(kindName, v -> new ArrayList<>()).add(rule));
+            }
+        }
+        this.ftRuleMapByStrategyKind = map;
+
+        // TODO: check whether the rules have been changed
+        handleFlowRuleUpdate();
+        handleCircuitBreakerRuleUpdate();
+
+        return true;
+    }
+
+    public synchronized boolean updateRateLimitStrategy(List<RateLimitStrategy> strategies) {
+        Map<String, RateLimitStrategy> map = new HashMap<>(4);
+        if (strategies != null && !strategies.isEmpty()) {
+            strategies.forEach(s -> map.put(s.getName(), s));
+        }
+        this.rateLimitStrategyMap = map;
+
+        return handleFlowRuleUpdate();
+    }
+
+    public synchronized boolean updateThrottlingStrategy(List<ThrottlingStrategy> strategies) {
+        Map<String, ThrottlingStrategy> map = new HashMap<>(4);
+        if (strategies != null && !strategies.isEmpty()) {
+            strategies.forEach(s -> map.put(s.getName(), s));
+        }
+        this.throttlingStrategyMap = map;
+
+        return handleFlowRuleUpdate();
+    }
+
+    public synchronized boolean updateCircuitBreakerStrategy(List<CircuitBreakerStrategy> strategies) {
+        Map<String, CircuitBreakerStrategy> map = new HashMap<>(4);
+        if (strategies != null && !strategies.isEmpty()) {
+            strategies.forEach(s -> map.put(s.getName(), s));
+        }
+        this.circuitBreakerStrategyMap = map;
+
+        return handleCircuitBreakerRuleUpdate();
+    }
+
+    private boolean handleFlowRuleUpdate() {
+        List<FlowRule> rules = new ArrayList<>();
+
+        List<FlowRule> rulesFromRateLimitStrategies = assembleFlowRulesFromRateLimitStrategies(
+            ftRuleMapByStrategyKind.get(ConfigKind.RATE_LIMIT_STRATEGY.getSimpleKindName()), rateLimitStrategyMap);
+        List<FlowRule> rulesFromThrottlingStrategies = assembleFlowRulesFromThrottlingStrategies(
+            ftRuleMapByStrategyKind.get(ConfigKind.THROTTLING_STRATEGY.getSimpleKindName()), throttlingStrategyMap);
+
+        rules.addAll(rulesFromRateLimitStrategies);
+        rules.addAll(rulesFromThrottlingStrategies);
+
+        // Update rules to upstream data-source.
+        return dataSourceMap.get(OpenSergoSentinelConstants.KIND_FLOW_RULE).updateValue(rules);
+    }
+
+    private boolean handleCircuitBreakerRuleUpdate() {
+        List<DegradeRule> rules = assembleDegradeRulesFromCbStrategies(
+            ftRuleMapByStrategyKind.get(ConfigKind.CIRCUIT_BREAKER_STRATEGY.getSimpleKindName()),
+            circuitBreakerStrategyMap);
+
+        // Update rules to upstream data-source.
+        return dataSourceMap.get(OpenSergoSentinelConstants.KIND_CIRCUIT_BREAKER_RULE).updateValue(rules);
+    }
+
+    private List<FlowRule> assembleFlowRulesFromRateLimitStrategies(List<FaultToleranceRule> ftRules,
+                                                                    Map<String, RateLimitStrategy> rateLimitStrategyMap) {
+        List<FlowRule> rules = new ArrayList<>();
+        if (ftRules == null || ftRules.isEmpty()) {
+            return rules;
+        }
+        for (FaultToleranceRule ftRule : ftRules) {
+            List<RateLimitStrategy> strategies = ftRule.getStrategiesList().stream()
+                .filter(e -> e.getKind().equals(ConfigKind.RATE_LIMIT_STRATEGY.getSimpleKindName()))
+                .map(e -> rateLimitStrategyMap.get(e.getName()))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+            if (strategies.isEmpty()) {
+                continue;
+            }
+
+            for (FaultToleranceRuleTargetRef targetRef : ftRule.getTargetsList()) {
+                String resourceName = targetRef.getTargetResourceName();
+
+                for (RateLimitStrategy strategy : strategies) {
+                    FlowRule flowRule = new FlowRule(resourceName);
+                    try {
+                        flowRule = fillFlowRuleWithRateLimitStrategy(flowRule, strategy);
+                        if (flowRule != null) {
+                            rules.add(flowRule);
+                        }
+                    } catch (Exception ex) {
+                        RecordLog.warn("Ignoring OpenSergo RateLimitStrategy due to covert failure, "
+                            + "resourceName={}, strategy={}", resourceName, strategy);
+                    }
+                }
+            }
+        }
+        return rules;
+    }
+
+    private List<FlowRule> assembleFlowRulesFromThrottlingStrategies(List<FaultToleranceRule> ftRules,
+                                                                     Map<String, ThrottlingStrategy> throttlingStrategyMap) {
+        List<FlowRule> rules = new ArrayList<>();
+        if (ftRules == null || ftRules.isEmpty()) {
+            return rules;
+        }
+        for (FaultToleranceRule ftRule : ftRules) {
+            List<ThrottlingStrategy> strategies = ftRule.getStrategiesList().stream()
+                .filter(e -> e.getKind().equals(ConfigKind.THROTTLING_STRATEGY.getSimpleKindName()))
+                .map(e -> throttlingStrategyMap.get(e.getName()))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+            if (strategies.isEmpty()) {
+                continue;
+            }
+
+            for (FaultToleranceRuleTargetRef targetRef : ftRule.getTargetsList()) {
+                String resourceName = targetRef.getTargetResourceName();
+
+                for (ThrottlingStrategy strategy : strategies) {
+                    FlowRule flowRule = new FlowRule(resourceName);
+                    fillFlowRuleWithThrottlingStrategy(flowRule, strategy);
+                    rules.add(flowRule);
+                }
+            }
+        }
+        return rules;
+    }
+
+    private List<DegradeRule> assembleDegradeRulesFromCbStrategies(List<FaultToleranceRule> ftRules,
+                                                                   Map<String, CircuitBreakerStrategy> strategyMap) {
+        List<DegradeRule> rules = new ArrayList<>();
+        if (ftRules == null || ftRules.isEmpty()) {
+            return rules;
+        }
+        for (FaultToleranceRule ftRule : ftRules) {
+            List<CircuitBreakerStrategy> strategies = ftRule.getStrategiesList().stream()
+                .filter(e -> e.getKind().equals(ConfigKind.CIRCUIT_BREAKER_STRATEGY.getSimpleKindName()))
+                .map(e -> strategyMap.get(e.getName()))
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+            if (strategies.isEmpty()) {
+                continue;
+            }
+
+            for (FaultToleranceRuleTargetRef targetRef : ftRule.getTargetsList()) {
+                String resourceName = targetRef.getTargetResourceName();
+
+                for (CircuitBreakerStrategy strategy : strategies) {
+                    DegradeRule degradeRule = new DegradeRule(resourceName);
+                    try {
+                        degradeRule = fillDegradeRuleWithCbStrategy(degradeRule, strategy);
+                        if (degradeRule != null) {
+                            rules.add(degradeRule);
+                        }
+                    } catch (Exception ex) {
+                        RecordLog.warn("Ignoring OpenSergo CircuitBreakerStrategy due to covert failure, "
+                            + "resourceName={}, strategy={}", resourceName, strategy);
+                    }
+                }
+            }
+        }
+        return rules;
+    }
+
+    private FlowRule fillFlowRuleWithRateLimitStrategy(FlowRule rule, RateLimitStrategy strategy) {
+        if (rule == null || strategy == null) {
+            return rule;
+        }
+        rule.setCount(strategy.getThreshold());
+        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
+        // TODO: support global rate limiting (limitMode=Global).
+        rule.setClusterMode(false);
+        // Relation strategy.
+        rule.setStrategy(RuleConstant.STRATEGY_DIRECT);
+        // Control behavior.
+        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
+
+        return rule;
+    }
+
+    private FlowRule fillFlowRuleWithThrottlingStrategy(FlowRule rule, ThrottlingStrategy strategy) {
+        if (rule == null || strategy == null) {
+            return rule;
+        }
+
+        // round-up
+        double countPerSec = Math.ceil(1000.0 / strategy.getMinIntervalMillisOfRequests());
+        rule.setCount(countPerSec);
+        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
+        rule.setClusterMode(false);
+        rule.setStrategy(RuleConstant.STRATEGY_DIRECT);
+        rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
+        rule.setMaxQueueingTimeMs((int) strategy.getQueueTimeoutMillis());
+
+        return rule;
+    }
+
+    private DegradeRule fillDegradeRuleWithCbStrategy(DegradeRule rule, CircuitBreakerStrategy strategy) {
+        if (rule == null || strategy == null) {
+            return rule;
+        }
+        switch (strategy.getStrategy()) {
+            case STRATEGY_SLOW_REQUEST_RATIO:
+                rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
+                rule.setSlowRatioThreshold(strategy.getTriggerRatio());
+                // maxAllowedRt
+                rule.setCount(strategy.getSlowCondition().getMaxAllowedRtMillis());
+                break;
+            case STRATEGY_ERROR_REQUEST_RATIO:
+                rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);
+                rule.setCount(strategy.getTriggerRatio());
+                break;
+            default:
+                throw new IllegalArgumentException("unknown strategy type: " + strategy.getStrategy());
+        }
+        int recoveryTimeoutSec = (int) (TimeUnitUtils.convertToMillis(strategy.getRecoveryTimeout(),
+            strategy.getRecoveryTimeoutTimeUnit()) / 1000);
+        rule.setTimeWindow(recoveryTimeoutSec);
+        int statIntervalMs = (int) TimeUnitUtils.convertToMillis(strategy.getStatDuration(),
+            strategy.getStatDurationTimeUnit());
+        rule.setStatIntervalMs(statIntervalMs);
+        rule.setMinRequestAmount(strategy.getMinRequestAmount());
+        return rule;
+    }
+
+}
diff --git a/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoSentinelConstants.java b/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoSentinelConstants.java
new file mode 100644
index 00000000..eb147040
--- /dev/null
+++ b/sentinel-extension/sentinel-datasource-opensergo/src/main/java/com/alibaba/csp/sentinel/datasource/OpenSergoSentinelConstants.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 1999-2022 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.datasource;
+
+/**
+ * @author Eric Zhao
+ */
+public final class OpenSergoSentinelConstants {
+
+    public static final String KIND_FLOW_RULE = "FlowRule";
+    public static final String KIND_CIRCUIT_BREAKER_RULE = "DegradeRule";
+    public static final String KIND_SYSTEM_ADAPTIVE_RULE = "SystemRule";
+    public static final String KIND_PARAM_FLOW_RULE = "ParamFlowRule";
+
+    private OpenSergoSentinelConstants() {}
+}
diff --git a/sentinel-extension/sentinel-datasource-redis/pom.xml b/sentinel-extension/sentinel-datasource-redis/pom.xml
index 17bc8e4b..0f1f3127 100644
--- a/sentinel-extension/sentinel-datasource-redis/pom.xml
+++ b/sentinel-extension/sentinel-datasource-redis/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-redis/src/main/java/com/alibaba/csp/sentinel/datasource/redis/RedisDataSource.java b/sentinel-extension/sentinel-datasource-redis/src/main/java/com/alibaba/csp/sentinel/datasource/redis/RedisDataSource.java
index d4e296b1..5888fc69 100644
--- a/sentinel-extension/sentinel-datasource-redis/src/main/java/com/alibaba/csp/sentinel/datasource/redis/RedisDataSource.java
+++ b/sentinel-extension/sentinel-datasource-redis/src/main/java/com/alibaba/csp/sentinel/datasource/redis/RedisDataSource.java
@@ -160,7 +160,7 @@ public class RedisDataSource<T> extends AbstractDataSource<String, T> {
             sentinelRedisUriBuilder.withClientName(clientName);
         }
         sentinelRedisUriBuilder.withSentinelMasterId(connectionConfig.getRedisSentinelMasterId())
-            .withTimeout(connectionConfig.getTimeout(), TimeUnit.MILLISECONDS);
+            .withTimeout(Duration.ofMillis(connectionConfig.getTimeout()));
         return RedisClient.create(sentinelRedisUriBuilder.build());
     }
 
diff --git a/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml b/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml
index 25a7098d..c889f735 100644
--- a/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml
+++ b/sentinel-extension/sentinel-datasource-spring-cloud-config/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-datasource-zookeeper/pom.xml b/sentinel-extension/sentinel-datasource-zookeeper/pom.xml
index ab8ecc2e..4c175cab 100644
--- a/sentinel-extension/sentinel-datasource-zookeeper/pom.xml
+++ b/sentinel-extension/sentinel-datasource-zookeeper/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-metric-exporter/pom.xml b/sentinel-extension/sentinel-metric-exporter/pom.xml
index 003bb636..e02cc518 100644
--- a/sentinel-extension/sentinel-metric-exporter/pom.xml
+++ b/sentinel-extension/sentinel-metric-exporter/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     
diff --git a/sentinel-extension/sentinel-parameter-flow-control/pom.xml b/sentinel-extension/sentinel-parameter-flow-control/pom.xml
index 5a60f3af..43a349d2 100644
--- a/sentinel-extension/sentinel-parameter-flow-control/pom.xml
+++ b/sentinel-extension/sentinel-parameter-flow-control/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-extension</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlot.java b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlot.java
index 0739a06a..f798c2be 100644
--- a/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlot.java
+++ b/sentinel-extension/sentinel-parameter-flow-control/src/main/java/com/alibaba/csp/sentinel/slots/block/flow/param/ParamFlowSlot.java
@@ -82,6 +82,10 @@ public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
                 String triggeredParam = "";
                 if (args.length > rule.getParamIdx()) {
                     Object value = args[rule.getParamIdx()];
+                    // Assign actual value with the result of paramFlowKey method
+                    if (value instanceof ParamFlowArgument) {
+                        value = ((ParamFlowArgument) value).paramFlowKey();
+                    }
                     triggeredParam = String.valueOf(value);
                 }
                 throw new ParamFlowException(resourceWrapper.getName(), triggeredParam, rule);
diff --git a/sentinel-logging/pom.xml b/sentinel-logging/pom.xml
index 46c399b6..742510b1 100755
--- a/sentinel-logging/pom.xml
+++ b/sentinel-logging/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-logging</artifactId>
     <packaging>pom</packaging>
diff --git a/sentinel-logging/sentinel-logging-slf4j/pom.xml b/sentinel-logging/sentinel-logging-slf4j/pom.xml
index e063ecb4..7e9a2c19 100644
--- a/sentinel-logging/sentinel-logging-slf4j/pom.xml
+++ b/sentinel-logging/sentinel-logging-slf4j/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-logging</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-transport/pom.xml b/sentinel-transport/pom.xml
index a4df4a42..0513f9e5 100755
--- a/sentinel-transport/pom.xml
+++ b/sentinel-transport/pom.xml
@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-parent</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <artifactId>sentinel-transport</artifactId>
     <description>The transport module of Sentinel</description>
diff --git a/sentinel-transport/sentinel-transport-common/pom.xml b/sentinel-transport/sentinel-transport-common/pom.xml
index 2b6a8a64..5fbe5333 100755
--- a/sentinel-transport/sentinel-transport-common/pom.xml
+++ b/sentinel-transport/sentinel-transport-common/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-transport</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <packaging>jar</packaging>
diff --git a/sentinel-transport/sentinel-transport-netty-http/pom.xml b/sentinel-transport/sentinel-transport-netty-http/pom.xml
index 4347757a..6c592ca0 100755
--- a/sentinel-transport/sentinel-transport-netty-http/pom.xml
+++ b/sentinel-transport/sentinel-transport-netty-http/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <groupId>com.alibaba.csp</groupId>
         <artifactId>sentinel-transport</artifactId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>sentinel-transport-netty-http</artifactId>
diff --git a/sentinel-transport/sentinel-transport-simple-http/pom.xml b/sentinel-transport/sentinel-transport-simple-http/pom.xml
index 775dbb01..63485cb7 100755
--- a/sentinel-transport/sentinel-transport-simple-http/pom.xml
+++ b/sentinel-transport/sentinel-transport-simple-http/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-transport</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
diff --git a/sentinel-transport/sentinel-transport-spring-mvc/pom.xml b/sentinel-transport/sentinel-transport-spring-mvc/pom.xml
index 184ea682..6a91495b 100644
--- a/sentinel-transport/sentinel-transport-spring-mvc/pom.xml
+++ b/sentinel-transport/sentinel-transport-spring-mvc/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>sentinel-transport</artifactId>
         <groupId>com.alibaba.csp</groupId>
-        <version>1.8.4</version>
+        <version>2.0.0-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 


Test patch:
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java
new file mode 100644
index 00000000..e4642cc9
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/BaseTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.csp.sentinel.adapter.dubbo3.fallback.DefaultDubboFallback;
+import com.alibaba.csp.sentinel.config.SentinelConfig;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
+import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
+import org.apache.dubbo.rpc.RpcContext;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+/**
+ * Base test class, provide common methods for subClass
+ * The package is same as CtSph, to call CtSph.resetChainMap() method for test
+ * <p>
+ * Note: Only for test. DO NOT USE IN PRODUCTION!
+ *
+ * @author cdfive
+ * @author lianglin
+ */
+public class BaseTest {
+
+
+    /**
+     * Clean up resources for context, clusterNodeMap, processorSlotChainMap
+     */
+    public void cleanUpAll() {
+        try {
+            clearDubboContext();
+            cleanUpCstContext();
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void cleanUpCstContext() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        ClusterBuilderSlot.getClusterNodeMap().clear();
+        CtSph.resetChainMap();
+        Method method = ContextUtil.class.getDeclaredMethod("resetContextMap");
+        method.setAccessible(true);
+        method.invoke(null, null);
+        ContextUtil.exit();
+        FlowRuleManager.loadRules(new ArrayList<>());
+        DegradeRuleManager.loadRules(new ArrayList<>());
+    }
+
+    private void clearDubboContext() {
+        SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "false");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_PROVIDER_RES_NAME_PREFIX_KEY, "");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_CONSUMER_RES_NAME_PREFIX_KEY, "");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false");
+        DubboAdapterGlobalConfig.setConsumerFallback(new DefaultDubboFallback());
+        RpcContext.removeContext();
+
+    }
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/DubboTestUtil.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/DubboTestUtil.java
new file mode 100644
index 00000000..b7f1912b
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/DubboTestUtil.java
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+import java.lang.reflect.Method;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author lianglin
+ */
+public class DubboTestUtil {
+
+
+    public static Class<?> DEFAULT_TEST_SERVICE = DemoService.class;
+    public static Method DEFAULT_TEST_METHOD_ONE = DEFAULT_TEST_SERVICE.getMethods()[0];
+    public static Method DEFAULT_TEST_METHOD_TWO = DEFAULT_TEST_SERVICE.getMethods()[1];
+
+    public static Invoker getMockInvoker(URL url, Class<?> cls) {
+        Invoker invoker = mock(Invoker.class);
+        when(invoker.getUrl()).thenReturn(url);
+        when(invoker.getInterface()).thenReturn(cls);
+        return invoker;
+    }
+
+    public static Invoker getDefaultMockInvoker() {
+        return getMockInvoker(getDefaultTestURL(), DEFAULT_TEST_SERVICE);
+    }
+
+    public static Invocation getMockInvocation(Method method) {
+        Invocation invocation = mock(RpcInvocation.class);
+        when(invocation.getMethodName()).thenReturn(method.getName());
+        when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
+        return invocation;
+    }
+
+    public static Invocation getDefaultMockInvocationOne() {
+        Invocation invocation = mock(RpcInvocation.class);
+        when(invocation.getMethodName()).thenReturn(DEFAULT_TEST_METHOD_ONE.getName());
+        when(invocation.getParameterTypes()).thenReturn(DEFAULT_TEST_METHOD_ONE.getParameterTypes());
+        return invocation;
+    }
+
+    public static Invocation getDefaultMockInvocationTwo() {
+        Invocation invocation = mock(RpcInvocation.class);
+        when(invocation.getMethodName()).thenReturn(DEFAULT_TEST_METHOD_TWO.getName());
+        when(invocation.getParameterTypes()).thenReturn(DEFAULT_TEST_METHOD_TWO.getParameterTypes());
+        return invocation;
+    }
+
+    public static URL getDefaultTestURL() {
+        URL url = URL.valueOf("dubbo://127.0.0.1:2181")
+                .addParameter(CommonConstants.VERSION_KEY, "1.0.0")
+                .addParameter(CommonConstants.GROUP_KEY, "grp1")
+                .addParameter(CommonConstants.INTERFACE_KEY, DEFAULT_TEST_SERVICE.getName());
+        return url;
+    }
+
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboAppContextFilterTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboAppContextFilterTest.java
new file mode 100644
index 00000000..89ff76e2
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboAppContextFilterTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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.dubbo3;
+
+import com.alibaba.csp.sentinel.BaseTest;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+/**
+ * @author cdfive
+ */
+public class DubboAppContextFilterTest extends BaseTest {
+
+    @Before
+    public void setUp() {
+        cleanUpAll();
+    }
+
+    @After
+    public void cleanUp() {
+        cleanUpAll();
+    }
+
+    @Test
+    public void testInvokeApplicationKey() {
+        Invoker invoker = mock(Invoker.class);
+        Invocation invocation = mock(Invocation.class);
+        URL url = URL.valueOf("test://test:111/test?application=serviceA");
+        when(invoker.getUrl()).thenReturn(url);
+
+        ApplicationModel applicationModel = FrameworkModel.defaultModel().newApplication();
+        applicationModel.getApplicationConfigManager().setApplication(new ApplicationConfig("serviceA"));
+        DubboAppContextFilter filter = new DubboAppContextFilter(applicationModel);
+        filter.invoke(invoker, invocation);
+        verify(invoker).invoke(invocation);
+
+        verify(invocation).setAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "serviceA");
+        applicationModel.destroy();
+    }
+
+    @Test
+    public void testInvokeNullApplicationKey() {
+        Invoker invoker = mock(Invoker.class);
+        Invocation invocation = mock(Invocation.class);
+        URL url = URL.valueOf("test://test:111/test?application=");
+        when(invoker.getUrl()).thenReturn(url);
+
+        ApplicationModel applicationModel = FrameworkModel.defaultModel().newApplication();
+        DubboAppContextFilter filter = new DubboAppContextFilter(applicationModel);
+        filter.invoke(invoker, invocation);
+        verify(invoker).invoke(invocation);
+
+        verify(invocation, times(0)).setAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "serviceA");
+        applicationModel.destroy();
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboUtilsTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboUtilsTest.java
new file mode 100644
index 00000000..70124ccf
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/DubboUtilsTest.java
@@ -0,0 +1,206 @@
+/*
+ * 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.dubbo3;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService;
+import com.alibaba.csp.sentinel.config.SentinelConfig;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.*;
+
+/**
+ * @author cdfive
+ */
+public class DubboUtilsTest {
+
+    @Before
+    public void setUp() {
+        SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "true");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_PROVIDER_RES_NAME_PREFIX_KEY, "");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_CONSUMER_RES_NAME_PREFIX_KEY, "");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false");
+    }
+
+
+    @After
+    public void tearDown() {
+        SentinelConfig.setConfig("csp.sentinel.dubbo.resource.use.prefix", "false");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_PROVIDER_RES_NAME_PREFIX_KEY, "");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_CONSUMER_RES_NAME_PREFIX_KEY, "");
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false");
+    }
+
+
+    @Test
+    public void testGetApplication() {
+        Invocation invocation = mock(Invocation.class);
+        when(invocation.getAttachments()).thenReturn(new HashMap<>());
+        when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, ""))
+                .thenReturn("consumerA");
+
+        String application = DubboUtils.getApplication(invocation, "");
+        verify(invocation).getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "");
+
+        assertEquals("consumerA", application);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetApplicationNoAttachments() {
+        Invocation invocation = mock(Invocation.class);
+        when(invocation.getAttachments()).thenReturn(null);
+        when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, ""))
+                .thenReturn("consumerA");
+
+        DubboUtils.getApplication(invocation, "");
+
+        fail("No attachments in invocation, IllegalArgumentException should be thrown!");
+    }
+
+    @Test
+    public void testGetResourceName() throws NoSuchMethodException {
+        Invoker invoker = mock(Invoker.class);
+        when(invoker.getInterface()).thenReturn(DemoService.class);
+
+        Invocation invocation = mock(Invocation.class);
+        Method method = DemoService.class.getDeclaredMethod("sayHello", String.class, int.class);
+        when(invocation.getMethodName()).thenReturn(method.getName());
+        when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
+
+        String resourceName = DubboUtils.getMethodResourceName(invoker, invocation);
+
+        assertEquals("com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
+
+    }
+
+    @Test
+    public void testGetResourceNameWithGroupAndVersion() throws NoSuchMethodException {
+        Invoker invoker = mock(Invoker.class);
+        URL url = URL.valueOf("dubbo://127.0.0.1:2181")
+                .addParameter(CommonConstants.VERSION_KEY, "1.0.0")
+                .addParameter(CommonConstants.GROUP_KEY, "grp1")
+                .addParameter(CommonConstants.INTERFACE_KEY, DemoService.class.getName());
+        when(invoker.getUrl()).thenReturn(url);
+        when(invoker.getInterface()).thenReturn(DemoService.class);
+
+        Invocation invocation = mock(Invocation.class);
+        Method method = DemoService.class.getDeclaredMethod("sayHello", String.class, int.class);
+        when(invocation.getMethodName()).thenReturn(method.getName());
+        when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
+
+        String resourceNameUseGroupAndVersion = DubboUtils.getMethodResourceName(invoker, invocation, true);
+
+        assertEquals("com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService:1.0.0:grp1:sayHello(java.lang.String,int)", resourceNameUseGroupAndVersion);
+    }
+
+
+    @Test
+    public void testGetResourceNameWithPrefix() throws NoSuchMethodException {
+        Invoker invoker = mock(Invoker.class);
+        when(invoker.getInterface()).thenReturn(DemoService.class);
+
+        Invocation invocation = mock(Invocation.class);
+        Method method = DemoService.class.getDeclaredMethod("sayHello", String.class, int.class);
+        when(invocation.getMethodName()).thenReturn(method.getName());
+        when(invocation.getParameterTypes()).thenReturn(method.getParameterTypes());
+
+        //test with default prefix
+        String resourceName = DubboUtils.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboProviderResNamePrefixKey());
+        assertEquals("dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
+        resourceName = DubboUtils.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey());
+        assertEquals("dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
+
+
+        //test with custom prefix
+        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 = DubboUtils.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboProviderResNamePrefixKey());
+        assertEquals("my:dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
+        resourceName = DubboUtils.getMethodResourceName(invoker, invocation, DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey());
+        assertEquals("my:dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService:sayHello(java.lang.String,int)", resourceName);
+
+    }
+
+    @Test
+    public void testGetInterfaceName() {
+
+        URL url = URL.valueOf("dubbo://127.0.0.1:2181")
+                .addParameter(CommonConstants.VERSION_KEY, "1.0.0")
+                .addParameter(CommonConstants.GROUP_KEY, "grp1")
+                .addParameter(CommonConstants.INTERFACE_KEY, DemoService.class.getName());
+        Invoker invoker = mock(Invoker.class);
+        when(invoker.getUrl()).thenReturn(url);
+        when(invoker.getInterface()).thenReturn(DemoService.class);
+
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "false");
+        assertEquals("com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService", DubboUtils.getInterfaceName(invoker));
+
+    }
+
+    @Test
+    public void testGetInterfaceNameWithGroupAndVersion() throws NoSuchMethodException {
+
+        URL url = URL.valueOf("dubbo://127.0.0.1:2181")
+                .addParameter(CommonConstants.VERSION_KEY, "1.0.0")
+                .addParameter(CommonConstants.GROUP_KEY, "grp1")
+                .addParameter(CommonConstants.INTERFACE_KEY, DemoService.class.getName());
+        Invoker invoker = mock(Invoker.class);
+        when(invoker.getUrl()).thenReturn(url);
+        when(invoker.getInterface()).thenReturn(DemoService.class);
+
+        SentinelConfig.setConfig(DubboAdapterGlobalConfig.DUBBO_INTERFACE_GROUP_VERSION_ENABLED, "true");
+        assertEquals("com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService:1.0.0:grp1", DubboUtils.getInterfaceName(invoker, true));
+    }
+
+    @Test
+    public void testGetInterfaceNameWithPrefix() throws NoSuchMethodException {
+        URL url = URL.valueOf("dubbo://127.0.0.1:2181")
+                .addParameter(CommonConstants.VERSION_KEY, "1.0.0")
+                .addParameter(CommonConstants.GROUP_KEY, "grp1")
+                .addParameter(CommonConstants.INTERFACE_KEY, DemoService.class.getName());
+        Invoker invoker = mock(Invoker.class);
+        when(invoker.getUrl()).thenReturn(url);
+        when(invoker.getInterface()).thenReturn(DemoService.class);
+
+
+        //test with default prefix
+        String resourceName = DubboUtils.getInterfaceName(invoker, DubboAdapterGlobalConfig.getDubboProviderResNamePrefixKey());
+        assertEquals("dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService", resourceName);
+        resourceName = DubboUtils.getInterfaceName(invoker, DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey());
+        assertEquals("dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService", resourceName);
+
+
+        //test with custom prefix
+        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 = DubboUtils.getInterfaceName(invoker, DubboAdapterGlobalConfig.getDubboProviderResNamePrefixKey());
+        assertEquals("my:dubbo:provider:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService", resourceName);
+        resourceName = DubboUtils.getInterfaceName(invoker, DubboAdapterGlobalConfig.getDubboConsumerResNamePrefixKey());
+        assertEquals("my:dubbo:consumer:com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService", resourceName);
+
+    }
+}
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboConsumerFilterTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboConsumerFilterTest.java
new file mode 100644
index 00000000..a91d67d4
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboConsumerFilterTest.java
@@ -0,0 +1,391 @@
+/*
+ * 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.dubbo3;
+
+import com.alibaba.csp.sentinel.BaseTest;
+import com.alibaba.csp.sentinel.DubboTestUtil;
+import com.alibaba.csp.sentinel.Entry;
+import com.alibaba.csp.sentinel.EntryType;
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.csp.sentinel.context.Context;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.node.ClusterNode;
+import com.alibaba.csp.sentinel.node.DefaultNode;
+import com.alibaba.csp.sentinel.node.Node;
+import com.alibaba.csp.sentinel.node.StatisticNode;
+import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
+import com.alibaba.csp.sentinel.slots.block.RuleConstant;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
+import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
+
+import org.apache.dubbo.rpc.*;
+import org.apache.dubbo.rpc.support.RpcUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.*;
+
+import static com.alibaba.csp.sentinel.slots.block.RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO;
+import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+/**
+ * @author cdfive
+ * @author lianglin
+ */
+public class SentinelDubboConsumerFilterTest extends BaseTest {
+
+    private final SentinelDubboConsumerFilter consumerFilter = new SentinelDubboConsumerFilter();
+
+    @Before
+    public void setUp() {
+        cleanUpAll();
+        initFallback();
+    }
+
+    @After
+    public void destroy() {
+        cleanUpAll();
+    }
+
+    @Test
+    public void testInterfaceLevelFollowControlAsync() throws InterruptedException {
+
+        Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
+        Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
+
+        when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString());
+        initFlowRule(DubboUtils.getInterfaceName(invoker));
+
+        Result result1 = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("normal", result1.getValue());
+
+        // should fallback because the qps > 1
+        Result result2 = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("fallback", result2.getValue());
+
+        // sleeping 1000 ms to reset qps
+        Thread.sleep(1000);
+        Result result3 = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("normal", result3.getValue());
+
+        verifyInvocationStructureForCallFinish(invoker, invocation);
+    }
+
+    @Test
+    public void testDegradeAsync() throws InterruptedException {
+
+        Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
+        Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
+
+        when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString());
+        initDegradeRule(DubboUtils.getInterfaceName(invoker));
+
+        Result result = invokeDubboRpc(false, invoker, invocation);
+        verifyInvocationStructureForCallFinish(invoker, invocation);
+        assertEquals("normal", result.getValue());
+
+        // inc the clusterNode's exception to trigger the fallback
+        for (int i = 0; i < 5; i++) {
+            invokeDubboRpc(true, invoker, invocation);
+            verifyInvocationStructureForCallFinish(invoker, invocation);
+        }
+
+        Result result2 = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("fallback", result2.getValue());
+
+        // sleeping 1000 ms to reset exception
+        Thread.sleep(1000);
+        Result result3 = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("normal", result3.getValue());
+
+        Context context = ContextUtil.getContext();
+        assertNull(context);
+    }
+
+    @Test
+    public void testDegradeSync() throws InterruptedException {
+
+        Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
+        Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
+        initDegradeRule(DubboUtils.getInterfaceName(invoker));
+
+        Result result = invokeDubboRpc(false, invoker, invocation);
+        verifyInvocationStructureForCallFinish(invoker, invocation);
+        assertEquals("normal", result.getValue());
+
+        // inc the clusterNode's exception to trigger the fallback
+        for (int i = 0; i < 5; i++) {
+            invokeDubboRpc(true, invoker, invocation);
+            verifyInvocationStructureForCallFinish(invoker, invocation);
+        }
+
+        Result result2 = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("fallback", result2.getValue());
+
+        // sleeping 1000 ms to reset exception
+        Thread.sleep(1000);
+        Result result3 = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("normal", result3.getValue());
+
+        Context context = ContextUtil.getContext();
+        assertNull(context);
+    }
+
+    @Test
+    public void testMethodFlowControlAsync() {
+
+        Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
+        Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
+
+        when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString());
+        initFlowRule(consumerFilter.getMethodName(invoker, invocation, null));
+        invokeDubboRpc(false, invoker, invocation);
+        invokeDubboRpc(false, invoker, invocation);
+
+        Invocation invocation2 = DubboTestUtil.getDefaultMockInvocationTwo();
+        Result result2 = invokeDubboRpc(false, invoker, invocation2);
+        verifyInvocationStructureForCallFinish(invoker, invocation2);
+        assertEquals("normal", result2.getValue());
+
+        // the method of invocation should be blocked
+        Result fallback = invokeDubboRpc(false, invoker, invocation);
+        assertEquals("fallback", fallback.getValue());
+        verifyInvocationStructureForCallFinish(invoker, invocation);
+
+    }
+
+    @Test
+    public void testInvokeAsync() {
+
+        Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
+        Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
+
+        when(invocation.getAttachment(ASYNC_KEY)).thenReturn(Boolean.TRUE.toString());
+        final Result result = mock(Result.class);
+        when(result.hasException()).thenReturn(false);
+        when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> {
+            verifyInvocationStructureForAsyncCall(invoker, invocation);
+            return result;
+        });
+        consumerFilter.invoke(invoker, invocation);
+        verify(invoker).invoke(invocation);
+
+        Context context = ContextUtil.getContext();
+        assertNotNull(context);
+    }
+
+    @Test
+    public void testInvokeSync() {
+
+        Invocation invocation = DubboTestUtil.getDefaultMockInvocationOne();
+        Invoker invoker = DubboTestUtil.getDefaultMockInvoker();
+
+        final Result result = mock(Result.class);
+        when(result.hasException()).thenReturn(false);
+        when(result.getException()).thenReturn(new Exception());
+        when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> {
+            verifyInvocationStructure(invoker, invocation);
+            return result;
+        });
+
+        consumerFilter.invoke(invoker, invocation);
+        verify(invoker).invoke(invocation);
+
+        Context context = ContextUtil.getContext();
+        assertNull(context);
+    }
+
+    /**
+     * Simply verify invocation structure in memory:
+     * EntranceNode(defaultContextName)
+     * --InterfaceNode(interfaceName)
+     * ----MethodNode(resourceName)
+     */
+    private void verifyInvocationStructure(Invoker invoker, Invocation invocation) {
+        Context context = ContextUtil.getContext();
+        assertNotNull(context);
+        // 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 = consumerFilter.getMethodName(invoker, invocation, null);
+        assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName());
+        assertEquals("", context.getOrigin());
+
+        DefaultNode entranceNode = context.getEntranceNode();
+        ResourceWrapper entranceResource = entranceNode.getId();
+
+        assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, entranceResource.getName());
+        assertSame(EntryType.IN, entranceResource.getEntryType());
+
+        // As SphU.entry(interfaceName, EntryType.OUT);
+        Set<Node> childList = entranceNode.getChildList();
+        assertEquals(1, childList.size());
+        DefaultNode interfaceNode = getNode(DubboUtils.getInterfaceName(invoker), entranceNode);
+        ResourceWrapper interfaceResource = interfaceNode.getId();
+
+        assertEquals(DubboUtils.getInterfaceName(invoker), interfaceResource.getName());
+        assertSame(EntryType.OUT, interfaceResource.getEntryType());
+
+        // As SphU.entry(resourceName, EntryType.OUT);
+        childList = interfaceNode.getChildList();
+        assertEquals(1, childList.size());
+        DefaultNode methodNode = getNode(resourceName, entranceNode);
+        ResourceWrapper methodResource = methodNode.getId();
+        assertEquals(resourceName, methodResource.getName());
+        assertSame(EntryType.OUT, methodResource.getEntryType());
+
+        // Verify curEntry
+        Entry curEntry = context.getCurEntry();
+        assertSame(methodNode, curEntry.getCurNode());
+        assertSame(interfaceNode, curEntry.getLastNode());
+        assertNull(curEntry.getOriginNode());// As context origin is not "", no originNode should be created in curEntry
+
+        // Verify clusterNode
+        ClusterNode methodClusterNode = methodNode.getClusterNode();
+        ClusterNode interfaceClusterNode = interfaceNode.getClusterNode();
+        assertNotSame(methodClusterNode,
+            interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode
+
+        // As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode
+        Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
+        assertEquals(0, methodOriginCountMap.size());
+
+        Map<String, StatisticNode> interfaceOriginCountMap = interfaceClusterNode.getOriginCountMap();
+        assertEquals(0, interfaceOriginCountMap.size());
+    }
+
+    private void verifyInvocationStructureForAsyncCall(Invoker invoker, Invocation invocation) {
+        Context context = ContextUtil.getContext();
+        assertNotNull(context);
+
+        // 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 = consumerFilter.getMethodName(invoker, invocation, null);
+        assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, context.getName());
+        assertEquals("", context.getOrigin());
+
+        DefaultNode entranceNode = context.getEntranceNode();
+        ResourceWrapper entranceResource = entranceNode.getId();
+        assertEquals(com.alibaba.csp.sentinel.Constants.CONTEXT_DEFAULT_NAME, entranceResource.getName());
+        assertSame(EntryType.IN, entranceResource.getEntryType());
+
+        // As SphU.entry(interfaceName, EntryType.OUT);
+        Set<Node> childList = entranceNode.getChildList();
+        assertEquals(2, childList.size());
+        DefaultNode interfaceNode = getNode(DubboUtils.getInterfaceName(invoker), entranceNode);
+        ResourceWrapper interfaceResource = interfaceNode.getId();
+        assertEquals(DubboUtils.getInterfaceName(invoker), interfaceResource.getName());
+        assertSame(EntryType.OUT, interfaceResource.getEntryType());
+
+        // As SphU.entry(resourceName, EntryType.OUT);
+        childList = interfaceNode.getChildList();
+        assertEquals(0, childList.size());
+        DefaultNode methodNode = getNode(resourceName, entranceNode);
+        ResourceWrapper methodResource = methodNode.getId();
+        assertEquals(resourceName, methodResource.getName());
+        assertSame(EntryType.OUT, methodResource.getEntryType());
+
+        // Verify curEntry
+        // nothing will bind to local context when use the AsyncEntry
+        Entry curEntry = context.getCurEntry();
+        assertNull(curEntry);
+
+        // Verify clusterNode
+        ClusterNode methodClusterNode = methodNode.getClusterNode();
+        ClusterNode interfaceClusterNode = interfaceNode.getClusterNode();
+        assertNotSame(methodClusterNode,
+            interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode
+
+        // As context origin is "", the StatisticNode should not be created in originCountMap of ClusterNode
+        Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
+        assertEquals(0, methodOriginCountMap.size());
+
+        Map<String, StatisticNode> interfaceOriginCountMap = interfaceClusterNode.getOriginCountMap();
+        assertEquals(0, interfaceOriginCountMap.size());
+    }
+
+    private void verifyInvocationStructureForCallFinish(Invoker invoker, Invocation invocation) {
+        Context context = ContextUtil.getContext();
+        assertNull(context);
+        String methodResourceName = consumerFilter.getMethodName(invoker, invocation, null);
+        Entry[] entries = (Entry[]) RpcContext.getContext().get(methodResourceName);
+        assertNull(entries);
+    }
+
+    private DefaultNode getNode(String resourceName, DefaultNode root) {
+
+        Queue<DefaultNode> queue = new LinkedList<>();
+        queue.offer(root);
+        while (!queue.isEmpty()) {
+            DefaultNode temp = queue.poll();
+            if (temp.getId().getName().equals(resourceName)) {
+                return temp;
+            }
+            for (Node node : temp.getChildList()) {
+                queue.offer((DefaultNode) node);
+            }
+        }
+        return null;
+    }
+
+    private void initFlowRule(String resource) {
+        FlowRule flowRule = new FlowRule(resource);
+        flowRule.setCount(1);
+        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
+        List<FlowRule> flowRules = new ArrayList<>();
+        flowRules.add(flowRule);
+        FlowRuleManager.loadRules(flowRules);
+    }
+
+    private void initDegradeRule(String resource) {
+        DegradeRule degradeRule = new DegradeRule(resource)
+            .setCount(0.5)
+            .setGrade(DEGRADE_GRADE_EXCEPTION_RATIO);
+        List<DegradeRule> degradeRules = new ArrayList<>();
+        degradeRules.add(degradeRule);
+        degradeRule.setTimeWindow(1);
+        DegradeRuleManager.loadRules(degradeRules);
+    }
+
+    private void initFallback() {
+        DubboAdapterGlobalConfig.setConsumerFallback((invoker, invocation, ex) -> {
+            // boolean async = RpcUtils.isAsync(invoker.getUrl(), invocation);
+            return AsyncRpcResult.newDefaultAsyncResult("fallback", invocation);
+        });
+    }
+
+    private Result invokeDubboRpc(boolean exception, Invoker invoker, Invocation invocation) {
+        Result result = null;
+        InvokeMode invokeMode = RpcUtils.getInvokeMode(invoker.getUrl(), invocation);
+        if (InvokeMode.SYNC == invokeMode) {
+            result = exception ? new AppResponse(new Exception("error")) : new AppResponse("normal");
+        } else {
+            result = exception ? AsyncRpcResult.newDefaultAsyncResult(new Exception("error"), invocation)
+                : AsyncRpcResult.newDefaultAsyncResult("normal", invocation);
+        }
+        when(invoker.invoke(invocation)).thenReturn(result);
+        return consumerFilter.invoke(invoker, invocation);
+    }
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboProviderFilterTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboProviderFilterTest.java
new file mode 100644
index 00000000..d90cdc45
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelDubboProviderFilterTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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.dubbo3;
+
+import com.alibaba.csp.sentinel.BaseTest;
+import com.alibaba.csp.sentinel.DubboTestUtil;
+import com.alibaba.csp.sentinel.Entry;
+import com.alibaba.csp.sentinel.EntryType;
+import com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService;
+import com.alibaba.csp.sentinel.context.Context;
+import com.alibaba.csp.sentinel.context.ContextUtil;
+import com.alibaba.csp.sentinel.node.ClusterNode;
+import com.alibaba.csp.sentinel.node.DefaultNode;
+import com.alibaba.csp.sentinel.node.Node;
+import com.alibaba.csp.sentinel.node.StatisticNode;
+import com.alibaba.csp.sentinel.slotchain.ResourceWrapper;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+/**
+ * @author cdfive
+ * @author lianglin
+ */
+public class SentinelDubboProviderFilterTest extends BaseTest {
+
+
+    private SentinelDubboProviderFilter filter = new SentinelDubboProviderFilter();
+
+
+    @Before
+    public void setUp() {
+        cleanUpAll();
+    }
+
+    @After
+    public void destroy() {
+        cleanUpAll();
+    }
+
+    @Test
+    public void testInvoke() {
+
+        final String originApplication = "consumerA";
+
+        URL url = DubboTestUtil.getDefaultTestURL();
+        url = url.addParameter(CommonConstants.SIDE_KEY, CommonConstants.PROVIDER_SIDE);
+        Invoker invoker = DubboTestUtil.getMockInvoker(url, DemoService.class);
+
+        Invocation invocation = DubboTestUtil.getMockInvocation(DemoService.class.getMethods()[0]);
+        when(invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, ""))
+                .thenReturn(originApplication);
+
+        final Result result = mock(Result.class);
+        when(result.hasException()).thenReturn(false);
+        when(result.getException()).thenReturn(new Exception());
+
+        when(invoker.invoke(invocation)).thenAnswer(invocationOnMock -> {
+            verifyInvocationStructure(originApplication, invoker, invocation);
+            return result;
+        });
+
+        filter.invoke(invoker, invocation);
+        verify(invoker).invoke(invocation);
+
+        Context context = ContextUtil.getContext();
+        assertNull(context);
+    }
+
+    /**
+     * Simply verify invocation structure in memory:
+     * EntranceNode(methodResourceName)
+     * --InterfaceNode(interfaceName)
+     * ----MethodNode(methodResourceName)
+     */
+    private void verifyInvocationStructure(String originApplication, Invoker invoker, Invocation invocation) {
+        Context context = ContextUtil.getContext();
+        assertNotNull(context);
+
+        // As ContextUtil.enter(resourceName, application) in SentinelDubboProviderFilter
+        String methodResourceName = filter.getMethodName(invoker, invocation, null);
+        assertEquals(methodResourceName, context.getName());
+        assertEquals(originApplication, context.getOrigin());
+
+        DefaultNode entranceNode = context.getEntranceNode();
+        ResourceWrapper entranceResource = entranceNode.getId();
+        assertEquals(methodResourceName, entranceResource.getName());
+        assertSame(EntryType.IN, entranceResource.getEntryType());
+
+        // As SphU.entry(interfaceName, EntryType.IN);
+        Set<Node> childList = entranceNode.getChildList();
+        assertEquals(1, childList.size());
+        DefaultNode interfaceNode = (DefaultNode) childList.iterator().next();
+        ResourceWrapper interfaceResource = interfaceNode.getId();
+
+        assertEquals(filter.getInterfaceName(invoker, null), interfaceResource.getName());
+        assertSame(EntryType.IN, interfaceResource.getEntryType());
+
+        // As SphU.entry(resourceName, EntryType.IN, 1, invocation.getArguments());
+        childList = interfaceNode.getChildList();
+        assertEquals(1, childList.size());
+        DefaultNode methodNode = (DefaultNode) childList.iterator().next();
+        ResourceWrapper methodResource = methodNode.getId();
+        assertEquals(methodResourceName, methodResource.getName());
+        assertSame(EntryType.IN, methodResource.getEntryType());
+
+        // Verify curEntry
+        Entry curEntry = context.getCurEntry();
+        assertSame(methodNode, curEntry.getCurNode());
+        assertSame(interfaceNode, curEntry.getLastNode());
+        assertNotNull(curEntry.getOriginNode());// As context origin is not "", originNode should be created
+
+        // Verify clusterNode
+        ClusterNode methodClusterNode = methodNode.getClusterNode();
+        ClusterNode interfaceClusterNode = interfaceNode.getClusterNode();
+        assertNotSame(methodClusterNode, interfaceClusterNode);// Different resource->Different ProcessorSlot->Different ClusterNode
+
+        // As context origin is not "", the StatisticNode should be created in originCountMap of ClusterNode
+        Map<String, StatisticNode> methodOriginCountMap = methodClusterNode.getOriginCountMap();
+        assertEquals(1, methodOriginCountMap.size());
+        assertTrue(methodOriginCountMap.containsKey(originApplication));
+
+        Map<String, StatisticNode> interfaceOriginCountMap = interfaceClusterNode.getOriginCountMap();
+        assertEquals(1, interfaceOriginCountMap.size());
+        assertTrue(interfaceOriginCountMap.containsKey(originApplication));
+    }
+
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelFilterTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelFilterTest.java
new file mode 100644
index 00000000..ea69e7b5
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/SentinelFilterTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.dubbo3;
+
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.ModuleModel;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Set;
+
+public class SentinelFilterTest {
+    @Test
+    public void test() {
+        ApplicationModel applicationModel = FrameworkModel.defaultModel().newApplication();
+        ModuleModel moduleModel = applicationModel.newModule();
+        Set<Filter> filters = moduleModel.getExtensionLoader(Filter.class).getSupportedExtensionInstances();
+        Assert.assertTrue(filters.stream().anyMatch(f -> f instanceof SentinelDubboProviderFilter));
+
+        Set<ClusterFilter> clusterFilters = moduleModel.getExtensionLoader(ClusterFilter.class).getSupportedExtensionInstances();
+        Assert.assertTrue(clusterFilters.stream().anyMatch(f -> f instanceof DubboAppContextFilter));
+        Assert.assertTrue(clusterFilters.stream().anyMatch(f -> f instanceof SentinelDubboConsumerFilter));
+
+        applicationModel.destroy();
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallbackRegistryTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallbackRegistryTest.java
new file mode 100644
index 00000000..67286f4d
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/fallback/DubboFallbackRegistryTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.dubbo3.fallback;
+
+import com.alibaba.csp.sentinel.DubboTestUtil;
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.csp.sentinel.slots.block.BlockException;
+import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
+
+import org.apache.dubbo.rpc.AsyncRpcResult;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+
+/**
+ * @author Eric Zhao
+ */
+public class DubboFallbackRegistryTest {
+
+    @Before
+    public void setUp() {
+        DubboAdapterGlobalConfig.setConsumerFallback(new DefaultDubboFallback());
+    }
+
+    @After
+    public void tearDown() {
+        DubboAdapterGlobalConfig.setConsumerFallback(new DefaultDubboFallback());
+    }
+
+    @Test
+    public void testDefaultFallback() {
+        // Test for default fallback.
+        BlockException ex = new FlowException("xxx");
+        Result result = new DefaultDubboFallback().handle(null, mock(RpcInvocation.class), ex);
+        Assert.assertTrue("The result should carry exception", result.hasException());
+        Assert.assertTrue(BlockException.isBlockException(result.getException()));
+        Assert.assertTrue(result.getException().getMessage().contains(ex.getClass().getSimpleName()));
+    }
+
+    @Test
+    public void testCustomFallback() {
+        BlockException ex = new FlowException("xxx");
+        DubboAdapterGlobalConfig.setConsumerFallback(
+            (invoker, invocation, e) -> AsyncRpcResult
+                .newDefaultAsyncResult("Error: " + e.getClass().getName(), invocation));
+        Result result = DubboAdapterGlobalConfig.getConsumerFallback()
+            .handle(null, mock(RpcInvocation.class), ex);
+        Assert.assertFalse("The invocation should not fail", result.hasException());
+        Assert.assertEquals("Error: " + ex.getClass().getName(), result.getValue());
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DubboOriginRegistryTest.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DubboOriginRegistryTest.java
new file mode 100644
index 00000000..10b24557
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/origin/DubboOriginRegistryTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.dubbo3.origin;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.DubboUtils;
+import com.alibaba.csp.sentinel.adapter.dubbo3.config.DubboAdapterGlobalConfig;
+import com.alibaba.dubbo.rpc.RpcInvocation;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * @author tiecheng
+ */
+public class DubboOriginRegistryTest {
+
+    @After
+    public void cleanUp() {
+        DubboAdapterGlobalConfig.setOriginParser(new DefaultDubboOriginParser());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testDefaultOriginParserFail() {
+        DubboAdapterGlobalConfig.getOriginParser().parse(null, null);
+    }
+
+    @Test
+    public void testDefaultOriginParserSuccess() {
+        RpcInvocation invocation = new RpcInvocation();
+        String dubboName = "sentinel";
+        invocation.setAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, dubboName);
+        String origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
+        Assert.assertEquals(dubboName, origin);
+    }
+
+    @Test
+    public void testCustomOriginParser() {
+        DubboAdapterGlobalConfig.setOriginParser(new DubboOriginParser() {
+            @Override
+            public String parse(Invoker<?> invoker, Invocation invocation) {
+                return invocation.getAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, "default") + "_" + invocation
+                        .getMethodName();
+            }
+        });
+
+        RpcInvocation invocation = new RpcInvocation();
+        String origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
+        Assert.assertEquals("default_null", origin);
+
+        String dubboName = "sentinel";
+        invocation.setAttachment(DubboUtils.SENTINEL_DUBBO_APPLICATION_KEY, dubboName);
+        origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
+        Assert.assertEquals(dubboName + "_null", origin);
+
+        invocation.setMethodName("hello");
+        origin = DubboAdapterGlobalConfig.getOriginParser().parse(null, invocation);
+        Assert.assertEquals(dubboName + "_hello", origin);
+    }
+
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/provider/DemoService.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/provider/DemoService.java
new file mode 100644
index 00000000..abc4c351
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/provider/DemoService.java
@@ -0,0 +1,24 @@
+/*
+ * 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.dubbo3.provider;
+
+/**
+ * @author leyou
+ */
+public interface DemoService {
+    String sayHello(String name, int n);
+    String sayHi(String name,int n);
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/provider/impl/DemoServiceImpl.java b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/provider/impl/DemoServiceImpl.java
new file mode 100644
index 00000000..54cdf1c2
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/java/com/alibaba/csp/sentinel/adapter/dubbo3/provider/impl/DemoServiceImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.dubbo3.provider.impl;
+
+import com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService;
+
+/**
+ * @author leyou
+ */
+public class DemoServiceImpl implements DemoService {
+    public String sayHello(String name, int n) {
+        return "Hello " + name + ", " + n;
+    }
+
+    @Override
+    public String sayHi(String name, int n) {
+        return "Hi " + name + ", " + n;
+    }
+}
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/resources/spring-dubbo-consumer-filter.xml b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/resources/spring-dubbo-consumer-filter.xml
new file mode 100755
index 00000000..69acd68c
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/resources/spring-dubbo-consumer-filter.xml
@@ -0,0 +1,18 @@
+<?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.dubbo3.provider.DemoService" ref="demoServiceImp" />
+    <bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo3.provider.impl.DemoServiceImpl"/>
+
+    <dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService"/>
+
+</beans>
\ No newline at end of file
diff --git a/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/resources/spring-dubbo-provider-filter.xml b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/resources/spring-dubbo-provider-filter.xml
new file mode 100755
index 00000000..b80f486f
--- /dev/null
+++ b/sentinel-adapter/sentinel-apache-dubbo3-adapter/src/test/resources/spring-dubbo-provider-filter.xml
@@ -0,0 +1,18 @@
+<?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.dubbo3.provider.DemoService" ref="demoServiceImp" />
+    <bean id="demoServiceImp" class="com.alibaba.csp.sentinel.adapter.dubbo3.provider.impl.DemoServiceImpl"/>
+
+    <dubbo:reference id="demoService" interface="com.alibaba.csp.sentinel.adapter.dubbo3.provider.DemoService"/>
+
+</beans>
\ No newline at end of file
diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilderTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilderTest.java
index ecdea6da..489843f1 100644
--- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilderTest.java
+++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/DefaultSlotChainBuilderTest.java
@@ -18,6 +18,7 @@ package com.alibaba.csp.sentinel.slots;
 import com.alibaba.csp.sentinel.slotchain.AbstractLinkedProcessorSlot;
 import com.alibaba.csp.sentinel.slotchain.ProcessorSlotChain;
 import com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot;
+import com.alibaba.csp.sentinel.slots.block.degrade.DefaultDegradeSlot;
 import com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot;
 import com.alibaba.csp.sentinel.slots.block.flow.FlowSlot;
 import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
@@ -70,6 +71,9 @@ public class DefaultSlotChainBuilderTest {
         next = next.getNext();
         assertTrue(next instanceof DegradeSlot);
 
+        next = next.getNext();
+        assertTrue(next instanceof DefaultDegradeSlot);
+
         next = next.getNext();
         assertNull(next);
 
diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java
index eb9dac79..0716f6e5 100755
--- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java
+++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/block/degrade/CircuitBreakingIntegrationTest.java
@@ -44,16 +44,17 @@ public class CircuitBreakingIntegrationTest extends AbstractTimeBasedTest {
 
     @Before
     public void setUp() {
-        DegradeRuleManager.loadRules(new ArrayList<DegradeRule>());
+        DegradeRuleManager.loadRules(new ArrayList<>());
     }
 
     @After
-    public void tearDown() throws Exception {
-        DegradeRuleManager.loadRules(new ArrayList<DegradeRule>());
+    public void tearDown() {
+        DegradeRuleManager.loadRules(new ArrayList<>());
+        DefaultDegradeRuleManager.loadRules(new ArrayList<>());
     }
 
     @Test
-    public void testSlowRequestMode() throws Exception {
+    public void testSlowRequestMode() {
         CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class);
         setCurrentMillis(System.currentTimeMillis() / 1000 * 1000);
         int retryTimeoutSec = 5;
@@ -115,7 +116,69 @@ public class CircuitBreakingIntegrationTest extends AbstractTimeBasedTest {
     }
 
     @Test
-    public void testExceptionRatioMode() throws Exception {
+    public void testSlowRequestModeUseDefaultRule() {
+        CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class);
+        setCurrentMillis(System.currentTimeMillis() / 1000 * 1000);
+        int retryTimeoutSec = 5;
+        int maxRt = 50;
+        int statIntervalMs = 20000;
+        int minRequestAmount = 10;
+        String res = "CircuitBreakingIntegrationTest_testSlowRequestModeUseDefaultRule";
+        EventObserverRegistry.getInstance().addStateChangeObserver(res, observer);
+
+        DefaultDegradeRuleManager.loadRules(Arrays.asList(
+                new DegradeRule(DefaultDegradeRuleManager.DEFAULT_KEY).setTimeWindow(retryTimeoutSec).setCount(maxRt)
+                        .setStatIntervalMs(statIntervalMs).setMinRequestAmount(minRequestAmount)
+                        .setSlowRatioThreshold(0.8d).setGrade(0)));
+
+        // Try first N requests where N = minRequestAmount.
+        for (int i = 0; i < minRequestAmount; i++) {
+            if (i < 7) {
+                assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+            } else {
+                assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(-20, -10)));
+            }
+        }
+
+        // Till now slow ratio should be 70%.
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+        // Circuit breaker has transformed to OPEN since here.
+        verify(observer)
+                .onStateChange(eq(State.CLOSED), eq(State.OPEN), any(DegradeRule.class), anyDouble());
+        assertEquals(State.OPEN, DefaultDegradeRuleManager.getDefaultCircuitBreakers(res).get(0).currentState());
+        assertFalse(entryAndSleepFor(res, 1));
+
+        sleepSecond(1);
+        assertFalse(entryAndSleepFor(res, 1));
+        sleepSecond(retryTimeoutSec);
+        // Test HALF-OPEN to OPEN.
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+
+        verify(observer)
+                .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class));
+        verify(observer)
+                .onStateChange(eq(State.HALF_OPEN), eq(State.OPEN), any(DegradeRule.class), anyDouble());
+        // Wait for next retry timeout;
+        reset(observer);
+        sleepSecond(retryTimeoutSec + 1);
+        assertTrue(entryAndSleepFor(res, maxRt - ThreadLocalRandom.current().nextInt(10, 20)));
+        verify(observer)
+                .onStateChange(eq(State.OPEN), eq(State.HALF_OPEN), any(DegradeRule.class), nullable(Double.class));
+        verify(observer)
+                .onStateChange(eq(State.HALF_OPEN), eq(State.CLOSED), any(DegradeRule.class), nullable(Double.class));
+        // Now circuit breaker has been closed.
+        assertTrue(entryAndSleepFor(res, maxRt + ThreadLocalRandom.current().nextInt(10, 20)));
+
+        EventObserverRegistry.getInstance().removeStateChangeObserver(res);
+    }
+
+    @Test
+    public void testExceptionRatioMode() {
         CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class);
         setCurrentMillis(System.currentTimeMillis() / 1000 * 1000);
         int retryTimeoutSec = 5;
@@ -169,7 +232,7 @@ public class CircuitBreakingIntegrationTest extends AbstractTimeBasedTest {
     }
 
     @Test
-    public void testExceptionCountMode() throws Throwable {
+    public void testExceptionCountMode() {
         // TODO
     }
     
@@ -188,7 +251,7 @@ public class CircuitBreakingIntegrationTest extends AbstractTimeBasedTest {
     }
     
     @Test
-    public void testMultipleHalfOpenedBreakers() throws Exception {
+    public void testMultipleHalfOpenedBreakers() {
         CircuitBreakerStateChangeObserver observer = mock(CircuitBreakerStateChangeObserver.class);
         setCurrentMillis(System.currentTimeMillis() / 1000 * 1000);
         int retryTimeoutSec = 2;
diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java
index 8a48bc7c..236780b8 100644
--- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java
+++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/slots/logger/EagleEyeLogUtilTest.java
@@ -19,7 +19,7 @@ public class EagleEyeLogUtilTest {
 
     @Test
     public void testWriteLog() throws Exception {
-        EagleEyeLogUtil.log("resourceName", "BlockException", "app1", "origin", 1);
+        EagleEyeLogUtil.log("resourceName", "BlockException", "app1", "origin", 1L,1);
 
         final File file = new File(LogBase.getLogBaseDir() + EagleEyeLogUtil.FILE_NAME);
         await().timeout(2, TimeUnit.SECONDS)
@@ -39,7 +39,7 @@ public class EagleEyeLogUtilTest {
         String newLogBase = userHome + File.separator + "tmpLogDir" + System.currentTimeMillis();
         System.setProperty(LogBase.LOG_DIR, newLogBase);
 
-        EagleEyeLogUtil.log("resourceName", "BlockException", "app1", "origin", 1);
+        EagleEyeLogUtil.log("resourceName", "BlockException", "app1", "origin", 2L,1);
 
 
         final File file = new File(LogBase.getLogBaseDir() + EagleEyeLogUtil.FILE_NAME);
diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/spi/SpiLoaderTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/spi/SpiLoaderTest.java
index 7eb8f13e..6fde7524 100644
--- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/spi/SpiLoaderTest.java
+++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/spi/SpiLoaderTest.java
@@ -22,6 +22,7 @@ import com.alibaba.csp.sentinel.slotchain.ProcessorSlot;
 import com.alibaba.csp.sentinel.slotchain.SlotChainBuilder;
 import com.alibaba.csp.sentinel.slots.DefaultSlotChainBuilder;
 import com.alibaba.csp.sentinel.slots.block.authority.AuthoritySlot;
+import com.alibaba.csp.sentinel.slots.block.degrade.DefaultDegradeSlot;
 import com.alibaba.csp.sentinel.slots.block.degrade.DegradeSlot;
 import com.alibaba.csp.sentinel.slots.block.flow.FlowSlot;
 import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot;
@@ -98,13 +99,14 @@ public class SpiLoaderTest {
         prototypeSlotClasses.add(NodeSelectorSlot.class);
         prototypeSlotClasses.add(ClusterBuilderSlot.class);
 
-        List<Class<? extends ProcessorSlot>> singletonSlotClasses = new ArrayList<>(6);
+        List<Class<? extends ProcessorSlot>> singletonSlotClasses = new ArrayList<>(7);
         singletonSlotClasses.add(LogSlot.class);
         singletonSlotClasses.add(StatisticSlot.class);
         singletonSlotClasses.add(AuthoritySlot.class);
         singletonSlotClasses.add(SystemSlot.class);
         singletonSlotClasses.add(FlowSlot.class);
         singletonSlotClasses.add(DegradeSlot.class);
+        singletonSlotClasses.add(DefaultDegradeSlot.class);
 
         for (int i = 0; i < slots1.size(); i++) {
             ProcessorSlot slot1 = slots1.get(i);
@@ -148,7 +150,7 @@ public class SpiLoaderTest {
         assertNotNull(sortedSlots);
 
         // Total 8 default slot in sentinel-core
-        assertEquals(8, sortedSlots.size());
+        assertEquals(9, sortedSlots.size());
 
         // Verify the order of slot
         int index = 0;
@@ -160,6 +162,7 @@ public class SpiLoaderTest {
         assertTrue(sortedSlots.get(index++) instanceof SystemSlot);
         assertTrue(sortedSlots.get(index++) instanceof FlowSlot);
         assertTrue(sortedSlots.get(index++) instanceof DegradeSlot);
+        assertTrue(sortedSlots.get(index++) instanceof DefaultDegradeSlot);
     }
 
     @Test
@@ -177,7 +180,7 @@ public class SpiLoaderTest {
         assertNotNull(slot);
 
         // NodeSelectorSlot is lowest order priority with @Spi(order = -1000) among all slots
-        assertTrue(slot instanceof DegradeSlot);
+        assertTrue(slot instanceof DefaultDegradeSlot);
     }
 
     @Test