提交 3b91e9d9 编写于 作者: zlt2000's avatar zlt2000

优化租户、trace等数据传递方式,由拦截器改为过滤器

上级 dd0fe108
package com.central.common.config;
import com.central.common.constant.ConfigConstants;
import com.central.common.feign.UserService;
import com.central.common.interceptor.LbIsolationInterceptor;
import com.central.common.interceptor.TenantInterceptor;
import com.central.common.interceptor.TraceInterceptor;
import com.central.common.resolver.ClientArgumentResolver;
import com.central.common.resolver.TokenArgumentResolver;
import com.central.log.properties.TraceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
......@@ -29,33 +22,6 @@ public class DefaultWebMvcConfig extends WebMvcConfigurationSupport {
@Autowired
private UserService userService;
@Autowired
private TraceProperties traceProperties;
@Value("${" + ConfigConstants.CONFIG_RIBBON_ISOLATION_ENABLED + ":false}")
private boolean enableIsolation;
/**
* 配置SpringMVC拦截器,添加租户拦截器
*/
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//租户拦截器
registry.addInterceptor(new TenantInterceptor()).addPathPatterns("/**");
if (traceProperties.getEnable()) {
//日志链路追踪拦截器
registry.addInterceptor(new TraceInterceptor()).addPathPatterns("/**");
}
if (enableIsolation) {
//负债均衡隔离规则拦截器
registry.addInterceptor(new LbIsolationInterceptor()).addPathPatterns("/**");
}
super.addInterceptors(registry);
}
/**
* Token参数解析
*
......
package com.central.common.filter;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.CommonConstant;
import com.central.common.constant.SecurityConstants;
import com.central.common.context.TenantContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 租户过滤器
*
* @author zlt
* @date 2019/9/15
*/
public class TenantFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
try {
//优先获取请求参数中的tenantId值
String tenantId = request.getParameter(CommonConstant.TENANT_ID_PARAM);
if (StrUtil.isEmpty(tenantId)) {
tenantId = request.getHeader(SecurityConstants.TENANT_HEADER);
}
//保存租户id
if (StrUtil.isEmpty(tenantId)) {
TenantContextHolder.setTenant(tenantId);
}
filterChain.doFilter(request, response);
} finally {
TenantContextHolder.clear();
}
}
}
package com.central.common.filter;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.CommonConstant;
import com.central.log.properties.TraceProperties;
import org.slf4j.MDC;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 日志链路追踪过滤器
*
* @author zlt
* @date 2019/9/15
*/
public class TraceFilter extends OncePerRequestFilter {
@Resource
private TraceProperties traceProperties;
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return !traceProperties.getEnable();
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
try {
String traceId = request.getHeader(CommonConstant.TRACE_ID_HEADER);
if (StrUtil.isNotEmpty(traceId)) {
MDC.put(CommonConstant.LOG_TRACE_ID, traceId);
}
filterChain.doFilter(request, response);
} finally {
MDC.clear();
}
}
}
package com.central.common.interceptor;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.CommonConstant;
import com.central.common.context.LbIsolationContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 负载均衡隔离规则截器
*
* @author zlt
* @date 2019/8/5
*/
public class LbIsolationInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String version = request.getHeader(CommonConstant.Z_L_T_VERSION);
if(StrUtil.isNotEmpty(version)){
LbIsolationContextHolder.setVersion(version);
}
return true;
}
}
package com.central.common.interceptor;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.CommonConstant;
import com.central.common.constant.SecurityConstants;
import com.central.common.context.TenantContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 租户拦截器
*
* @author zlt
* @date 2019/8/5
*/
public class TenantInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
//优先获取请求参数中的tenantId值
String tenantId = request.getParameter(CommonConstant.TENANT_ID_PARAM);
if (StrUtil.isEmpty(tenantId)) {
tenantId = request.getHeader(SecurityConstants.TENANT_HEADER);
}
//保存租户id
if(StrUtil.isNotEmpty(tenantId)){
TenantContextHolder.setTenant(tenantId);
} else {
TenantContextHolder.clear();
}
return true;
}
}
package com.central.common.interceptor;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.CommonConstant;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 日志链路追踪拦截器
*
* @author zlt
* @date 2019/8/13
*/
public class TraceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String traceId = request.getHeader(CommonConstant.TRACE_ID_HEADER);
if (StrUtil.isNotEmpty(traceId)) {
MDC.put(CommonConstant.LOG_TRACE_ID, traceId);
}
return true;
}
}
org.springframework.context.ApplicationContextInitializer=\
com.central.common.config.BannerInitializer
\ No newline at end of file
com.central.common.config.BannerInitializer
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.central.common.filter.TenantFilter,\
com.central.common.filter.TraceFilter
\ No newline at end of file
......@@ -37,7 +37,7 @@ public class FeignInterceptorConfig {
*/
@Bean
public RequestInterceptor requestInterceptor() {
RequestInterceptor requestInterceptor = template -> {
return template -> {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
if (attributes != null) {
......@@ -77,7 +77,6 @@ public class FeignInterceptorConfig {
template.header(CommonConstant.TRACE_ID_HEADER, traceId);
}
};
return requestInterceptor;
}
/**
......
package com.central.common.ribbon.filter;
import cn.hutool.core.util.StrUtil;
import com.central.common.constant.CommonConstant;
import com.central.common.constant.ConfigConstants;
import com.central.common.context.LbIsolationContextHolder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 负载均衡隔离规则过滤器
*
* @author zlt
* @date 2019/9/15
*/
public class LbIsolationFilter extends OncePerRequestFilter {
@Value("${" + ConfigConstants.CONFIG_RIBBON_ISOLATION_ENABLED + ":false}")
private boolean enableIsolation;
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return !enableIsolation;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
try {
String version = request.getHeader(CommonConstant.Z_L_T_VERSION);
if(StrUtil.isNotEmpty(version)){
LbIsolationContextHolder.setVersion(version);
}
filterChain.doFilter(request, response);
} finally {
LbIsolationContextHolder.clear();
}
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.central.common.ribbon.RibbonAutoConfigure,\
com.central.common.ribbon.FeignAutoConfigure,\
com.central.common.ribbon.RestTemplateAutoConfigure
com.central.common.ribbon.RestTemplateAutoConfigure,\
com.central.common.ribbon.filter.LbIsolationFilter
......@@ -13,8 +13,11 @@
 
**提供以下两个测试接口**
1. `http://localhost:9090/placeOrder`:成功下单
2. `http://localhost:9090/placeOrder`:测试异常回滚,`storage-service``order-service`的事务已提交,`account-service`出异常后全局回滚
1. 事务成功:扣除库存成功 > 创建订单成功 > 扣减账户余额成功
http://localhost:9090/placeOrder
1. 事务失败:扣除库存成功 > 创建订单成功 > 扣减账户余额失败,事务回滚
http://localhost:9090/placeOrderFallBack
 
## 二、运行步骤
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册