一.问题
循环调用同一个接口,调用100次,其中有95次或是98次都是几十毫秒返回,但是有那么几次一秒左右才返回。接口相同,参数相同,返回时间怎么差异这么大?这个问题困扰了我很长时间,经过一段时间的研究终于知道原因了,起初我猜测可能的原因如下:
1:难道是网络问题?
2:难道是缓存问题?
二.分析问题
1:网络延迟
服务同属于一个局域网,网络延迟不会超过5ms,所以不是网络延迟造成的。
2:没有命中缓存
如果没有命中缓存,也应该是第一个请求没有命中,后续的请求就会从缓存中拿数据了。(我使用的缓存策略是从关系型数据库中读取数据后,会写到redis中)
3:不是网络延迟,也不是缓存问题,那就只能是服务本身的问题,服务除了正常接收请求外,还会做一件很重要的事,那就是垃圾回收。因此查看了那个请求慢的时间点,再查看服务的垃圾回收记录,发现刚好一致。因此可以证明,偶发的请求慢,是因为遇到了垃圾回收。
三.获取垃圾回收信息
通过性能计数器来获取垃圾回收的信息,可以获取如下信息:
1:获取0代、1代、2代对象的回收次数
2:获取1代堆、2代堆和大对象堆大小
3:代码
- 
获取一个实例名称(要监控对象) 
  
- 
根据类型名称、计数名称、实例名称创建新能计数器,并且获取垃圾回收次数(此处是获取1代对象的垃圾回收次数) 
  
- 
运行代码,查看结果。6 就代表了从服务启动以来,进行的1代对象的垃圾回收次数 
  
四.实战
已经介绍了如何获取垃圾回收的信息,那么在实际工作当中如何应用呢,答案也很简单,只需要做两件事,如下:
1:服务要支持获取0代、1代、2代对象的回收次数的功能
2:间隔3秒或是5秒将回收次数存放到数据库中。当发现请求有延迟的情况,可以查看数据库中的数据,在那个时间点是否存在垃圾回收。
五.另外
也有可能是其他原因,请高手指点…
 
                   
                   
                   
                   
                             本文探讨了一个Java服务在循环调用同一接口时,出现少数请求响应时间显著延长的问题。通过对网络延迟、缓存命中情况的排除,作者发现问题是由于垃圾回收导致。通过性能计数器收集垃圾回收信息,确认了这一猜想。解决方案包括服务增加监控GC次数的功能,并定期存储到数据库,以便在请求延迟时排查。
本文探讨了一个Java服务在循环调用同一接口时,出现少数请求响应时间显著延长的问题。通过对网络延迟、缓存命中情况的排除,作者发现问题是由于垃圾回收导致。通过性能计数器收集垃圾回收信息,确认了这一猜想。解决方案包括服务增加监控GC次数的功能,并定期存储到数据库,以便在请求延迟时排查。
           
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   552
					552
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            