背景
生产/UAT环境,运维集成了pinpoint监控。后来出来个问题:项目启动非常慢从40秒变成了200秒
了解pinpoint原理
土味百度易得
ok,和预想差不多,代理方法,然后远端大数据持久化
顺带学习下为什么选择HBase
1. Write-Ahead logs 可以提升最近查询效率?即使有也是很常见的,不算特点了。
2. 廉价硬件需求,链路追踪又不要什么高性能高并发,HBase能单一满足高并发就可以了,不是实时的所以几百ms不在乎
3. HBase不适合分析,但就一个链路监控能分析些啥,所以ok
4. HBase列式存储,横向分布式,横向扩容支持海量数据。且KV Nosql,不影响查询指定类似于日期的性能
各种花哨的功能都是堆积量,小开发就老老实实学下他是怎么实现代理的
我们自己的类都是被AppClassloader加载的,不破坏这个就没法代理所有我们自己的类,然后埋点上发监控信息。
所以必然在启动命令里,添加-javaagent:xxx.jar时,实现了代理所有的类;或者说启动命令还指定了什么什么代理main方法,然后pinpoint在代理main方法里去通过自定义类加载器加载所有类?
找个教程一看
-javaagent:/home/perf/pinpoint/pinpoint-bootstrap-2.2.2.jar -Dpinpoint.agentId=serviceName -Dpinpoint.applicationName=applicationName
只有指定agent类而已,那就一定是在这里实现的代理。也合理,毕竟刚才说的或者那种路子太野了,直接破坏了原有的加载lib等等一系列机制。
学习javaagent参数,参考javaagent使用指南 - rickiyang - 博客园 (cnblogs.com)
很显然是java自带的口子,然后符合Instrumentation的标准,jvm就会用你得agent类去代理,然后什么什么埋点上发就是堆积数量了。
ok结束,后面再查下pinpoint上发的源码逻辑,看看为什么会变慢那么多?
随便看看Pinpoint源码
这个大概是基础Trace拦截器,before和after分别代理记录各类信息
其中Trace类有多种实现,工厂提供
其中Async的实现其实也是封装的DefaultTrace,莫名其妙(其中close还是有不同的,不细究了)
那么可以认为拦截器全是同步的包括存储store方法,那么
-
上生产后卡了150多秒,按Hbase一次要100ms来看,就是千位数级别的类代理呗,
-
当然看源码里面它有优化缓冲提交什么的,但再粗略考虑class代理耗时,其实也差不多啦……吧
总之
是知道了,慢是合理的,代码不用自查了,其实这个问题也不是什么问题, 只是生产环境运维配的探针提前启动了,但当时应用还没起来,就死循环重启。
已经把探针启动时间延迟了,就修好了