springcloud整合dubbo结构
整体架构:
请求传递流程:
可以看到请求是a -> b -> c跳了两层的,所以http请求中附带的token等请求头参数无法在provider中直接获取,换言之,token只能在controller层获取,而不能在service层获取
为了解决这个问题,可以配置消费者拦截器:
package com.gdcx.web.filter; import com.gdcx.constants.Constant; import com.gdcx.utils.UserClientUtil; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.rpc.*; @Activate(group = {CommonConstants.CONSUMER}, order = Integer.MIN_VALUE) public class DubboConsumerParamsFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { RpcServiceContext context = RpcContext.getServiceContext(); context.setObjectAttachment(Constant.TOKEN_HEADER, UserClientUtil.getCurrentToken());//消费者带上token请求 return invoker.invoke(invocation); } }
此外为了方便,还可以配置异常处理器拦截器:
package com.gdcx.web.filter; import com.gdcx.exception.ServiceException; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.ReflectUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.BaseFilter.Listener; import org.apache.dubbo.rpc.*; import org.apache.dubbo.rpc.service.GenericService; import java.lang.reflect.Method; @Activate(group = {CommonConstants.PROVIDER}) @Slf4j public class DubboExceptionFilter implements Filter, Listener { public DubboExceptionFilter() { } public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { return invoker.invoke(invocation); } public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) { if (appResponse.hasException() && GenericService.class != invoker.getInterface()) { try { Throwable exception = appResponse.getException(); if (!(exception instanceof RuntimeException) && exception instanceof Exception) { return; } try { Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes()); Class<?>[] exceptionClasses = method.getExceptionTypes(); Class[] var7 = exceptionClasses; int var8 = exceptionClasses.length; for(int var9 = 0; var9 < var8; ++var9) { Class<?> exceptionClass = var7[var9]; if (exception.getClass().equals(exceptionClass)) { return; } } } catch (NoSuchMethodException var11) { return; } log.error("5-36", "", "", "Got unchecked and undeclared exception which called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception); String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface()); String exceptionFile = ReflectUtils.getCodeBase(exception.getClass()); if (serviceFile != null && exceptionFile != null && !serviceFile.equals(exceptionFile)) { String className = exception.getClass().getName(); if (!className.startsWith("java.") && !className.startsWith("javax.")) { if (exception instanceof RpcException) { return; } if (exception instanceof ServiceException) { return; } appResponse.setException(new RuntimeException(StringUtils.toString(exception))); return; } return; } return; } catch (Throwable var12) { log.warn("5-36", "", "", "Fail to ExceptionFilter when called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + var12.getClass().getName() + ": " + var12.getMessage(), var12); } } } public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) { log.error("5-36", "", "", "Got unchecked and undeclared exception which called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e); } }
最后,将两个拦截器放入请求中
路径:
代码:
dubboConsumerParamsFilter=com.gdcx.web.filter.DubboConsumerParamsFilter
exception=com.gdcx.web.filter.DubboExceptionFilter