首页 > 其他分享 >技术问题系列--查询过大引发的Dubbo问题

技术问题系列--查询过大引发的Dubbo问题

时间:2024-02-11 11:02:22浏览次数:23  
标签:Dubbo remoting java dubbo -- 查询 10.11 apache org

某天上午,我喝着茶看着技术博客,突然接到一个系统告警短信,还没来得及看内容,公司的客服小姐姐就飞快的跑到面前说,“系统出问题了”,吓得我一口茶水喷了出来......

1、问题反馈

听了客服小姐姐的反馈之后,我又赶紧看了下系统的告警短信内容(某个微服务内存达到了阈值),紧接着我查看了系统异常日志,内容如下:

2023-08-01 14:00:12|ERROR|com.xxx.xxx.xxx.ordercenter.api.DubboApiAop:validResultSize|79|DubboServerHandler-10.11.4.4:20880-thread-195|"orderCenter dubbo interface result is too large, size:321673424, class:com.xxx.xxx.xxx.ordercenter.api.impl.ClueApiImpl@5dc7881d, method:queryList"|""

2023-08-01 14:00:13|ERROR|org.apache.dubbo.remoting.transport.AbstractCodec:checkPayload|52|NettyServerWorker-6-4|"Data length too large: 59892326, max payload: 8388608, channel: NettyChannel [channel=[id: 0xa9b42a62, L:/10.11.4.4:20880 - R:/10.11.2.152:42026]]"|"org.apache.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 59892326, max payload: 8388608, channel: NettyChannel [channel=[id: 0xa9b42a62, L:/10.11.4.4:20880 - R:/10.11.2.152:42026]]
        at org.apache.dubbo.remoting.transport.AbstractCodec.checkPayload(AbstractCodec.java:50)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encodeResponse(ExchangeCodec.java:296)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encode(ExchangeCodec.java:71)
        at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(DubboCountCodec.java:40)
        at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder.encode(NettyCodecAdapter.java:69)
"
2023-08-01 14:00:13|WARN|org.apache.dubbo.remoting.exchange.codec.ExchangeCodec:encodeResponse|311|NettyServerWorker-6-4|" [DUBBO] Data length too large: 59892326, max payload: 8388608, channel: NettyChannel [channel=[id: 0xa9b42a62, L:/10.11.4.4:20880 - R:/10.11.2.152:42026]], dubbo version: 2.7.8, current host: 10.11.4.4"|"org.apache.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 59892326, max payload: 8388608, channel: NettyChannel [channel=[id: 0xa9b42a62, L:/10.11.4.4:20880 - R:/10.11.2.152:42026]]
        at org.apache.dubbo.remoting.transport.AbstractCodec.checkPayload(AbstractCodec.java:50)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encodeResponse(ExchangeCodec.java:296)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encode(ExchangeCodec.java:71)
        at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(DubboCountCodec.java:40)
        at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder.encode(NettyCodecAdapter.java:69)
        
// ===================================

2023-08-01 14:20:12|ERROR|com.xxx.xxx.xxx.ordercenter.api.DubboApiAop:validResultSize|79|DubboServerHandler-10.11.1.186:20880-thread-198|"orderCenter dubbo interface result is too large, size:321689904, class:com.xxx.xxx.xxx.ordercenter.api.impl.ClueApiImpl@3b850bb7, method:queryList"|""

2023-08-01 14:20:12|ERROR|org.apache.dubbo.remoting.transport.AbstractCodec:checkPayload|52|NettyServerWorker-6-3|"Data length too large: 59896419, max payload: 8388608, channel: NettyChannel [channel=[id: 0xfa3545c4, L:/10.11.1.186:20880 - R:/10.11.0.124:48306]]"|"org.apache.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 59896419, max payload: 8388608, channel: NettyChannel [channel=[id: 0xfa3545c4, L:/10.11.1.186:20880 - R:/10.11.0.124:48306]]
        at org.apache.dubbo.remoting.transport.AbstractCodec.checkPayload(AbstractCodec.java:50)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encodeResponse(ExchangeCodec.java:296)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encode(ExchangeCodec.java:71)
        at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(DubboCountCodec.java:40)
        at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder.encode(NettyCodecAdapter.java:69)
"
2023-08-01 14:20:12|WARN|org.apache.dubbo.remoting.exchange.codec.ExchangeCodec:encodeResponse|311|NettyServerWorker-6-3|" [DUBBO] Data length too large: 59896419, max payload: 8388608, channel: NettyChannel [channel=[id: 0xfa3545c4, L:/10.11.1.186:20880 - R:/10.11.0.124:48306]], dubbo version: 2.7.8, current host: 10.11.1.186"|"org.apache.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 59896419, max payload: 8388608, channel: NettyChannel [channel=[id: 0xfa3545c4, L:/10.11.1.186:20880 - R:/10.11.0.124:48306]]
        at org.apache.dubbo.remoting.transport.AbstractCodec.checkPayload(AbstractCodec.java:50)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encodeResponse(ExchangeCodec.java:296)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encode(ExchangeCodec.java:71)
        at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(DubboCountCodec.java:40)
        at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder.encode(NettyCodecAdapter.java:69)        

2、问题分析

2.1、大致原因

看到异常日志后,接下来就是分析原因和解决问题了。我们系统架构是SpringCloudAlibaba + Dubbo的微服务架构,采用云原生的部署方式,有一套Kubernetes的Dashboard和监控告警系统。

从上面的Dubbo的错误信息Data length too large: 59896419, max payload: 8388608,能猜出是某个微服务接口响应对象的大小超过默认值引发的异常。是哪个接口响应对象过大呢?继续分析。

2.2、深度剖析

1、之前我对Dubbo服务提供者做了统一的切面,在切面里会判断接口响应对象的内存占用是否过大,如果过大,会把相关的类和方法打印出来。所以,能看到下面这段日志。从这段日志能定位出是哪个系统的哪个接口出现的对象过大的问题。

2023-08-01 14:20:12|ERROR|com.xxx.xxx.xxx.ordercenter.api.DubboApiAop:validResultSize|79|DubboServerHandler-10.11.1.186:20880-thread-198|"orderCenter dubbo interface result is too large, size:321689904, class:com.xxx.xxx.xxx.ordercenter.api.impl.ClueApiImpl@3b850bb7, method:queryList"|""

2、哪个服务提供者的哪个接口确定之后,如果判断是哪个服务调用者呢?继续分析这段日志:

2023-08-01 14:00:13|ERROR|org.apache.dubbo.remoting.transport.AbstractCodec:checkPayload|52|NettyServerWorker-6-4|"Data length too large: 59892326, max payload: 8388608, channel: NettyChannel [channel=[id: 0xa9b42a62, L:/10.11.4.4:20880 - R:/10.11.2.152:42026]]"|"org.apache.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 59892326, max payload: 8388608, channel: NettyChannel [channel=[id: 0xa9b42a62, L:/10.11.4.4:20880 - R:/10.11.2.152:42026]]
        at org.apache.dubbo.remoting.transport.AbstractCodec.checkPayload(AbstractCodec.java:50)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encodeResponse(ExchangeCodec.java:296)
        at org.apache.dubbo.remoting.exchange.codec.ExchangeCodec.encode(ExchangeCodec.java:71)
        at org.apache.dubbo.rpc.protocol.dubbo.DubboCountCodec.encode(DubboCountCodec.java:40)
        at org.apache.dubbo.remoting.transport.netty4.NettyCodecAdapter$InternalEncoder.encode(NettyCodecAdapter.java:69)

3、这段日志里有一行信息引入注目:channel: NettyChannel [channel=[id: 0xa9b42a62, L:/10.11.4.4:20880 - R:/10.11.2.152:42026]],看来突破口要从这里找了,于是我赶紧翻看了Dubbo源码,找到了源码对应的位置,见下图:

4、顺着checkPayload方法,找到encodeResponse方法。至此可以判断,Dubbo将服务提供者的响应对象序列化后通过Netty传输的出去的过程中会对接口响应对象的大小做校验。

5、checkPayload方法里打印的信息是channel,入参也是Channel,所以继续挖Channel类。从上面的日志可以看出,此Channel接口的实现类是NettyChannel,所以继续挖源码,找到了与上面日志内容相匹配的代码了,见下图:

6、那上面这段代码里的channel是个啥呢?上面日志里的L、R和2个IP地址又是什么意思呢? 想弄明白这个问题,只能在小小的源码里面继续挖呀挖呀挖。终于在Dubbo里的Netty的源码部分里挖到了这段代码,代码里打印的信息和上面的异常日志信息完全一致,见下图:

7、至此我们已经清晰地看到上面的异常是怎么引发出来的了。也明白了日志里的L、R和2个IP地址代表的意思,L代表本地IP地址,R代表远程IP地址。

8、接下来就很轻松了,通过远程IP地址在Kubernetes的Dashboard里找到了IP地址对应的Kubernetes-Pod,从而确定了是哪个微服务。

9、找到微服务之后,继续找到了调用的地方。最后发现,是因为程序员小贾,在调用queryList接口的时候,缺少了一些查询条件,导致查询到了大量数据,引发了内存阈值告警。

3、问题总结

结合异常日志和Dubbo源码,通过层层源码分析,得出结论:程序员小贾写代码调用某个微服务的查询接口时,由于少传了核心条件,导致大量数据被查询加载到了内存里,引发了内存告警。幸好,Dubbo有接口响应数据过大的校验,才没引发更严重的问题。

问题至此分析完毕,接下来程序员小贾要赶紧修复代码上线了,然后要背上一口锅,顺带我也要分一口小锅。

4、经验教训

通过分析问题,也得出些经验教训:

  1. 系统的监控告警功能非常重要。它有助于及时发现问题,解决问题,避免给公司造成损失。再次确定了它的重要性。
  2. 作为服务提供者,对接口的入参校验必不可少,不能任由别的微服务服务随意传参调用。
  3. 在服务提供者层面,要做好限流、异常操作的限制等,加强接口的健壮性。
  4. 再次见证了dubbo的生产级别的强大。
  5. 建议大家多阅读开源框架的源码。

原文链接:http://www.mangod.top/articles/2023/08/01/1690904592378.htmlhttps://mp.weixin.qq.com/s/7INpeFoGDP9IftvYXqGNEA

感谢你的阅读,码字不易,欢迎点赞 关注 收藏!!!

标签:Dubbo,remoting,java,dubbo,--,查询,10.11,apache,org
From: https://www.cnblogs.com/mangod/p/18013228

相关文章

  • PHP项目&变量覆盖&反序列化&未授权访问&身份验证
    CNVD拿1day-验证&未授权-xhcms&Bosscms此种漏洞由于没有什么关键函数,所以需要通过功能点去进行测试。Bosscms未授权访问CNVD官网上搜索Bosscms未授权访问漏洞。根据描述,影响的是1.0版本。看到发送时间为21年12月29好,收录时间为22年1月18号。再去官网看版本更新的时间点,V1.0版......
  • 10分钟了解Flink Watermark水印
    在上一篇中,介绍了Flink里时间的概念和窗口计算,在实际生产过程中,由于网络等原因,许多数据会延迟到达窗口,这种情况Flink如何处理?Watermark登场,本文从这几点进行介绍:水印的概念、水印如何计算、允许延迟和侧道输出、水印生成策略、案例及代码。1、一个小例子讲解概念前,我先举个例......
  • 5分钟了解Flink状态管理
    什么叫做Flink的有状态计算呢?说白了就是将之前的中间结果暂时存储起来,等待后续的事件数据过来后,可以使用之前的中间结果继续计算。本文主要介绍Flink状态计算和管理、代码示例。1、有状态的计算什么是Flink的有状态的计算。在流式计算过程中将算子的中间结果保存在内存或者文......
  • TTL和CMOS器件的连接
    TTL、CMOS器件的互连 1:逻辑器件的互连总则   在不同逻辑电平器件之间进行互连时主要考虑以下几点:电平关系,必须保证在各自的电平范围内工作,否则,不能满足正常逻辑功能,严重时会烧毁芯片。驱动能力,必须根据器件的特性参数仔细考虑,计算和试验,否则很可能造成隐患,在电源波动,受到......
  • Kubernetes架构及核心部件
    Kubernetes有哪些核心部件,架构图和流程图又是怎样的,kubectl和kubelet经常分不清,声明式API和命令式API又有什么区别,本文一一详说。1、Kubernetes集群概述1.1、概述Kubernetes是一个容器编排平台,它使用共享网络将多个主机(物理服务器或虚拟机)构建成集群。分为MasterNode(主节......
  • Docker小知识备忘录
    本文整理了一些Docker基础知识和常用命令,方便朋友们查阅。同时也感谢Docker这个划时代的产品,它解决了环境一致性的问题,让交付和迁移更轻松。1、Docker与虚拟化1.1、虚拟化技术虚拟化技术分为两大类,全虚拟化和半虚拟化。全虚拟化比如之前我们使用的虚拟机就是全虚拟化,这种......
  • 《长安三万里》给程序员的启发
    前段时间陪孩子一起看了《长安三万里》,结合这些年自己走过的路,内心有不少感触。不论电影评价怎样,也不论事实如何,单从程序员的角度,来说说三点启发:1、尽早做好程序员的职业规划,并且知行合一非常喜欢高适这个人物,文武双全,有勇有谋讲义气。虽没有李白的放荡不羁和才华,但他早早的给......
  • 概念解读-云原生和容器编排
    有些概念没有标准答案,每个地方解释的也都很模糊,概念也一直被滥用,比如说云原生的概念。有些概念听起来高大上,实际上很普通,比如说容器编排的概念。本文我对这两个概念作个解释。1、云原生最近几年,“云原生”一度成为前沿的技术用语,各种业内技术大会都能看到“云原生”的字样,但是......
  • Kafka 命令行操作
    1.Topic(主题)命令行操作1.查看Topic所有命令bin/kafka-topics.sh以下展示为最常使用的参数描述--bootstrap-server<String:servertoconnectto>连接的KafkaBroker主机名称和端口号--topic<String:topic>操作的topic名称--create创建Topic(主题)......
  • NET项目&DLL反编译&MSSQL监控&VS搜索&注入&上传
    知识点1.NET普通源码&编译源码2.DLL反编译&后缀文件&指向3.代码审计-SQL注入&文件上传ASPX文件->CSASPX.CSDLL反编译后寻找看核心代码分析漏洞CSASPX.CSDLL反编译文件->ASPX文件寻找确定漏洞进行调试测试代码审计时要把这个反编译文件提取导入到IDE中后期搜索关......