From 92c2d79dc1ffef143149510eb685e64ba9f984bc Mon Sep 17 00:00:00 2001
From: YunaiV <>
Date: Tue, 21 Jul 2020 19:45:58 +0800
Subject: [PATCH] =?UTF-8?q?1.=20=E9=87=8D=E6=96=B0=E5=AE=9E=E7=8E=B0=20Dub?=
=?UTF-8?q?bo=20=E8=B7=AF=E7=94=B1=E7=9A=84=E8=BF=87=E6=BB=A4=E5=99=A8?=
=?UTF-8?q?=EF=BC=8C=E4=B9=8B=E5=89=8D=E7=9A=84=E7=89=88=E6=9C=AC=E6=9C=89?=
=?UTF-8?q?=E9=97=AE=E9=A2=98=202.=20Spring=20Cloud=20Alibaba=20Dubbo=20?=
=?UTF-8?q?=E7=9A=84=20URL=20=E5=A4=84=E7=90=86=E6=9C=89=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=EF=BC=8C=E5=88=87=E5=9B=9E=E5=88=B0=20Dubbo=20=E5=8E=9F?=
=?UTF-8?q?=E7=94=9F=E6=B3=A8=E5=86=8C=E4=B8=AD=E5=BF=83=EF=BC=8C=E4=B8=8D?=
=?UTF-8?q?=E4=BD=BF=E7=94=A8=20Spring=20Cloud=20=E6=B3=A8=E5=86=8C?=
=?UTF-8?q?=E4=B8=AD=E5=BF=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
common/mall-spring-boot-starter-dubbo/pom.xml | 10 ++-
.../config/DubboWebAutoConfiguration.java | 8 ++-
...boConsumerRouterTagClusterInterceptor.java | 37 +++++++++++
.../filter/DubboProviderRouterTagFilter.java | 44 +++++++++++++
.../core/filter/DubboRouterTagFilter.java | 62 -------------------
.../router/DubboRouterTagContextHolder.java | 4 +-
.../web/DubboRouterTagWebInterceptor.java | 8 ++-
.../dubbo/com.alibaba.dubbo.rpc.Filter | 2 +-
...rpc.cluster.interceptor.ClusterInterceptor | 1 +
mall-dependencies/pom.xml | 2 +-
.../src/main/resources/application-local.yml | 8 ++-
.../SystemServiceApplication.java | 4 +-
.../src/main/resources/application-local.yaml | 3 +-
13 files changed, 121 insertions(+), 72 deletions(-)
create mode 100644 common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/cluster/interceptor/DubboConsumerRouterTagClusterInterceptor.java
create mode 100644 common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboProviderRouterTagFilter.java
delete mode 100644 common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboRouterTagFilter.java
create mode 100644 common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor
diff --git a/common/mall-spring-boot-starter-dubbo/pom.xml b/common/mall-spring-boot-starter-dubbo/pom.xml
index 6fc1417d7..31acd196e 100644
--- a/common/mall-spring-boot-starter-dubbo/pom.xml
+++ b/common/mall-spring-boot-starter-dubbo/pom.xml
@@ -26,9 +26,15 @@
+
+
+
+
+
+
- com.alibaba.cloud
- spring-cloud-starter-dubbo
+ org.apache.dubbo
+ dubbo-spring-boot-starter
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboWebAutoConfiguration.java b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboWebAutoConfiguration.java
index 7d6c9757a..92fbbd9cd 100644
--- a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboWebAutoConfiguration.java
+++ b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/config/DubboWebAutoConfiguration.java
@@ -1,6 +1,8 @@
package cn.iocoder.mall.dubbo.config;
import cn.iocoder.mall.dubbo.core.web.DubboRouterTagWebInterceptor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
@@ -11,14 +13,18 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class DubboWebAutoConfiguration implements WebMvcConfigurer {
+ private Logger logger = LoggerFactory.getLogger(DubboWebAutoConfiguration.class);
+
// ========== 拦截器相关 ==========
@Override
public void addInterceptors(InterceptorRegistry registry) {
try {
+ // 设置为 -1000 的原因,保证在比较前面就处理该逻辑。例如说,认证拦截器;
registry.addInterceptor(new DubboRouterTagWebInterceptor()).order(-1000);
+ logger.info("[addInterceptors][加载 DubboRouterTagWebInterceptor 拦截器完成]");
} catch (NoSuchBeanDefinitionException e) {
-// logger.warn("[addInterceptors][无法获取 AccessLogInterceptor 拦截器,因此不启动 AccessLog 的记录]");
+ logger.warn("[addInterceptors][无法获取 DubboRouterTagWebInterceptor 拦截器,无法使用 Dubbo 标签路由]");
}
}
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/cluster/interceptor/DubboConsumerRouterTagClusterInterceptor.java b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/cluster/interceptor/DubboConsumerRouterTagClusterInterceptor.java
new file mode 100644
index 000000000..4991f0da2
--- /dev/null
+++ b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/cluster/interceptor/DubboConsumerRouterTagClusterInterceptor.java
@@ -0,0 +1,37 @@
+package cn.iocoder.mall.dubbo.core.cluster.interceptor;
+
+import cn.iocoder.common.framework.util.StringUtils;
+import cn.iocoder.mall.dubbo.core.filter.DubboProviderRouterTagFilter;
+import cn.iocoder.mall.dubbo.core.router.DubboRouterTagContextHolder;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor;
+import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
+
+/**
+ * Consumer 方,在调用 Provider 时,将 {@link DubboRouterTagContextHolder} 中的 Tag 通过 Dubbo 隐式传参。
+ *
+ * 完整逻辑说明,见 {@link DubboProviderRouterTagFilter}
+ *
+ * 注意,这里需要设置到 order = 1 的原因,是需要保证排在 ConsumerContextClusterInterceptor 之后
+ */
+@Activate(group = CommonConstants.CONSUMER, order = 1)
+public class DubboConsumerRouterTagClusterInterceptor implements ClusterInterceptor {
+
+ @Override
+ public void before(AbstractClusterInvoker> clusterInvoker, Invocation invocation) {
+ // 设置 Dubbo Tag 到 Dubbo 隐式传参
+ String dubboTag = DubboRouterTagContextHolder.getTag();
+ if (StringUtils.hasText(dubboTag)) {
+ invocation.setAttachment(CommonConstants.TAG_KEY, dubboTag);
+ }
+ }
+
+ @Override
+ public void after(AbstractClusterInvoker> clusterInvoker, Invocation invocation) {
+ // 清空 Dubbo Tag 的隐式传参
+ invocation.setAttachment(CommonConstants.TAG_KEY, null);
+ }
+
+}
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboProviderRouterTagFilter.java b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboProviderRouterTagFilter.java
new file mode 100644
index 000000000..7051e16f8
--- /dev/null
+++ b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboProviderRouterTagFilter.java
@@ -0,0 +1,44 @@
+package cn.iocoder.mall.dubbo.core.filter;
+
+import cn.iocoder.common.framework.util.StringUtils;
+import cn.iocoder.mall.dubbo.core.cluster.interceptor.DubboConsumerRouterTagClusterInterceptor;
+import cn.iocoder.mall.dubbo.core.router.DubboRouterTagContextHolder;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.*;
+import org.apache.dubbo.rpc.cluster.router.tag.TagRouter;
+
+/**
+ * 基于 Dubbo 标签路由规则(http://dubbo.apache.org/zh-cn/docs/user/demos/routing-rule.html),实现如下功能:
+ * 1. 本地开发调试时,在带有 Dubbo Tag 的情况下,优先调用指定 Tag 的服务提供者。这样,我们可以将本地启动的服务提供者打上相应的 Tag,即可优先调用本地;
+ * 2. TODO 优化点:蓝绿发布、灰度发布
+ *
+ * 实现逻辑为:
+ * 1. 对于 Consumer 方,在调用 Provider 时,{@link DubboConsumerRouterTagClusterInterceptor} 会将 {@link DubboRouterTagContextHolder} 中的 Tag 通过 Dubbo 隐式传参。
+ * 同时,Dubbo 自带 {@link TagRouter},会根据该参数,会选择符合该 Tag 的 Provider。
+ * 2. 对于 Provider 方,在通过 Dubbo 隐式传参获得到 Tag 时,会设置到 {@link DubboRouterTagContextHolder} 中。
+ * 这样,在 Provider 作为 Consumer 角色时,调用其它 Provider 时,可以继续实现标签路由的功能。
+ */
+@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = -1000)
+public class DubboProviderRouterTagFilter implements Filter {
+
+ @Override
+ public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {
+ // 从 Dubbo 隐式传参获得 Dubbo Tag
+ String dubboTag = invocation.getAttachment(CommonConstants.TAG_KEY);
+ boolean hasDubboTag = StringUtils.hasText(dubboTag);
+ if (hasDubboTag) {
+ invocation.setAttachment(CommonConstants.TAG_KEY, dubboTag);
+ }
+ // 继续调用
+ try {
+ return invoker.invoke(invocation);
+ } finally {
+ // 清理
+ if (hasDubboTag) {
+ DubboRouterTagContextHolder.clear();
+ }
+ }
+ }
+
+}
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboRouterTagFilter.java b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboRouterTagFilter.java
deleted file mode 100644
index 002a332cc..000000000
--- a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/filter/DubboRouterTagFilter.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package cn.iocoder.mall.dubbo.core.filter;
-
-import cn.iocoder.common.framework.util.StringUtils;
-import cn.iocoder.mall.dubbo.core.router.DubboRouterTagContextHolder;
-import org.apache.dubbo.common.constants.CommonConstants;
-import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.rpc.*;
-
-/**
- * 基于 Dubbo 标签路由规则(http://dubbo.apache.org/zh-cn/docs/user/demos/routing-rule.html),实现如下功能:
- * 1. 本地开发调试时,在带有 Dubbo Tag 的情况下,优先调用指定 Tag 的服务提供者。这样,我们可以将本地启动的服务提供者打上相应的 Tag,即可优先调用本地;
- * 2. TODO 优化点:蓝绿发布、灰度发布
- *
- * 实现逻辑为:
- * 1. 对于 Consumer 方,在调用 Provider 时,会将 {@link DubboRouterTagContextHolder} 中的 Tag 通过 Dubbo 隐式传参。
- * 同时,Dubbo 自带 {@link org.apache.dubbo.rpc.cluster.router.tag.TagRouter},会根据该参数,会选择符合该 Tag 的 Provider。
- * 2. 对于 Provider 方,在通过 Dubbo 隐式传参获得到 Tag 时,会设置到 {@link DubboRouterTagContextHolder} 中。
- * 这样,在 Provider 作为 Consumer 角色时,调用其它 Provider 时,可以继续实现标签路由的功能。
- */
-@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = -1000)
-public class DubboRouterTagFilter implements Filter {
-
- @Override
- public Result invoke(Invoker> invoker, Invocation invocation) throws RpcException {
- // 消费端
- if (RpcContext.getContext().isConsumerSide()) {
- // 设置 Dubbo Tag 到 Dubbo 隐式传参
- String dubboTag = DubboRouterTagContextHolder.getTag();
- boolean hasDubboTag = StringUtils.hasText(dubboTag);
- if (hasDubboTag) {
- invocation.setAttachment(CommonConstants.TAG_KEY, dubboTag);
- }
- // 继续调用
- try {
- return invoker.invoke(invocation);
- } finally {
- // 解决极端情况下,本地 injvm 调用时,消费端会调用 DubboRouterTagContextHolder.clear() 上下文,导致消费端也被清理了,因为在同一个 JVM 进程内。
- if (hasDubboTag) {
- DubboRouterTagContextHolder.setTag(dubboTag);
- }
- }
- // 提供端
- } else {
- // 从 Dubbo 隐式传参获得 Dubbo Tag
- String dubboTag = invocation.getAttachment(CommonConstants.TAG_KEY);
- boolean hasDubboTag = StringUtils.hasText(dubboTag);
- if (hasDubboTag) {
- invocation.setAttachment(CommonConstants.TAG_KEY, dubboTag);
- }
- // 继续调用
- try {
- return invoker.invoke(invocation);
- } finally {
- // 清理
- if (hasDubboTag) {
- DubboRouterTagContextHolder.clear();
- }
- }
- }
- }
-
-}
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/router/DubboRouterTagContextHolder.java b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/router/DubboRouterTagContextHolder.java
index c25bd1c2e..2a658b6b2 100644
--- a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/router/DubboRouterTagContextHolder.java
+++ b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/router/DubboRouterTagContextHolder.java
@@ -1,9 +1,11 @@
package cn.iocoder.mall.dubbo.core.router;
+import cn.iocoder.mall.dubbo.core.filter.DubboProviderRouterTagFilter;
+
/**
* Dubbo 路由 Tag 的上下文
*
- * @see cn.iocoder.mall.dubbo.core.filter.DubboRouterTagFilter
+ * @see DubboProviderRouterTagFilter
* @see cn.iocoder.mall.dubbo.core.web.DubboRouterTagWebInterceptor
*/
public class DubboRouterTagContextHolder {
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/web/DubboRouterTagWebInterceptor.java b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/web/DubboRouterTagWebInterceptor.java
index aab2363cb..c7ce62713 100644
--- a/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/web/DubboRouterTagWebInterceptor.java
+++ b/common/mall-spring-boot-starter-dubbo/src/main/java/cn/iocoder/mall/dubbo/core/web/DubboRouterTagWebInterceptor.java
@@ -1,7 +1,11 @@
package cn.iocoder.mall.dubbo.core.web;
import cn.iocoder.common.framework.util.StringUtils;
+import cn.iocoder.mall.dubbo.core.cluster.interceptor.DubboConsumerRouterTagClusterInterceptor;
+import cn.iocoder.mall.dubbo.core.filter.DubboProviderRouterTagFilter;
import cn.iocoder.mall.dubbo.core.router.DubboRouterTagContextHolder;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.rpc.RpcContext;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@@ -11,7 +15,8 @@ import javax.servlet.http.HttpServletResponse;
/**
* Dubbo 路由标签的 Web 拦截器,将请求 Header 中的 {@link #HEADER_DUBBO_TAG} 设置到 {@link DubboRouterTagContextHolder} 中。
*
- * @see cn.iocoder.mall.dubbo.core.filter.DubboRouterTagFilter
+ * @see DubboProviderRouterTagFilter
+ * @see DubboConsumerRouterTagClusterInterceptor
*/
public class DubboRouterTagWebInterceptor implements HandlerInterceptor {
@@ -22,6 +27,7 @@ public class DubboRouterTagWebInterceptor implements HandlerInterceptor {
String tag = request.getHeader(HEADER_DUBBO_TAG);
if (StringUtils.hasText(tag)) {
DubboRouterTagContextHolder.setTag(tag);
+ RpcContext.getContext().setAttachment(CommonConstants.TAG_KEY, tag);
}
return true;
}
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter b/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
index b1f85b26f..f81a93f70 100644
--- a/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
+++ b/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter
@@ -1,2 +1,2 @@
dubboExceptionFilter=cn.iocoder.mall.dubbo.core.filter.DubboProviderExceptionFilter
-dubboRouterTagFilter=cn.iocoder.mall.dubbo.core.filter.DubboRouterTagFilter
+dubboProviderRouterTagFilter=cn.iocoder.mall.dubbo.core.filter.DubboProviderRouterTagFilter
diff --git a/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor b/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor
new file mode 100644
index 000000000..bba113398
--- /dev/null
+++ b/common/mall-spring-boot-starter-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.interceptor.ClusterInterceptor
@@ -0,0 +1 @@
+dubboConsumerRouterTagClusterInterceptor=cn.iocoder.mall.dubbo.core.cluster.interceptor.DubboConsumerRouterTagClusterInterceptor
diff --git a/mall-dependencies/pom.xml b/mall-dependencies/pom.xml
index 78e5b952e..64255fcc6 100644
--- a/mall-dependencies/pom.xml
+++ b/mall-dependencies/pom.xml
@@ -41,7 +41,7 @@
3.1.1
3.2.5.RELEASE
- 2.7.6
+ 2.7.7
2.0.1
diff --git a/management-web-app/src/main/resources/application-local.yml b/management-web-app/src/main/resources/application-local.yml
index 2e9e99973..b03881072 100644
--- a/management-web-app/src/main/resources/application-local.yml
+++ b/management-web-app/src/main/resources/application-local.yml
@@ -11,4 +11,10 @@ spring:
dubbo:
# Dubbo 注册中心
registry:
- address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
+# address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
+# address: nacos://400-infra.server.iocoder.cn:8848?namespace=local # 指定 Dubbo 服务注册中心的地址
+ protocol: nacos
+ address: 400-infra.server.iocoder.cn:8848?namespace=local
+ timeout: 20000
+ register: true
+ subscribe: true
diff --git a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/SystemServiceApplication.java b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/SystemServiceApplication.java
index 13349c96a..7c1623bbb 100644
--- a/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/SystemServiceApplication.java
+++ b/system-service-project/system-service-app/src/main/java/cn/iocoder/mall/systemservice/SystemServiceApplication.java
@@ -2,12 +2,14 @@ package cn.iocoder.mall.systemservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class SystemServiceApplication {
public static void main(String[] args) {
- SpringApplication.run(SystemServiceApplication.class, args);
+ ConfigurableApplicationContext context = SpringApplication.run(SystemServiceApplication.class, args);
+ System.out.println(context);
}
}
diff --git a/system-service-project/system-service-app/src/main/resources/application-local.yaml b/system-service-project/system-service-app/src/main/resources/application-local.yaml
index bf97cae95..e15afd4d1 100644
--- a/system-service-project/system-service-app/src/main/resources/application-local.yaml
+++ b/system-service-project/system-service-app/src/main/resources/application-local.yaml
@@ -17,4 +17,5 @@ spring:
dubbo:
# Dubbo 注册中心
registry:
- address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
+# address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址
+ address: nacos://400-infra.server.iocoder.cn:8848?namespace=local # 指定 Dubbo 服务注册中心的地址