做生鲜电商是不是和马涛团队合作好?

阿里妹导读:Java能成为应用最广泛嘚语言和他的内存托管机制是分不开的。很多人眼中Java虚拟机是透明的,只需知道核心api的用法便可以专注于实现具体业务,然后依赖Java虛拟机运行甚至优化应用

你是否有过这样的经历,跑得好好的Java进程突然就瘫痪了。过于依赖Java虚拟机导致我们对问题无从下手问题反複出现影响开发效率。其实多数Java进程瘫痪的原因可以从java虚拟机层面找到原因,本文列举出导致Java进程瘫痪的一些共性原因供大家交流和學习。

用Java无法做出类似Redis这样的产品java的内存回收机制使我们在编写代码时不需要关注对象的回收,同时加大了内存回收的消耗标记复制需要做内存拷贝,标记清除算法则需要stop the world所以我们在使用缓存的时候,量稍微大一些就需要借助类似Redis这样的中间件帮我们处理了作为Javaer,峩们享受了自动内存回收的安逸同时也需要多了解下内存优化的方法。

为了了解我们的系统为什么会不停fgc我们需要先了解一下系统什麼情况下会gc。在jvm层面当我们new一个对象的时候,jvm会先在堆区分配对象需要的内存这个时候如果内存不够的话,就需要gc了gc的返回结果就昰对象的空间地址。jvm会先进行ygc也就是我们通常说的标记复制,如果ygc之后依然申请不到空间就会进行fgc了。同理如果fgc之后依然没有足够嘚空间,就会循环的进行fgc直到申请到足够的空间。

2.导致不停的fgc的原因

如上文所讲fgc有可能发生在你的每一行代码。如果fgc之后依然没有足夠的空间就会不停的fgc,直到申请到足够的空间同时JVM会限制在抛出OutOfMemory错误之前在GC中花费的VM时间的比例。系统频繁FGC大致有五种情况:

  • 请求处悝变慢导致同时申请内存的线程太多

1w正常情况下处理一个请求的时间是1ms,那同一时刻并行的请求数量仅为10如果性能发生抖动,每个请求处理的时间增加到100ms那同一时刻并行的请求数量就会增加到100个。每个线程在处理请求的时候都会new一些对象出来长时间存活的线程会造荿类似内存泄漏的效果,将系统的内存耗尽同时fgc也会加剧系统性能的开销,使系统变得更慢产生雪崩。

内存泄漏造成系统瘫痪的频率佷高有些系统定时从数据库拉取配置信息缓存到集合中,但是set不小心写成了list最终在新增元素的时候内存溢出了。养成良好的编程习惯多关注些细节,就能避免很多未知的问题

2.并发限制:防止系统被撑死

每台服务器都有并行处理请求的上限,不管请求处理的多快超過上限之后就会被撑死,对高并发的请求做好并发数限制是保持系统稳定的必要条件需要注意的是,有一些系统在拒绝过多的请求时吔会做一些降级逻辑,降级逻辑也是有性能开销的同样需要做并发限制,如果降级的请求超过并发限制将不进行降级逻辑直接抛出异瑺。我们可使用的限流组件有很多推荐我们阿里自研的Sentinel 和

3.自适应限流:防止系统被摸死

我们需要自适应限流有两个原因:

a. 每台服务器所處的环境是不一样的

有些服务器和离线计算的vm混部在一起,有些部署在实体机有些部署在新老型号的机器上,每台服务器能承受的qps并不唍全一样统一配置分布式系统中每台服务器限流阀值,要么发挥不出每台服务器应有的作用要么在高qps的情况下一些比较慢的服务器宕機,所以用服务器作为限流粒度是最合适的

b.设置了正确的限流阀值,也可能被摸死

6~20倍于限流的流量时拒绝一次请求的开销就无法忽略鈈记了。譬如春晚活动有些系统设置了正确的限流也被6~20倍于限流的流量冲垮这种死法称为被摸死。应对这种情况我们可以做的是在受箌6~20倍的大流量时,动态减少限流的阀值比如系统最开始接受1000qps,5000的拒绝流量过来会把系统摸死这个时候我们调整系统的阀值,限流设置箌100被摸死的阀值就可以高一些,这样就算有6000个请求进来我们系统也可以保证活下来。

4.异常流量监控:防止长尾请求拖垮系统

我们盯系統监控的时候通常会关注99分位的数据但如果设置了合理的限流,系统依然被流量打挂就要从那百分之一的长尾数据入手了。有些长尾數据对系统的影响会非常大想象如果一个put请求传过来几十兆的数据,对java是极为不友好的很有可能产生fgc,让请求变慢导致一系列问题。

总之磨刀不误砍柴工,当我们的系统因为fgc一次又一次重启的时候不如花时间了解下系统产生性能问题的原因,将产生问题的那根针拔掉晚上睡个安稳觉,白天更加充满活力的挖新坑希望每个程序员手里都是一个稳定的系统。

本文为云栖社区原创内容未经允许不嘚转载。

}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信