当前位置:首页 > 服务端 > Dubbo IO异常的捕获

Dubbo IO异常的捕获

2022年11月09日 20:12:47服务端6

需求

为什么要写这么一个小问题呢,可能有同学说了,发生异常后不是自动就体现到日志里面去了吗?有啥可捕获的?

想想这么一个场景:

生产环境中众多日志中发现了如下异常信息:

[New I/O worker #1][Log4j2Logger.java:73] - 
Data length too large: 1895857664, max payload: 8388608, 
channel: NettyChannel [channel=[id: 0xbe23f2b5, 
/172.31.5.38:36596 => /172.31.2.196:21880]]\n\"\

用过Dubbo的都知道,这是因为 RPC接口的返回值过大,超出了设定的响应最大值,可以通过修改 payload 参数来解决。

通过这个信息你大致可以知道是 哪两个服务 交互时发生的异常,但是无法知道具体是哪个接口、哪个方法、什么参数情况下产生的这个异常,里面也没有logId。

这就是老吕要捕获它的原因,我要把产生这个错误时对应的 logId,接口名称,方法名称,和参数值 全部记录下来,方便业务开发的同学进行优化改进。

logId在每一个业务线程中都会绑定,发生业务异常时日志中就会自动记录下 logId,开发人员可以方便的检索 分布式链路日志解决问题。但是这个IO异常是产生的IO线程上的,大家都知道在NIO架构中IO线程是所有业务线程共享的,这就意味着 IO线程上不可能绑定业务logId这个东西,所以它出来的异常中是没有logId这个东西的。

解决方案

关于Dubbo IO线程模型的先不说了,下面直接给出一个针对此问题的可行的解决方案:

由于这个IO异常的根源产生在提供者端,我一直想在提供者端捕获,最终证明不太可行(有知道的同学可以通知我下),还是要到消费者端捕获。

我分别写了2个过滤器,一个是提供者端过滤器,一个是消费者端过滤器,看里面的注释就知道怎么做了,如下:

##提供者过滤器(无法感知Duboo IO异常,这里只是为了说明问题)

public class MyProviderFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long startTime = System.currentTimeMillis();
        try {
            Result result = invoker.invoke(invocation);
            if (result.hasException()) {
                //是否有异常,异常处理,这里可以感知所有的业务线程异常,但无法感知Dubbo的IO异常
            }
            return result;
        }catch (Throwable e){
            //这里也无法感知IO异常
            e.printStackTrace();
            throw e;
        }finally {
            String log = invoker.getInterface().getCanonicalName()+","+invocation.getMethodName();
            System.out.println(log+","+(System.currentTimeMillis()-startTime));
        }


    }
}

##消费者过滤器(可以感知Dubbo IO异常,但是也需要特殊处理才行)

public class MyConsumerFilter implements Filter {
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long startTime = System.currentTimeMillis();
        try {
            Result result = invoker.invoke(invocation);
            if (result.hasException()) {
                //是否有异常,异常处理,这里无法感知Dubbo IO异常
            }
            return result;
        }catch (Throwable e){
            //这里可以感知IO异常
            dubboRpcLog(invoker,invocation,e.getMessage());
            throw e;
        }finally {
            String log = invoker.getInterface().getCanonicalName()+","+invocation.getMethodName();
            System.out.println(log+","+(System.currentTimeMillis()-startTime));
        }


    }




    /**
     * 记录调用日志
     * @param invoker
     * @param invocation
     */
    private void dubboRpcLog(Invoker<?> invoker, Invocation invocation,String errorMsg) {


        StringBuilder message = new StringBuilder();
        message.append("dubboUrl:").append(invoker.getUrl()).append(";");
        message.append("interface:").append(invoker.getInterface().getName()).append(";");
        message.append("methodName:").append(invocation.getMethodName()).append(";");


        Class<?>[] parameterTypes = invocation.getParameterTypes();
        Object[] arguments = invocation.getArguments();


        if (parameterTypes!=null||parameterTypes.length>0) {
            message.append("arguments:");
            try {
                message.append(JSON.json(arguments));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println(message.toString());
    }
}

今天就到这里,希望对你有所帮助

Dubbo IO异常的捕获 _ JavaClub全栈架构师技术笔记

扫码加微信技术群

Dubbo IO异常的捕获 _ JavaClub全栈架构师技术笔记

作者:老吕架构
来源链接:https://blog.csdn.net/super_scan/article/details/121092559

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/69201.html

标签: Dubbo异常
分享给朋友:

“Dubbo IO异常的捕获” 的相关文章

解决 There is no getter for property named ‘null‘ in class 的报错异常

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There i...

Java异常(一) Java异常简介及其架构

Java异常(一) Java异常简介及其架构

  概要 本章对Java中的异常进行介绍。内容包括:Java异常简介Java异常框架 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3544168.html   Java异常简介   ...

after : """>【异常】Maxwell异常 Exception in thread "main" net.sf.jsqlparser.parser.TokenMgrError: Lexical error at line 1, column 596. Encountered: after : ""

1 详细异常 Exception in thread "main" net.sf.jsqlparser.parser.TokenMgrError: Lexical error at line 1, column 596. Encountered: <EOF>...

Android 混淆问题排查

Android 混淆问题排查

问题 近期在开发过程中,突然出现混淆后程序出现运行时异常,编译是正常的,不混淆也是正常的, 错误信息如下提示 12-07 14:10:27.056 10603-10603/? E/AndroidRuntime: FATAL EXCEPTION...

Android之NetworkOnMainThreadException异常

转载自:https://blog.csdn.net/mad1989/article/details/25964495 看名字就应该知道,是网络请求在MainThread中产生的异常 先来看一下官网的解释: Class Overview The excepti...

Error creating bean with name ‘sqlSessionFactory’ defined in class path resource

Error creating bean with name ‘sqlSessionFactory’ defined in class path resource

原文链接:这里 0.报错描述 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in...

AndoridStudio--Error:FAILURE: Build failed with an exception.

相信用过Android Studio开发的朋友都知道,Andorid Studio有时候在运行的时候突然出现如下信息: Error:FAILURE: Build failed with an exception. * What went wrong: Execut...

android studio 的FAILURE: Build failed with an exception解决办法

android studio 的FAILURE: Build failed with an exception解决办法

关于导入项目、或者从远程pull下来的项目出现”FAILURE: Build failed with an exception”的解决方法: 如果项目列表显示错误可以考虑用以下方式 1、检查目录列表是否有以下文件,如没有请从其...

用Jenkins部署war包到tomcat8报错

用Jenkins部署war包到tomcat8报错"ERROR: Build step failed with exception org.codehaus.cargo.container.ContainerException: Failed to redeploy"的解决办法

一、 Jenkins部署war包到tomcat8 1. 构建结果FAILURE     查看Jenkins控制台,输出的报错的信息如下:   [JENKINS] Archiving /var/lib/jenkins...

Android -- Exception大全

异常类型 Exception ArithmeticExecption 算术异常类 NullPointerException...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。