java服务器优抛_调优Java服务器

java服务器优抛

随着成千上万的Java服务器在企业生产中运行,Java已成为构建生产系统的首选语言。 如果我们的计算机要表现出令人满意的性能,则需要定期进行调整。本文详细介绍了用于调整Java Server的技术。

衡量绩效

为了使我们的调整有意义,我们需要一种衡量性能改进的方法。 让我们了解两个关键性能指标:延迟和吞吐量。

  • 延迟测量操作的端到端处理时间。 在分布式环境中,我们通过测量发送请求和接收响应之间的完整往返时间来确定延迟。 在这些情况下,延迟是从客户端计算机测量的,并且还包括网络开销。
  • 吞吐量衡量服务器在特定时间间隔(例如每秒)中处理的消息数。 使用以下公式计算吞吐量:

吞吐量=请求数/完成请求的时间

理想情况下,我们希望以最小的延迟获得最大的吞吐量。 但是,在设计良好的服务器中,需要在吞吐量和延迟之间进行权衡。 例如,如下图所示,如果需要更高的吞吐量,则必须为运行系统提供更多的并发性,但是平均延迟也会增加。 通常,您需要实现最大吞吐量,同时将延迟保持在可接受的范围内。 例如,您可以在延迟小于10毫秒的范围内选择最大吞吐量。

下图捕获了服务器的典型行为。 如图所示,服务器性能是通过测量延迟和针对并发的吞吐量来衡量的。

在图中,“理想路径”是完美编写的服务器的理论性能图。 实际上,如果并发过多,大多数服务器将崩溃或降低性能。

调优/分析服务器

在性能分析会话中,我们尝试深入研究服务器并了解其行为,然后验证服务器是否可以发挥其潜能,或者找到提高其性能的方法。 我们使用剖析来解决三个目标:

  1. 提高吞吐量-最大化系统处理的消息数量
  2. 改善延迟-确保我们达到了响应时间SLA。
  3. 查找并修复泄漏(例如内存,文件,线程,连接泄漏)

正如我们所说,我们的目标是在使延迟保持在可接受范围内的同时实现最大吞吐量。 如果您根本没有进行任何调整,那么最好的方法就是调整吞吐量,因此让我们首先来看一下。

调整吞吐量

在开始之前,让我们了解是什么限制了性能。 将服务器理解为水流管道系统很有帮助; 增加并发性就像增加我们投入系统的水量一样。添加更多的水并不能确保有更多的水流过管道。 流量受系统最慢部分的限制。

同样,应用程序的性能由系统中最稀缺的资源决定。 计算机系统具有多种类型的资源。 CPU,内存,磁盘和网络I / O。 任何这些都可能限制我们系统的性能。

在尝试研究体外性能时,我们可以从增加负载开始,直到至少耗尽一种资源(因为您可能无法充分利用服务器的力量)。 这将有助于识别任何有限的资源,我们可以分配更多的资源,也可以更改系统以更谨慎地使用该资源。

接下来,让我们设置系统并运行代表性的工作负载。 (有关如何执行此操作的更多详细信息,请参阅我的博客 )。 在负载运行时,我们接下来应该确定各种资源的利用率。

基于最稀缺的资源,我们将服务器性能下降分为三类:

  1. CPU绑定-服务器在CPU上被阻止
  2. IO绑定-服务器由于磁盘或网络带宽而被阻止
  3. 延迟限制-服务器正在等待某些活动发生(例如,等待数据从磁盘传递到网络)

让我们研究示例系统中稀缺的资源。 首先,让我们在Unix / Linux上运行top命令。

(点击图片放大)

工程师经常犯的一个错误是对CPU进行性能分析,而没有先确定它是否真的是受CPU约束的用例。 尽管top命令显示的CPU使用率较低,但是计算机可能正在忙于执行IO(例如,读取磁盘,写入网络)。 平均负载是确定机器是否已加载的更好的指标。

平均负载表示OS调度程序队列中等待的进程数。 与CPU不同,当限制任何资源(例如CPU,网络,磁盘,内存等)时,平均负载将增加。 请参阅博客“ 了解Linux平均负载 ”以获取更多详细信息。

我们可以使用以下负载平均值来确定计算机是否已加载

  • 如果平均负载<内核数,则表示计算机未加载
  • 如果平均负载==内核数,则说明计算机已完全使用
  • 如果平均负载> = 4X内核数,则表明计算机处于高负载状态
  • 如果平均负载> =大约是内核数的40倍,则该计算机不可用

如果未加载计算机,则通常意味着它处于空闲状态。 许多因素都可能导致此问题,并且可以通过以下方式纠正此问题:

  1. 尝试增加负载(通常这意味着增加并发性)。 例如,仅使用一个或两个客户端测试服务器通常不会加载服务器。 它通常需要数百个客户端来加载服务器。
  2. 检查锁定配置文件(如果大多数线程被锁定或死锁,则吞吐量将降低)。 尽可能使用无阻塞数据结构查找并修复那些问题。 我们将在下面的“延迟调整”部分中更详细地讨论锁配置文件。
  3. 尝试调整线程池(有时系统配置的线程太少,导致其运行缓慢)。 例如,我经常发现增加Tomcat线程池中的线程数会增加吞吐量。
  4. 确保网络未饱和(如果网络已饱和,则进入计算机的有效负载可能会很小)。 在大多数计算机中,您可以使用Linux iftop命令进行检查。

另一方面,如果机器已装载,则显然它正在做某事,但是您仍然必须确保它忙于做有用的工作!

  • 确保您的应用程序是在同一台计算机上运行的唯一繁重的过程; 您不希望其他应用程序扭曲您的测试结果。
  • 如果不是,则通过顶部检查CPU利用率。 如果CPU使用率很高,请使用分析器查看CPU配置文件。

(点击图片放大)

例如,上图显示了使用JProfiler获取的CPU配置文件。 它显示了服务器的执行树(java方法),并标明了每种方法所花费的时间减去其子级所花费的时间。 检查占用大量CPU的方法,并确保它们在做有用的事情。 (注意:在本文中,我们使用JProfiler ,但其他产品(例如,流行的Yourkit Profiler以及与JDK 1.7和更高版本捆绑在一起的Java Flight Recorder)也可以使用类似的视图。)

  • 确定应用程序在垃圾回收(GC)上花费了多少时间。 如果超过10%,则需要调整JVM GC。 (您可以使用VisualVM GC插件之类的工具来检查开销。有关详细信息,请参阅我的博客中有关GC调整分析的文章 。)如果GC有问题,则探查器的分配视图可能会帮助您找到分配热点并进行修复。 Kirk Pepperdine的演讲是有关GC Tuning的很好资源。
  • 下一步是检查网络和磁盘的IO配置文件(假设您的程序将数据写入磁盘)。 以下屏幕快照显示了使用JProfiler拍摄的IO配置文件。 验证具有大量IO的节点确实位于预期发生它们的位置。 对数据库访问也执行相同的操作。

(点击图片放大)

  • 最后,检查您的计算机是否正在分页(例如, 在Linux中检查交换使用情况 )。 通常,您需要避免交换任何Java服务器,因为这将大大降低服务器的速度。 如果存在交换,则需要减少服务器的内存使用量或向主机添加更多的物理内存。

如果您已完成上述所有操作,但服务器仍未达到可接受的性能水平,则可能是服务器已达到极限。 您需要通过添加更多服务器来扩展规模,或者对其架构进行完整的重新设计。

调整延迟

高延迟是由处理请求中的长时间运行操作引起的。 磁盘访问,网络访问和锁定是长时间运行操作的常见原因。

在调整延迟时,首先要检查网络和磁盘配置文件(如上一节所述),然后尝试查找并减少IO操作的数量。 以下是一些可能的补救措施:

  1. 避免不必要的IO操作。 如果可能,请消除它们,或将其替换为缓存。
  2. 尝试将许多IO操作分批处理,这会将IO开销减少到一个IO操作。
  3. 如果您可以事先猜到需要什么数据,请尝试预取数据。

接下来让我们检查JVM的线程视图。 下图显示了线程数量和状态随时间变化的情况。 图中的红色带表示许多线程在锁上被阻塞。

(点击图片放大)

如果线程视图显示许多等待线程,则可以浏览“监视器和锁”视图,以找出导致阻塞的线程。

(点击图片放大)

JProfiler的以下屏幕截图显示了最长的时间,哪些代码被阻止,以及在这段时间内拥有该代码的锁。 以下是两个经验法则:

  1. 尽可能避免同步块和锁。 另外,通常最好使用java.util.concurrent包中的并发数据结构。

  2. 当您必须加锁或编写同步块时,请尝试尽快将其返回。 按住锁时,尽量减少长时间运行的操作(例如IO)。 并尝试避免从另一个锁或同步块中获取其他锁。

接下来检查客户端和服务器之间的网络行为。 您可以从“ ping”和“ iftop”之类的工具开始,但是您可能需要网络管理员的帮助进行详细调查。

最后一种选择是向系统引入更多服务器。 然后减少每个服务器看到的并发性,以减少等待时间,正如我们在本文前面与服务器性能曲线所讨论的那样。 杰夫·迪恩(Jeff Dean)在演讲“应对延迟的可变性”中解释道,一种极端的措施是运行服务器的两个副本并使用第一个结果。 此外,如果您需要非常低的延迟,请考虑针对此类用例设计的工具,例如LMX Disruptor

性能调优清单

我们讨论了吞吐量和延迟的调整。 正如您现在所了解的那样,调整Java服务器是一项棘手的工作,并且在那座冰山的水线之下隐藏着很多冰。 以下是我们讨论的步骤的摘要清单。 这可能不会告诉您如何描述所有内容,但是可以使您避免许多陷阱。

  1. 检查机器的平均负载。 如果> 4XNumberOfCores,则您的计算机正在全速运行,您可以跳到CPU调整部分。

  2. 您是否对系统造成了沉重打击? 尝试通过增加客户端程序中的线程数来模拟更多客户端。 如果这样可以提高吞吐量,则增加负载,直到吞吐量最大化。

  3. 您的线程是否空闲? 如果锁太多或线程太少,则系统可能无法提供完整的吞吐量。 使用探查器查看锁定配置文件并尝试将其删除。 尽管一些锁是最需要的。

  4. 尝试增加线程池中的线程数,然后检查是否可以提高吞吐量。

  5. 现在检查CPU配置文件中的热点

  6. 研究树视图,并确保所有热点都在预期的位置。 例如,XML解析器可能会消耗大量CPU。 但是,如果您发现某些意外情况占用了过多的CPU,则可以进行一些修复

  7. 检查内存和GC,如果GC吞吐量小于90%,则该调整GC了。 如果内存快要用完了(检查分页),请添加更多内存,看看是否有帮助。

  8. 查看数据库配置文件,并确保预期将承担最大的负载。

  9. 查看网络IO配置文件。 转至热点,确保所有主要文章都在您期望的范围内。 如果有一些不必要的IO,则会显示出来。

  10. 验证诸如基础网络和磁盘安装之类的资源是否到位

调优Java服务器可能很棘手,但结果却很美味。 有时,它看起来比工程更像艺术,但是按照我概述的步骤进行操作应该会使您受益匪浅。

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

java服务器优抛

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值