闲聊OOM

序言

    失败才有借鉴意义,成功的路只有一条,而失败的原因千千万,从失败中才能看到更多的东西。

    说者无意,听者有心,打人不打脸,不可能。。。还好,我朋友越来越多,现在,就剩下飘着的风了。。感觉单纯说技术的话,这个无所谓吧,会那么介意吗??

oom

    OOM有好多,喜欢用java的朋友估计经常看到oom,披着同样的外衣,相同的报错,相同的简称,不同的含义。

    在操作系统层面,有个oom,这是一个无情的杀手,只要你触碰到了底线,那就是杀。。。

640?wx_fmt=png

    

    OOM表示为out of memory,也就是超出了内存的使用,当一个进程申请内存的时候,操作系统进行分配内存,打开钱包一看,钱不够,欠钱的该还钱了,那么就有一个评分机制,欠钱最多的优先还钱,从而直接杀了占用内存最多的进程,emmm,一般就是java了。

    OOM的日志一般可以在dmesg指令中看到,也可以在/var/log/messages中看到。在查看一个进程的评分可以在如下图中看到:

640?wx_fmt=png

    在进行运行进程的时候,可以设置一个进程的分数,设置的参数是oom_score_adj,范围是-1000到1000,也可以设置参数oom_adj,范围是-16到16,kubelet的居然设置成了-999,差不多就是无限不能杀了,而oom_score表示当前进程的分数,这个分数一旦最高,那么就会被操作系统杀了。

    如何解决这种问题?关闭oom killer?如果关闭了,那么就可能会导致kernel panic,那么还是别关闭的好,当然你也可以设置成kernel panic之后,服务器重启,但是。。。又有什么意思呢?还是扩大服务器的内存好了,或者找出有问题的进程然后限制一下内存。

    oom这么无趣,为啥要说oom。。。

    java就不一样了,也会出现oom,但是很好玩的是,java中的oom不会有killer,也就是说,如果一个java进程里面有很多子线程,当一个线程出现oom之后,整个程序就崩溃了吗?

640?wx_fmt=png

    不可能。。。程序依旧健在。。。

    在进行健康健康的时候,如果是四层,那么就是telnet ip port,那么当一个子线程oom之后,其实整个端口还是ok的,依旧能连接,那么出现问题的现象将是当任务分配到oom的这个进程之后,服务就会挂掉,从而就会出现服务时好时坏的情况,这种情况怎么判断?只能直接连接后端的rs,然后查看服务是否正常,当然,要是会看java日志的话,那么直接重启一下java进程就好了。。。眼瞎,看不见。

    那么问题来了,如果这个时候使用的不是四层健康检查,如果使用的是七层的呢?也就是程序专门有一个页面,然后进行curl localhost:/health来检查返回码,那么lb可以自动将后段不健康的rs进行剔除。

    那么问题来了?操作系统的杀手啥时候将java的整个进程杀了?操作系统内存不足的时候。。。

    那java的oom又有什么关系呢?在非常特殊的情况下没关系,在一般的情况下必须将java进行重启。。。不懂java,靠感觉。。。

    看看java里面的各种内存,什么head,什么stack,什么老年代,什么新生代。。。WTF,欺负我不懂java。。。

    其实最好玩的还是这个里面java的进程监听了这个端口,而这个进程里面又有很多子线程,一个子线程挂了,其他的线程和进程都没啥事,这才是关键点,最最关键的是,当一个子线程挂了之后,在短时间内不会出现问题,但是时间长了,整个java进程可能都不能对外服务了,why?

    在其中有可能出现的是,当一个线程挂了之后,这个线程占用的内存都会被会被gc收回释放,但是如果是共享的内存,那么依旧不会被释放,这个时候,随着时间,其他的线程也逐渐的开始oom,导致最终oom killer。。

    还有一种可能出现的情况就是,几个子线程之间是相互配合的,例如一个子线程持有锁,然后释放的时候通知另外一个子线程,但是持有的挂了,那么另外一个子线程也就长期等待,资源不释放。。。2PC?好像有点这个感觉。。。

    所以呢,能得出啥结论呢?在使用健康检查的时候,最好还是使用七层的检查,可能速度慢了点,还需要判断http的状态返回码,但是从实际上来说,是更可靠的一种方式。

    表面上看起来是活着,实际上是一具行尸走肉。。。行尸走肉电视剧蛮好看的,都不用带脑子。。。

640?wx_fmt=jpeg

    人呢,总是喜欢高估自己,就像一个进程开启了那么多子线程,每一个子线程都以为整个内存,整个堆栈是自己的,实际上。。。这也是一个云环境,资源池都是共享的。一个子线程要想做很多很多事,其实也蛮难的,因为涉及到资源争抢,各种边界条件,各种race condition。。。但是,要想毁坏一个环境,那就简单了。。。

    遇到问题,正面面对。那么多子线程,你凭什么认定是一个线程搞事情?

    自由?什么是自由?高度自律才能换来自由。没有半点儿自律,谈自由。跪着吧。

    很多事,回过头来,才发现当初是多么的愚蠢,那又能怎么办呢?毕竟。。为什么要打脸?因为认识不到错误。面向过程编程,面向对象编程,如今。。。面向kpi编程。。。    

    不要面向兴趣学技术,而要面向价值学技术。可能你不信,等你信的时候就迟了。哈哈哈哈,28法则,百分之二十的技术产生百分之八十的价值,看看研究的一些诡异的问题,根本就排不上用场。。。

发布了188 篇原创文章 · 获赞 424 · 访问量 43万+

猜你喜欢

转载自blog.csdn.net/TM6zNf87MDG7Bo/article/details/95269588
OOM