news 2026/6/10 19:12:12

顶级Java才懂的,长尾请求hack工具!

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
顶级Java才懂的,长尾请求hack工具!

百分位

有时候,我们某些重要的服务,对每个请求的延迟忍受度都很低。如果我们用比较专业的词来描述的话,那就是:我们无法忍受任何长尾请求,即使平均响应时间非常的短。

这就需要一种指标来测量这种情况。为了解决这个问题,一个比较常用的指标,就是百分位数(Percentile)。

如果非要找出一种形状的话,那它就是请求分布的直方图。

百分位可以这么理解。如果我们圈定一个时间范围,把每次请求的耗时加入到一个列表中,然后,按照从小到大的顺序将这些时间进行排序。这样,我们取出某个位置请求的耗时,这个数字 就是TP值。可以看到,TP值(Top Percentile)和中位数、平均数等是类似的,都是一个统计学里的术语。

它的意义是,超过N%的请求,都在X时间内返回。比如TP90=50ms,意思就是超过90th的请求,都在50ms内返回。

这个指标能够反映出应用接口的整体响应情况。比如,某段时间发生了长时间的GC,就会影响高百分位的请求耗时增加。

我们一般分为Tp50、TP90、TP95、TP99、TP99.9等多个段,对高百分位的值要求越高,对系统响应能力的稳定性要求越高。

对于普通的百分位分布,像Dropwizard、MicroMeter、OpenTelemetry等组件,也会累积一些直方图到监控指标里,如果你使用SpringBoot等组件,你会发现这些值存在于le中。

http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="0.001",} 0.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="0.001048576",} 0.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="0.001398101",} 0.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="0.001747626",} 0.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="0.002097151",} 0.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="0.002446676",} 0.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="0.002796201",} 0.0 // 54 other lines here http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="12.884901886",} 3.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="14.316557651",} 3.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="15.748213416",} 3.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="17.179869184",} 3.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="22.906492245",} 3.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="28.633115306",} 3.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="30.0",} 3.0 http_server_requests_seconds_bucket{exception="None",method="GET",outcome="SUCCESS",status="200",uri="/foo",le="+Inf",} 3.0

这些值都是估计值,采用了插值统计的方式,精度其实是受损的。如果我们的服务有更高的要求,要求抖动尽可能的少,那么我们就需要更其他的工具支持。

HdrHistogram

HdrHistogram,可以用较少的资源,来计算平均值、中位数等,且拥有较高的精度。认识HdrHistogram,是从Hytrix依赖中发现的,Hytrix用它来统计latency。

要使用它,我们只需要在pom中引入maven坐标即可。

<dependency> <groupId>org.hdrHistogram</groupId> <artifactId>HdrHistogram</artifactId> <version>2.1.12</version> </dependency>

使用的时候,我们只需要传入所需要的精度就可以了。

Histogram HISTOGRAM = new Histogram(TimeUnit.MINUTES.toNanos(1), 3);

比如,上面这行代码,就定义了一个纳秒维度的精度。也就是说,1分钟之内的请求,都可以使用纳秒来描述请求的耗时。

它有两个参数。第一个参数是线性的区间分割方式(本质上就是数组);第二个参数是指数的线性分割方式。第一种精确,第二种占用内存少。上面的设置,如果我们有超过1分钟的请求耗时,这个桶是放不下这种数据的。

然后,在需要记录时间的地方调用如下方法。

histogram.recordValue(time);

结果分析

最后,我们使用output方法输出测试结果即可。

HISTOGRAM.outputPercentileDistribution(System.out, 1000.0);

一个测试样例结果如下:

Value Percentile TotalCount 1/(1-Percentile) 0.000 0.000000000000 238 1.00 0.041 0.100000000000 208090 1.11 0.042 0.200000000000 620768 1.25 0.042 0.300000000000 620768 1.43 0.083 0.400000000000 820209 1.67 0.166 0.500000000000 1003029 2.00 1.541 0.550000000000 1117185 2.22 1.625 0.600000000000 1223882 2.50 1.667 0.650000000000 1325848 2.86 1.708 0.700000000000 1426775 3.33 1.750 0.750000000000 1566704 4.00 1.750 0.775000000000 1566704 4.44 1.792 0.800000000000 1658827 5.00 1.792 0.825000000000 1658827 5.71 1.875 0.850000000000 1717764 6.67 2.000 0.875000000000 1753302 8.00 2.251 0.887500000000 1778274 8.89 2.543 0.900000000000 1800741 10.00 3.043 0.912500000000 1825223 11.43 3.333 0.925000000000 1853576 13.33 3.459 0.937500000000 1883704 16.00 3.501 0.943750000000 1902088 17.78 3.501 0.950000000000 1902088 20.00 3.543 0.956250000000 1914577 22.86 3.625 0.962500000000 1932711 26.67 3.667 0.968750000000 1939228 32.00 3.709 0.971875000000 1944415 35.56 3.793 0.975000000000 1951960 40.00 3.875 0.978125000000 1956422 45.71 4.127 0.981250000000 1962509 53.33 4.459 0.984375000000 1969250 64.00 4.543 0.985937500000 1974203 71.11 4.583 0.987500000000 1976011 80.00 4.627 0.989062500000 1979231 91.43 4.711 0.990625000000 1982267 106.67 4.835 0.992187500000 1984844 128.00 4.919 0.992968750000 1985983 142.22 5.083 0.993750000000 1987744 160.00 5.251 0.994531250000 1989220 182.86 5.543 0.995312500000 1990682 213.33 5.919 0.996093750000 1992236 256.00 6.167 0.996484375000 1993013 284.44 6.543 0.996875000000 1993764 320.00 7.043 0.997265625000 1994539 365.71 7.667 0.997656250000 1995330 426.67 8.375 0.998046875000 1996133 512.00 8.959 0.998242187500 1996507 568.89 9.839 0.998437500000 1996884 640.00 10.879 0.998632812500 1997275 731.43 12.127 0.998828125000 1997660 853.33 13.879 0.999023437500 1998050 1024.00 14.879 0.999121093750 1998248 1137.78 16.295 0.999218750000 1998441 1280.00 18.175 0.999316406250 1998634 1462.86 20.223 0.999414062500 1998833 1706.67 23.503 0.999511718750 1999026 2048.00 26.511 0.999560546875 1999124 2275.56 29.583 0.999609375000 1999219 2560.00 33.183 0.999658203125 1999317 2925.71 37.343 0.999707031250 1999416 3413.33 43.071 0.999755859375 1999512 4096.00 47.103 0.999780273438 1999561 4551.11 53.183 0.999804687500 1999610 5120.00 61.471 0.999829101563 1999659 5851.43 77.823 0.999853515625 1999708 6826.67 97.087 0.999877929688 1999756 8192.00 117.759 0.999890136719 1999781 9102.22 143.231 0.999902343750 1999805 10240.00 171.519 0.999914550781 1999830 11702.86 224.255 0.999926757813 1999854 13653.33 289.279 0.999938964844 1999878 16384.00 325.375 0.999945068359 1999891 18204.44 375.295 0.999951171875 1999903 20480.00 422.143 0.999957275391 1999915 23405.71 499.711 0.999963378906 1999927 27306.67 581.119 0.999969482422 1999939 32768.00 685.567 0.999972534180 1999946 36408.89 769.023 0.999975585938 1999952 40960.00 844.799 0.999978637695 1999958 46811.43 1065.983 0.999981689453 1999964 54613.33 1352.703 0.999984741211 1999970 65536.00 1603.583 0.999986267090 1999973 72817.78 2529.279 0.999987792969 1999976 81920.00 2879.487 0.999989318848 1999979 93622.86 3221.503 0.999990844727 1999982 109226.67 5070.847 0.999992370605 1999985 131072.00 6287.359 0.999993133545 1999987 145635.56 6922.239 0.999993896484 1999988 163840.00 8085.503 0.999994659424 1999990 187245.71 10199.039 0.999995422363 1999991 218453.33 10600.447 0.999996185303 1999993 262144.00 30572.543 0.999996566772 1999994 291271.11 30572.543 0.999996948242 1999994 327680.00 31621.119 0.999997329712 1999995 374491.43 32817.151 0.999997711182 1999996 436906.67 32866.303 0.999998092651 1999997 524288.00 32866.303 0.999998283386 1999997 582542.22 32866.303 0.999998474121 1999997 655360.00 74186.751 0.999998664856 1999998 748982.86 74186.751 0.999998855591 1999998 873813.33 74842.111 0.999999046326 1999999 1048576.00 74842.111 0.999999141693 1999999 1165084.44 74842.111 0.999999237061 1999999 1310720.00 74842.111 0.999999332428 1999999 1497965.71 74842.111 0.999999427795 1999999 1747626.67 86114.303 0.999999523163 2000000 2097152.00 86114.303 1.000000000000 2000000 #[Mean = 1.357, StdDeviation = 108.037] #[Max = 86114.303, Total count = 2000000] #[Buckets = 24, SubBuckets = 2048]

Percentile就是百分位。一般的业务关注TP95,要求较高的业务关注TP99,甚至TP99.99,上面的测试结果也提供了这种细分。当然,精度是在我们的构造参数里就提供了的,这些数据非常可信。

结果的下面是一些统计信息。比如,我的这段关键代码,调用了2000000次,每个调用都在1.3ns左右,但最大的也有86114.303ns。

至于最后的Buckets和SubBuckets,就涉及到HdrHistogram的一些内部原理,也就是内部的一些参数,我们倒可以不用关注它。

End

HdrHistogram是为了追求性能和稳定性的代码而生的,它才是真正的平均主义--希望所有的请求尽量的平均,没有长尾请求。

比如证券交易系统,你肯定不想自己的那笔单子正好碰上千万分之一的那种延迟。

一般这样的服务,对GC也有较高的要求,容不得半点延迟。像CMS这种动不动就Full GC的垃圾回收器,自然是不适合使用的。

评判服务的响应能力,除了一些耳熟能详的统计工具,必要的时候,我们还可以祭出更强大的工具,来助力达成这个目标。

HdrHistogram显然就是这种存在,你一定不想错过它。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 20:37:21

为什么头部保险公司都在用Open-AutoGLM做到期提醒?真相令人震惊,

第一章&#xff1a;为什么头部保险公司都在用Open-AutoGLM做到期提醒&#xff1f;真相令人震惊在保险行业数字化转型的浪潮中&#xff0c;客户保单到期提醒的自动化与精准化已成为提升续保率的关键环节。越来越多头部保险公司悄然采用名为 Open-AutoGLM 的开源智能提醒系统&…

作者头像 李华
网站建设 2026/6/10 14:10:24

C++类的构造顺序

1. C 类成员与自身的构造和析构顺序 默认先构造类成员&#xff08;类成员的构造顺序就是类成员在类中被书写的顺序&#xff09;&#xff0c;然后再构造类本身。参看 “测试代码 1”。默认先析构类本身&#xff0c;然后再析构类成员&#xff08;类成员的析构顺序就是类成员在类中…

作者头像 李华
网站建设 2026/6/10 14:07:21

YOLOv11 改进 - C2PSA | C2PSA融合DiffAttention差分注意力:轻量级差分计算实现高效特征降噪,提升模型抗干扰能力

前言 本文介绍了 DiffCLIP,一种将差分注意力机制集成到 CLIP 架构的视觉 - 语言模型,并将其应用于 YOLOv11。差分注意力机制通过计算两个互补注意力分布的差值,抵消无关信息干扰。单头差分注意力将 Q 和 K 拆分,分别计算注意力分布后做差值融合;多头差分注意力则每个头独…

作者头像 李华
网站建设 2026/6/9 23:37:52

体检报告查询进入AI时代:Open-AutoGLM究竟带来了哪些颠覆性变革?

第一章&#xff1a;体检报告查询进入AI时代&#xff1a;Open-AutoGLM的崛起随着人工智能技术在医疗健康领域的深度渗透&#xff0c;体检报告的智能解析正迎来革命性变革。传统依赖人工解读的模式逐渐被高效、精准的AI系统取代&#xff0c;而Open-AutoGLM作为新一代通用语言模型…

作者头像 李华
网站建设 2026/6/10 14:08:23

揭秘Open-AutoGLM智能纪要生成:如何5分钟自动生成高质量会议记录

第一章&#xff1a;揭秘Open-AutoGLM智能纪要生成&#xff1a;5分钟打造高质量会议记录在快节奏的现代办公环境中&#xff0c;高效、准确地生成会议纪要是提升团队协作效率的关键。Open-AutoGLM 作为一款基于大语言模型的开源工具&#xff0c;专为自动化会议纪要生成而设计&…

作者头像 李华
网站建设 2026/6/10 15:56:18

揭秘Open-AutoGLM待办同步黑科技:如何实现跨平台零延迟数据同步

第一章&#xff1a;揭秘Open-AutoGLM待办同步黑科技&#xff1a;跨平台零延迟的奥秘 在分布式任务管理场景中&#xff0c;Open-AutoGLM 凭借其创新的同步机制实现了跨平台待办事项的“零延迟”更新。这一能力背后融合了事件驱动架构、增量数据同步与智能冲突解决策略&#xff0…

作者头像 李华