㑈手机版
  • 首页
  • 英语学习
  • 人物介绍
  • 旅游攻略
  • 汽车知识
  • 电脑数码
  • 生活常识
首页 电脑数码

处理一起生产集群CPU 100%问题

时间:2024-02-14 14:40:10  编辑:IT技术控

背景

收到一生产环境报警消息,一个集群的CPU利用率直接飙升到了100%

领导说让我处理,但是我还不知道这个集群是干啥用的。。

找问题

看监控

先看下监控看下能不能看到有什么发现,发现这个集群消费MQ消息的数量突增,有几个尖刺状的流量已经达到了每分钟8W+,

很有可能是尖刺流量造成的这个问题,但是在8:30之后流量已经趋于缓和,但是CPU还是一直100%并没有降下去。

查看jvmGC状况

于是登录服务器看下jvm的运行状况。 通过 jstat -gcutil命令查看服务的GC情况,发现已经进行了500多次的FullGC。 关键点在于图中的 534 -> 535次的FullGC内存一点都没有被回收下去,这就很可怕了。

arthas查看服务整体状态

于是想用arthas查看下是否是内存分配有问题到这的内存无法回收,

如图:发现jvm的非堆内存的利用率已经满了,那么很有可能是这个问题导致的。 于是想办法调整下这个内存的大小,打开项目中配置的启动命令发现已经设置了非堆内存的大小,但是这里并没有生效 nohup java -Xms2g -Xmx2g -Xmn1g -Xss1024K -XX:PermSize=512m -XX:MaxPermSize=512m 启动参数长这个样子,其中 -XX:PermSize=512m就是设置非堆内存大小的。但是没有生效。。。。 为什么没生效呢???

jdk7->jdk8内存结构的调整

我们都知道7到8的改动很大,其中一块改动就是jdk8将以前的永久代。 也就是说**_-XX:PermSize_**这个参数在jdk8中已经没有用了,但是这个陈旧的项目并没有人去修改这个参数。 先调整下这个参数试试。 关于永久代和元空间的介绍:
www.cnblogs.com/paddix/p/53…
cloud.tencent.com/developer/a…

分析堆内存

内存无法回收一般是由内存泄漏,或者有大对象无法回收造成的,虽然上面找到一处问题,但是并不能很好的解释为什么内存无法被回收。 分析下堆内存,

  • 使用 jmap -dump:live,format=b,file=heap.hprof 命令将堆内存的快照导出,下载下来。
  • 使用 jvisualvmjdk自带的工具分析下内存情况

类的分布情况,最大的 cahr[] string这个没什么问题,第三名和第四名就有问题了, 这两个一个是 阻塞队列、一个是业务代码中的一个内部类。 一个内部类怎么会占用这么大的比重,看下代码

java复制代码ExecutorService executorPool = Executors.newFixedThreadPool(numberOfCore);
RateLimiter handleLimit = RateLimiter.create(20, 10, TimeUnit.SECONDS);

ESBClient client = new ESBClient(key_esb);
client.setReceiveSubject(new ESBSubject(INFO_DEL_SUBJECTID, INFO_DEL_CLIENTID,SubMode.PULL));
client.setReceiveHandler(new ESBReceiveHandler() {

    @Override
    public void messageReceived(final ESBMessage msg) {
        try {
            final String msgStr = new String(msg.getBody(), "UTF8");
            executorPool.execute(new Runnable(){
                public void run() {
                    try {
                        handleLimit.acquire();
                        handleDelMsg(msgStr);
                    } catch (Exception e) {
                        e.printStackTrace();								
                    }
                }
            });

        } catch (Exception e) {
        }

    }
});

大家一起看下这端代码有没有什么问题,

  1. 第一点,这里使用了一个一定不能使用的线程池创建方法,Executors.newFixedThreadPool这个方法创建出来的线程池里面的任务队列是个无界队列。
  2. 第二点这里用到了限流,RateLimiter这里应该是防止流量过大下游扛不住。

但是为什么要在任务里面限流呢?在线程任务里面限流这个任务放到线程池中,线程在执行任务的时候就会等待 拖慢了整个线程池的运行速度,并发量高的时候大量的任务被放到队列中,而队列又是个无界队列 一下就会把jvm的内存打满,并且这些任务都是被线程池引用的状态无法回收。 这样jvm就会一直进行GC,已经在队列中的任务拿不到CPU资源无法执行,GC又无法回收内存导致了整个集群挂掉。

问题修改

除了修改元空间的启动参数,这里还需要修改代码如下

java复制代码private static final ExecutorService executorPool = new ThreadPoolExecutor(numberOfCore, numberOfCore * 2, 10, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1024), new DefaultThreadFactory("custom"), new ThreadPoolExecutor.CallerRunsPolicy());
RateLimiter handleLimit = RateLimiter.create(20, 10, TimeUnit.SECONDS);

ESBClient client = new ESBClient(key_esb);
client.setReceiveSubject(new ESBSubject(INFO_DEL_SUBJECTID, INFO_DEL_CLIENTID,SubMode.PULL));
client.setReceiveHandler(new ESBReceiveHandler() {

    @Override
    public void messageReceived(final ESBMessage msg) {
        try {
            handleLimit.acquire();
            final String msgStr = new String(msg.getBody(), "UTF8");
            executorPool.execute(new Runnable(){
                public void run() {
                    try {
                        handleDelMsg(msgStr);
                    } catch (Exception e) {
                        e.printStackTrace();								
                    }
                }
            });

        } catch (Exception e) {
        }

    }
});
  1. 首先将限流器移到提交任务的时候限流。
  2. 修改线程池的参数,有界队列、当队列满了调用者执行任务。由于我们这里消费MQ使用的是PULL模式,所有当任务消费不过来的时候就不会去拉消息了,所以采用这个 CallerRunsPolicy策略

后续关注

内存和GC恢复正常

  • 本文分类:电脑数码
  • 浏览次数:258 次浏览
  • 本文链接:https://www.deibaike.com/diannaoshuma/rjZ0AG4Ndw.html
  • 上一篇 > cpu没有核显 ,为何还能流畅播放视频?
  • 下一篇 > 一招提升电脑CPU40%的性能!解决CPU经常100%的问题
相关文章
  • 什么是冷冻信用卡(“坑爹”的信用卡冷冻提额)
    近日,有我爱卡论坛的网友发帖称,自己信用卡的额度原来是20000,在冷冻3个月后,接到短信提醒说额度调整为2000元。对此,网友大呼,这种冷冻提额实在“太坑爹”了。据了解,原来这位网友想尝试一下“传说中”的交行冷冻提额,便打客服电话咨询,客服自称这个系统每个月会审核用户的用卡情况,进行调整,说是对长[详细]
  • 商险都包括什么东西(商业保险保的是什么?)
    问题一:万一得了大病怎么办?在人的一生中,有两个我们无法预知的突发事件:疾病和意外。如果一个人真的遭遇大病或残疾,有三笔费用是必须要面对的:医疗费、康复费、收入损失费。社保可以为你解决基本医疗费的问题,但如果得了重病,需要进口药或者复杂的手术,那就只能自费了。这是一笔巨大的开支,特别是病后的恢复。医[详细]
  • 担保什么意思(为他人提供担保要谨慎)
      近日,吴起县人民法院成功调解了一起借贷担保纠纷。  2011年5月24日,原告张某某为好友陈某某在被告某银行处借款提供了个人担保。该笔借款期限从2011年5月24日至2014年5月22日。张某某提供担保的保证期限为借款到期之日起两年内,即从2014年5月22日至2016年5月22日。借款到期后陈[详细]
  • 为什么电工套管有多长(一文教会你选购电工套管)
    装修大计,水电先行,电路作为隐蔽工程,一旦发生事故,轻则全屋短路,重则引发事故。可见做好电线布局十分重要,电线不能直接埋进墙体或者地面,应该进行穿线,防止电线绝缘层受损。因此,一款好的电工套管显得十分重要。然而,市面上的电工套管琳琅满目,如何选择一款性价比高、质量过硬的电工套管成了摆在业主面前的一道[详细]
  • 店里为什么要放植物(5种“招财花”,生意人养上“它”财源滚滚)
    爱养花的朋友来自各个领域,商人也是其中之一。大部分花店都为很多商务场所和家庭提供了各种花卉盆栽。他们对花卉的挑选和摆放都有很高的要求。今天这几种很受商业人士喜爱的花,不仅好看还有好寓意!白掌白掌,也被称为“一帆风顺”,代表着万事顺利。它四季常青,不会掉叶,适合在酸性泥炭土中生长,喜欢半阴半阳的环境,[详细]
最新推荐
  • 什么是冷冻信用卡(“坑爹”的信用卡冷冻提额)
  • 商险都包括什么东西(商业保险保的是什么?)
  • 担保什么意思(为他人提供担保要谨慎)
  • 为什么电工套管有多长(一文教会你选购电工套管)
  • 店里为什么要放植物(5种“招财花”,生意人养上“它”财源滚滚)
  • 为什么紫檀有黑斑(小叶紫檀变色陷阱!)
  • 酒店为什么都地毯(酒店地毯如何选择)
  • 什么化肥好用又安全(种菜还是用这五种肥料)
  • 为什么实木也有甲醛(木地板甲醛多久能挥发完?)
  • 为什么鱼池要做循环水(鱼池循环水系统怎么做,循环水有什么好处)
热门推荐
  • 庐山的风景特色:自然之峰与文化之境
  • c盘的东西怎么清理 ?电脑c盘垃圾太多不知道怎么清理一招教你解决
  • 贵州三都县有什么旅游景点?3大传统村落,这里藏着不一样的水族风情
  • 居民医保异地就医怎么办理手续 ,哪些人适用?一文了解→
  • 汽车托运|车辆是如何装载托运的呢?
  • 你知道“get off your high horse的俚语 是什么意思吗?
  • 车保险保费上涨怎么算 走保险还是私了?次年保费涨多少?先报案不理赔”不算出险?
  • c盘temp清理? 电脑越用越卡怎么办?5个方法教你释放C盘空间,瞬间多出几个G
  • kick back俚语”不是踢回去!职场人士一定要懂!
  • 车险第三者二百万保费多少钱 ,买多少合适?老司机算笔账

网站内容来自网络,如有侵权请联系我们,立即删除!
Copyright © 得百科 琼ICP备2023010365号-2