进一步完善 Dubbo 路由封装

This commit is contained in:
YunaiV
2020-07-22 07:26:09 +08:00
parent 92c2d79dc1
commit 8edc49f4e7
29 changed files with 122 additions and 36 deletions

View File

@@ -1,4 +1,4 @@
package cn.iocoder.common.framework.util;
package cn.iocoder.common.framework.exception.util;
import cn.iocoder.common.framework.exception.ErrorCode;
import cn.iocoder.common.framework.exception.ServiceException;

View File

@@ -0,0 +1,14 @@
package cn.iocoder.common.framework.util;
import cn.hutool.system.SystemUtil;
/**
* 操作系统工具类
*/
public class OSUtils {
public static String getHostName() {
return SystemUtil.getHostInfo().getName();
}
}

View File

@@ -0,0 +1,66 @@
package cn.iocoder.mall.dubbo.config;
import cn.iocoder.common.framework.util.OSUtils;
import cn.iocoder.common.framework.util.StringUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.Map;
/**
* Dubbo 配置项的后置处理器,主要目的如下:
*
* 1. 生成 {@link #DUBBO_TAG_PROPERTIES_KEY} 配置项,可用于本地开发环境下的 dubbo.provider.tag 配置项
*/
public class DubboEnvironmentPostProcessor implements EnvironmentPostProcessor {
/**
* 默认配置项的 PropertySource 名字
*/
private static final String PROPERTY_SOURCE_NAME = "mallDubboProperties";
/**
* Dubbo 路由标签属性 KEY
*/
private static final String DUBBO_TAG_PROPERTIES_KEY = "DUBBO_TAG";
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
// 需要修改的配置项
Map<String, Object> modifyProperties = new HashMap<>();
// 生成 DUBBO_TAG_PROPERTIES_KEY使用 hostname
String dubboTag = OSUtils.getHostName();
if (!StringUtils.hasText(dubboTag)) {
dubboTag = StringUtils.uuid(true); // 兜底,强行生成一个
}
modifyProperties.put(DUBBO_TAG_PROPERTIES_KEY, dubboTag);
// 添加到 environment 中,排在最优,最低优先级
addOrReplace(environment.getPropertySources(), modifyProperties);
}
private void addOrReplace(MutablePropertySources propertySources, Map<String, Object> map) {
if (CollectionUtils.isEmpty(map)) {
return;
}
// 情况一,如果存在 defaultProperties 的 PropertySource则进行 key 的修改
if (propertySources.contains(PROPERTY_SOURCE_NAME)) {
PropertySource<?> source = propertySources.get(PROPERTY_SOURCE_NAME);
if (source instanceof MapPropertySource) {
MapPropertySource target = (MapPropertySource) source;
for (String key : map.keySet()) {
target.getSource().put(key, map.get(key));
}
}
return;
}
// 情况二,不存在 defaultProperties 的 PropertySource则直接添加到其中
propertySources.addLast(new MapPropertySource(PROPERTY_SOURCE_NAME, map));
}
}

View File

@@ -51,6 +51,7 @@ public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
appResponse.setValue(CommonResult.error((ServiceException) exception));
// 2.2 如果是 GlobalException 全局异常,则直接抛出
} else {
// TODO 优化点:尝试修改成 RpcException
appResponse.setException(exception);
}
} catch (Throwable e) {

View File

@@ -1,11 +1,10 @@
package cn.iocoder.mall.dubbo.core.web;
import cn.iocoder.common.framework.util.OSUtils;
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;
@@ -22,12 +21,18 @@ public class DubboRouterTagWebInterceptor implements HandlerInterceptor {
private static final String HEADER_DUBBO_TAG = "dubbo-tag";
private static final String HOST_NAME_VALUE = "${HOSTNAME}";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String tag = request.getHeader(HEADER_DUBBO_TAG);
if (StringUtils.hasText(tag)) {
// 特殊逻辑,解决 IDEA Rest Client 不支持环境变量的读取,所以就服务器来做
if (HOST_NAME_VALUE.equals(tag)) {
tag = OSUtils.getHostName();
}
// 设置到 DubboRouterTagContextHolder 上下文
DubboRouterTagContextHolder.setTag(tag);
RpcContext.getContext().setAttachment(CommonConstants.TAG_KEY, tag);
}
return true;
}

View File

@@ -1,2 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.mall.dubbo.config.DubboWebAutoConfiguration
org.springframework.boot.env.EnvironmentPostProcessor=\
cn.iocoder.mall.dubbo.config.DubboEnvironmentPostProcessor

View File

@@ -1,6 +1,6 @@
package cn.iocoder.mall.security.admin.core.interceptor;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.mall.security.admin.core.context.AdminSecurityContextHolder;
import cn.iocoder.mall.systemservice.enums.SystemErrorCodeConstants;
import org.springframework.http.HttpMethod;

View File

@@ -4,7 +4,7 @@ import cn.iocoder.common.framework.enums.UserTypeEnum;
import cn.iocoder.common.framework.exception.GlobalException;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.common.framework.util.HttpUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.security.admin.core.context.AdminSecurityContext;
import cn.iocoder.mall.security.admin.core.context.AdminSecurityContextHolder;

View File

@@ -3,7 +3,7 @@ package cn.iocoder.mall.security.user.core.interceptor;
import cn.iocoder.common.framework.exception.enums.GlobalErrorCodeEnum;
import cn.iocoder.common.framework.enums.UserTypeEnum;
import cn.iocoder.common.framework.util.HttpUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.security.user.core.context.UserSecurityContext;
import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder;

View File

@@ -2,7 +2,7 @@ package cn.iocoder.mall.system.errorcode.core;
import cn.iocoder.common.framework.util.CollectionUtils;
import cn.iocoder.common.framework.util.DateUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.systemservice.rpc.errorcode.ErrorCodeRpc;
import cn.iocoder.mall.systemservice.rpc.errorcode.vo.ErrorCodeVO;