热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

性能分析之dubbo性能参数导致单cpu高

背景今天记录一个小问题。问题不大,也没什么分析的逻辑可以讲的。但是想着比较典型,所以就写一写。这一日,一个朋友发来个问题。​

背景

今天记录一个小问题。
问题不大,也没什么分析的逻辑可以讲的。但是想着比较典型,所以就写一写。
这一日,一个朋友发来个问题。

一个 Java 应用,从 visualVm 这里看,有 10 个 new I/O worker 线程。具体 top -d -Ph pid 看到只有一个线程在忙。

问题分析

听起来是个问题。一个线程忙,这种情况应该比较好处理吧。
再看一下 CPU 的状态是什么样, 记住这一步是看进程中的线程。这种操作我想看过 7DGroup 公众号上文章的人都已经会了。

然后印下 dump信 息。printf 转换下 pid 到十六进制,查到如下进程:

"New I/O worker #8" #124 daemon prio=5 os_prio=0 tid=0x00007f4c100a2800 nid=0xd232 runnable [0x00007f4ba45c7000]
java.lang.Thread.State: RUNNABLE
at com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:2449)
at com.alibaba.dubbo.common.serialize.support.hessian.Hessian2ObjectInput.readObject(Hessian2ObjectInput.java:76)
at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:83)
at com.alibaba.dubbo.rpc.protocol.dubbo.DecodeableRpcResult.decode(DecodeableRpcResult.java:109)
at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.decodeBody(DubboCodec.java:90)
at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:118)
at com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec.decode(ExchangeCodec.java:79)
at com.alibaba.dubbo.rpc.protocol.dubbo.DubboCountCodec.decode(DubboCountCodec.java:46)
at com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter$InternalDecoder.messageReceived(NettyCodecAdapter.java:134)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:109)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:312)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:90)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- <0x00000007500fccf0> (a java.util.concurrent.ThreadPoolExecutor$Worker)

这其实是一个挺明确的问题,如果理解了dubbo 的话。

不止是 dubbo,对其他的应用也是同样的判断逻辑。如果只有一个 CPU 使用率高。

那就三个方向:

  • 单线程;
  • 锁或等待;
  • 等待。

可是现在是什么年代了?还能有单线程的问题吗?嗯,确实是有的,不管年代。

对于 dubbo 这种配置参数如此之繁杂的玩意来说,配置更需要麻烦。之前我整理过 dubbo 和性能相关的参数,有比较直接的关联关系的大概就有四十几个(包括消耗者和生产者)。
在我们的性能分析中,其实有一个环节,至今我看到仍然做的非常差的,就是事先把性能配置参数给梳理一遍。有些问题在梳理的时候就可以看出来了,所以我在工作的时候,在做性能分析之前,都会先干一遍这样的事情。

比如说 Linux 的参数(下图中红色为性能参数,做了标识):

上图只是展示了一部分,全部参数是什么样的呢?

样算一屏的话,大概有三屏的参数。
可以想像,配置那么多,在出现性能问题时怎么分辨?
并且一个参数问题,导致的问题表象都会让你觉得非常不理解。

有时候我们费了几天的劲分析了一个问题,最后发现是一个参数导致的,改一下就性能大涨,会觉得特别不值得,想骂人的感觉有没有?
有的人看着写文章中一个性能问题,觉得到最后改一个IP、改一个参数、改一行代码、改一个SQL,就会觉得性能问题无非就是这样嘛。
但是你想过没有,这个过程中要分析多少数据?做多少实验?要多有耐心?要多需要功底?
感慨的差不多了,说一下上面的问题是什么原因吧,要不然,看官们该想扔手机了!

上面的问题是什么呢就是一个 connections 配置。这个朋友是把 connections 放到代码里的,写成了这样。

referenceConfig.setConnections(1);

因为限制了连接为 1,并且在压测的这个环境中,一个 consumer 一个 provider。这样一来,就完全限制住了吞吐量。
其实是实际的生产 dubbo 环境中,并不完全是这样。当 consumer 和 provider 多的时候,CPU 也可以用得起来。

但是在这个特定的环境中,就完全被限制了。怎么办呢?这时候,就简单了对不对。

referenceConfig.setConnections(10);

这样就可以用起来了。

小结

因为这个问题比较简单,记录下来,就是为了告诉玩性能的人们,你要关心性能配置参数。
应该说,什么都得关心,缺少一个环节,就是知识的盲区。


推荐阅读
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Introduction(简介)Forbeingapowerfulobject-orientedprogramminglanguage,Cisuseda ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Python语法上的区别及注意事项
    本文介绍了Python2x和Python3x在语法上的区别,包括print语句的变化、除法运算结果的不同、raw_input函数的替代、class写法的变化等。同时还介绍了Python脚本的解释程序的指定方法,以及在不同版本的Python中如何执行脚本。对于想要学习Python的人来说,本文提供了一些注意事项和技巧。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • ***byte(字节)根据长度转成kb(千字节)和mb(兆字节)**parambytes*return*publicstaticStringbytes2kb(longbytes){ ... [详细]
author-avatar
php.net
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有