Dubbo如何处理业务异常

warning: 这篇文章距离上次修改已过353天,其中的内容可能已经有所变动。

https://blog.csdn.net/m0_57077948/article/details/117524555?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-117524555-blog-128680545.235^v31^pc_relevant_default_base3&spm=1001.2101.3001.4242.2&utm_relevant_index=4

https://deepmind.t-salon.cc/article/5835

方案

即采用dubbo的filter重写,dubbo的异常处理。

1、将dubbo源码中ExceptionFilter复制到我们的项目改名为DubboExceptionFilter
修改一些代码

2、在此处加上一段代码来过滤我们项目中的异常,以免被dubbo重新封装
3、在resources目录下添加纯文本文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter并添加内容

dubboExceptionFilter=com.rainbow.goods.server.filter.DubboExceptionFilter

4.修改dubbo 的配置文件,将DubboExceptionFilter加载进去并且去掉自身的ExceptionFilter

<dubbo:providerfilter="dubboExceptionFilter,-exception"/>

上面exception就是dubbo默认的处理异常的filter,前面-号就代表去除

/* 
 * Copyright 1999-2011 Alibaba Group. 
 *   
 * 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.dubbo.rpc.filter;  
import java.lang.reflect.Method;  
import com.alibaba.dubbo.common.Constants;  
import com.alibaba.dubbo.common.extension.Activate;  
import com.alibaba.dubbo.common.logger.Logger;  
import com.alibaba.dubbo.common.logger.LoggerFactory;  
import com.alibaba.dubbo.common.utils.ReflectUtils;  
import com.alibaba.dubbo.common.utils.StringUtils;  
import com.alibaba.dubbo.rpc.Filter;  
import com.alibaba.dubbo.rpc.Invocation;  
import com.alibaba.dubbo.rpc.Invoker;  
import com.alibaba.dubbo.rpc.Result;  
import com.alibaba.dubbo.rpc.RpcContext;  
import com.alibaba.dubbo.rpc.RpcException;  
import com.alibaba.dubbo.rpc.RpcResult;  
import com.alibaba.dubbo.rpc.service.GenericService;  
/** 
 * ExceptionInvokerFilter 
 * <p> 
 * 功能: 
 * <ol> 
 * <li>不期望的异常打ERROR日志(Provider端)
 
 *     不期望的日志即是,没有的接口上声明的Unchecked异常。 
 * <li>异常不在API包中,则Wrap一层RuntimeException。
 
 *     RPC对于第一层异常会直接序列化传输(Cause异常会String化),避免异常在Client出不能反序列化问题。 
 * </ol> 
 *  
 * @author william.liangf 
 * @author ding.lid 
 */  
@Activate(group = Constants.PROVIDER)  
public class ExceptionFilter implements Filter {  
    private final Logger logger;  
    public ExceptionFilter() {  
        this(LoggerFactory.getLogger(ExceptionFilter.class));  
    }  
    public ExceptionFilter(Logger logger) {  
        this.logger = logger;  
    }  
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {  
        try {  
            Result result = invoker.invoke(invocation);  
            if (result.hasException() && GenericService.class != invoker.getInterface()) {  
                try {  
                    Throwable exception = result.getException();  
                    // 如果是checked异常,直接抛出  
                    if (! (exception instanceof RuntimeException) && (exception instanceof Exception)) {  
                        return result;  
                    }  
                    // 在方法签名上有声明,直接抛出  
                    try {  
                        Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());  
                        Class<?>[] exceptionClassses = method.getExceptionTypes();  
                        for (Class<?> exceptionClass : exceptionClassses) {  
                            if (exception.getClass().equals(exceptionClass)) {  
                                return result;  
                            }  
                        }  
                    } catch (NoSuchMethodException e) {  
                        return result;  
                    }  
                    // 未在方法签名上定义的异常,在服务器端打印ERROR日志  
                    logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()  
                            + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()  
                            + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);  
                    // 异常类和接口类在同一jar包里,直接抛出  
                    String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());  
                    String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());  
                    if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)){  
                        return result;  
                    }  
                    // 是JDK自带的异常,直接抛出  
                    String className = exception.getClass().getName();  
                    if (className.startsWith("java.") || className.startsWith("javax.")) {  
                        return result;  
                    }  
                    // 是Dubbo本身的异常,直接抛出  
                    if (exception instanceof RpcException) {  
                        return result;  
                    }  
                    // 否则,包装成RuntimeException抛给客户端  
                    return new RpcResult(new RuntimeException(StringUtils.toString(exception)));  
                } catch (Throwable e) {  
                    logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()  
                            + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()  
                            + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);  
                    return result;  
                }  
            }  
            return result;  
        } catch (RuntimeException e) {  
            logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()  
                    + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()  
                    + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);  
            throw e;  
        }  
    }  
} 
版权声明 ▶ 本网站名称:我的学习笔记
▶ 本文链接:https://ooolo.net/article/177.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!!

none
最后修改于:2023年05月09日 18:56

添加新评论

icon_mrgreen.pngicon_neutral.pngicon_twisted.pngicon_arrow.pngicon_eek.pngicon_smile.pngicon_confused.pngicon_cool.pngicon_evil.pngicon_biggrin.pngicon_idea.pngicon_redface.pngicon_razz.pngicon_rolleyes.pngicon_wink.pngicon_cry.pngicon_surprised.pngicon_lol.pngicon_mad.pngicon_sad.pngicon_exclaim.pngicon_question.png