免费节点2:使用捷径添加_盒子:找到性能瓶颈的捷径

免费节点2:使用捷径添加

经常会通过一些非常古怪的注释来报告性能问题,这些注释并没有帮助您了解从何处着手。 面对这种困境,团队开始猜测根本原因并不少见。 现在输入“盒子”,这是一个完整系统的抽象小图。 该框提醒了性能瓶颈的真实情况。 当与严格的调查一起使用时,它可以帮助您排除猜测的瓶颈。 如果您要保持一致和可预测,则必须摆脱猜测。

系统夹心蛋糕

如图1所示的盒子由4层组成。 这些层被标记为人员,应用程序,Java虚拟机和硬件。 当我们进一步探索该框时,我们将看到这些层中的每一层在我们的系统性能中扮演的主要角色。 我们还将看到包装盒如何帮助我们组织发现性能瓶颈的工作。
图1.盒子

关于性能,已经有人说过,改变人,你就改变了问题。 这就是说性能瓶颈对系统上的负载很敏感。 如果我们更改框中的图层,我们将得到一个不同的系统,因此该框包含“人物”是一致的。 仅具有“人员”层代表人员是不够的。 人也代表了驱动我们系统的任何事物,包括批处理过程和其他系统。 这些都对系统的其他层提出了要求,从而又消耗了它们提供的稀缺资源。

从中我们可以看到,为了理解我们的系统,我们必须首先了解人民正在做什么。 这将帮助我们设置负载测试,而此设置对于帮助我们确定瓶颈至关重要。 您可能以为UML包含一个称为参与者的东西,而参与者的作用是解释作用在系统上的作用力。 确实可以,但是UML中的Actor会描述将要发生的情况,但是它通常缺少设置负载测试所需的其他信息。

为了创建良好的模拟,我们需要知道的事情清单包括:用户数量,他们在做什么,他们做多少次,何时做。 我们还需要考虑以下场景: 轮班活动的开始和结束,季节性趋势,特殊事件,每天凌晨2点的备用活动。 一旦我们收集了所有这些信息并将其编写为负载测试工具的脚本,我们就可以开始寻找瓶颈的过程了。

应用

人员下面的层是应用程序。 我喜欢将这一层视为人员与JVM和硬件之间的映射。 如果我们很聪明或很幸运,我们将设法定义一个有效的映射-这种映射可以最大限度地利用底层资源来满足人民的需求。 一般来说,我们会说我们的系统是有效的。 如果不是每本书,每篇文章,每条建议和我们体内的纤维都告诉我们,这是我们将要进行的工作,那么为什么不忽略它并从这里开始。

我不得不有机会让几百名开发人员进行非常简单的性能调整。 适度的目标是使有关方法的运行速度提高3倍。 观察结果虽然不科学,但仍然令人震惊。 经过30分钟的努力,只有不到2%的参与者能够识别瓶颈。 能够识别瓶颈的2%的绝大多数人都忽略了代码,而是查看框内的较低层告诉他们什么。 从这组不科学的观察得出的结论是: 忽略代码,直到您查看了该框的下层。 即使这样,您仍会涉足代码,应该使用探查器作为指南。

Java虚拟机

就像应用程序可以看作是People与JVM之间的映射一样,JVM也可以看作是应用程序与硬件之间的映射。 虽然我们实际上没有选择更改JVM中代码的选项,但是我们可以选择更改JVM自身的选项。 最有可能发生的事情是,通过设置许多命令行开关中的许多开关,人们将可以配置(调整)JVM。 配置不当的JVM会人为地使应用程序资源匮乏,这可能会对应用程序性能产生巨大的负面影响。

硬件

框中的最后一层是硬件。 这是具有有限容量的静态层。 CPU每秒只能处理这么多指令,内存只能容纳这么多数据,I / O通道的数据传输速率受到限制,磁盘具有固定的容量。 几乎不必说,如果您的硬件容量不足,则应用程序的性能会受到影响。 考虑到硬件对性能的直接影响,所有调查都必须从这里开始。

将内核像租来的m子一样对待

有很多工具可以帮助您查看系统是否缺少4种主要资源之一(CPU,内存,磁盘和网络I / 0)。 在Windows系统上,就像打开图2所示的任务管理器一样简单。这将始终显示出,您的应用程序正在消耗100%的CPU或无法消耗100%的CPU。 尽管这听起来可能不多,但实际上这是非常有价值的线索,尤其是当您将其与其他信息结合在一起时。

图2 Windows TaskManager

如果看图2,我们可以看到CPU正在热运行,实际上非常热。 但是,除了偶尔的峰值外,它的利用率还不到100%。 请注意CPU利用率图形中绿线下方的红线。 该行表示Windows内核正在消耗多少CPU。 通常,我们希望系统CPU利用率低于总数的20%。 越大越好,我们有迹象表明,应用程序代码中的某些内容导致操作系统工作异常困难。 要了解什么,我们需要了解内核可能要做什么。 了解内核在帮助我们理解代码中需要寻找的内容方面具有无价的意义。

内核执行的任务包括:上下文切换,线程调度,内存管理,中断处理等。 所有这些活动都需要使用CPU。 让我们考虑一下管理内存的任务。 随着对系统内存需求的增加,内核很可能开始将页面从内存弹出到磁盘。 如果应用程序引用页面,也需要在页面中进行交换。 在大多数情况下,要弹出的页面将是最近最少使用的页面。 查找该页面需要使用CPU。 它还需要使用磁盘I / O通道。 稍后读取或写入磁盘的步骤将导致内核停止运行。 停滞的内核和停滞的应用程序将不使用CPU。 但是,如果内存利用率变得至关重要,我们将看到内核经常尝试找出要弹出的页面与磁盘I / O混合在一起。 此扫描活动可以负责系统利用率编号。

如果我们看一下图2的底部面板,我们可以很快看到该系统中有足够的内存,并且其中大部分是空闲的。 因此,我们可以(以合理的信心)消除内存不足这一问题的根源。 我们仍然需要做更多的工作来完全确认这一发现。 现在,我们将继续进行下一个竞争者上下文切换,而不是这样做。

线程会定期换入和换出CPU。 正是这项活动使我们可以同时运行多个进程。 分配给每个线程的时间量是固定的。 当一个线程耗尽时,它就会被另一个线程所取代。 所有这些活动都由内核中运行的线程调度程序管理。 为了完成这项工作,内核必须使用CPU。 在正常情况下,重新安排线程的工作几乎不会引起注意。 但是,在某些情况下,线程可能会在完成时间分配之前从CPU中删除。 一些较常见的原因是I / O被阻塞或被迫等待锁定。 反复从CPU移除线程将导致调度程序更加努力地工作。 如果这种情况经常发生,则可能会导致内核提高CPU利用率,从而影响应用程序性能。

在图2中的图形情况下,CPU中频繁的早期上下文切换是CPU利用率高的最可能原因。 知道这一点为我们进一步研究/表征该问题提供了一个良好的起点。 回顾一下,我们已经对行为进行了特征描述,并且对哪种类型的代码可能会导致这种类型的问题有所了解。 在这一点上,我们可以看一下代码,看看是否可以找到任何可能导致上下文切换过早的内容,但是还有许多其他可能性。 我们将更好地使用该框作为指导,以帮助我们在深入研究代码之前进一步描述问题的特征。 例如,我们可能想要重新调整监控范围,以查看网络,磁盘活动或查看是否在锁上承受压力。 我们可以再次使用读取内核维护的计数器的工具(Windows和Unix),或使用VTune(Intel)或CodeAnalyst(AMD)之类的工具。

尽管CPU利用率可能是一个问题,但I / O或锁定绑定的应用程序更可能会对CPU表现出强烈的厌恶感。 这种厌恶感可能如此强烈,实际上CPU利用率会随着负载的增加而降低。 但是,您会看到内核CPU利用率将占据整体CPU利用率的很大一部分。

把垃圾带出去

除了查看硬件之外,我们还需要考虑JVM可能带来的影响。 JVM提供给我们的主要资源是线程和内存(Java堆空间)。 大堆会导致您的应用程序长时间停滞。 小堆会经常产生短时间的停顿。 无论哪种情况,管理内存的过程(垃圾回收)都会消耗大量的CPU。 长话短说,堆大小不正确会导致JVM进行比通常所需更多的工作,并且正常工作的JVM会从应用程序中窃取CPU周期。 与内核CPU利用率不同,系统报告的JVM CPU利用率没有细分为运行垃圾收集所花费的时间和运行应用程序所花费的时间。

要测量垃圾收集器的效率(或低效率),我们需要监视垃圾收集活动。 我们可以通过在命令行上设置-Xverbose:gc标志来实现。 这将导致垃圾收集活动摘要记录为标准输出。 通过使用GC日志中找到的数字,我们可以计算GC吞吐量或GC效率。

GC效率定义为在应用程序运行期间花费在垃圾回收上的时间。 由于GC在应用程序运行时的正常运行过程中可以运行1000次,因此最好使用诸如HP的JTune的Tagtram的GCViewer(均免费提供)之类的工具进行测量。 GC效率高于10%表示需要调整JVM堆。 如果CPU利用率高且GC运行正常,则很可能算法效率低下有问题。 为了诊断这种可能性,我们将转向执行分析器。 同样,在使用探查器之前,最好尝试通过查看框来缩小问题的范围。

线程和线程池

应用服务器供应商很早就了解到,让每个请求都产生一个新线程可能会Swift破坏其他运行良好的系统的稳定性。 解决方案是引入线程池。 线程池通过限制它可以处理的请求数来限制应用程序中的活动级别。 线程池的好处在于,负载下的系统应保持最大吞吐量。 在高负载下,某些请求可能需要等待很长时间才能得到服务。 调整线程池的大小是一个可调参数,可以对性能产生巨大影响。 游泳池太大,您就没有优势了。 太小,将有可能无法处理的请求。 这会增加他们的响应时间。 知道是否设置适当平衡的唯一方法是监视活动线程的数量,响应时间以及关键系统资源的利用率。

有几种方法可以推断您的线程池太小。 大多数涉及将完整的往返时间与给定请求的服务器内部响应时间进行比较。 如果网络延迟无法解决很大的差距,那么线程池可能太小。 另一方面,如果有一个较大的缺口无法解决,并且您的硬件表明您的池太大,则可能是因为您没有足够的硬件或正在遭受算法的困扰效率低下。 无论哪种方式,您都可以了解到下一步的价值。

如果我们取消了硬件,并确定已正确配置了JVM,则只需考虑锁争用和与外部系统的交互。 这些情况中的每一个都以线程停止为特征,因此无法执行“有用的工作”。 用引号引起来是有用的,因为毫无疑问,与信用卡服务进行交互显然是有用的工作。 也就是说,长时间的停顿可能表明应该异步处理事务,从而腾出空间来执行其他有用的任务。

避免代码

在从下到上的调查过程中,我们可以看到目标是消除在开始查看代码之前可能消除的尽可能多的潜在瓶颈。 我们还想利用从系统监视中获得的线索来帮助我们在开始对问题应用分析工具时缩小焦点或缩小搜索范围。 在大多数情况下,我们要做的最后一件事是查看代码。 实际上,如果您觉得有必要开始深入研究代码,那么您很可能没有获得正确的度量标准,无法准确地告诉您要查找的位置。 可以肯定的是,有时您需要在代码中翻阅,但是肯定要避免这种活动,因为这会导致猜测,而猜测是所有性能调整活动的祸根。

结论

实际的应用程序将创建大量数据,需要大量搜索才能发现潜在的瓶颈。 鉴于工具可以产生大量数据,团队尝试捷径并猜测潜在问题并不奇怪。 在某些时候,这些猜测是正确的,但有时它们往往会被证明是错误的。 困难在于猜测时您会发现结果不一致。 该框的目的是通过向我们展示如何对调查进行排序来消除猜测。 它还可以帮助我们理解在系统的每个主要组件中什么是重要的。 有了团队合作,团队应该能够提高发现和消除性能瓶颈的效率。

翻译自: https://www.infoq.com/articles/the-box/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

免费节点2:使用捷径添加

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值