jvm在k8s中参数调整
作为一个jvm参数一直是手动调整的码农,本身对自动调整没啥感觉,类似gc线程数等参数都是手动调整的。
后面发现这样的好处是各种参数可控,不好处就是调整一次太繁琐了。每一个进程都这么调整,工作量会变的特别大。
所以使用默认的参数在前期跑起业务来的作用非常巨大。
k8s的问题
java进程跑在物理机的时候,就是我们常见的方法,啥也不设置,那么xmx默认就是物理机进程的四分之一。这个问题不大,当跑在k8s的时候,会有一些小意外。默认的gc线程数也是和cpu核数相关的。
* 使用gc线程过多
这种情况不少见,物理机的合数可能有98核,但是pod只分配了4核,在java10之前,他获取到可用的核数就是物理机的核数。默认启动的gc线程会特别多。
* xmx默认太小
jvm启动以后,有4g的内存空间,xmx其实只有1g。剩下的都需要强制指定xmx才能利用到空间。
问题的解决
* 升级到jdk10
在jdk10中有-XX:UseContainerSupport这个参数可以解决以上的所有问题。k8s给了4核3g的内存,那么xmx最大值就是3g,cpu可用核数就是4核。
* 如果不能升级到10
在jdk8
191以上,cpu可以使用参数ActiveProcessorCount来控制cpu可用核数。用RAMPercentage等参数来控制xmx默认的比率。
* 如果是jdk8 191一下版本
只能是选择手动控制每个参数。其中在8的某个版本是可以使用UseCGroupMemoryLimitForHeap来开启对资源设置的感知,配合MaxRAMFraction来控制内存。MaxRAMFraction有个弊端,就是他只能设置正数,例如1,2,3,分别表示1,1/2,1/3。这个控制的力度比较大。如果可以RAMPercentage系列,就不用这个参数,RAMPercentage是可以设置百分比的,控制的资源会更大。
小结
在k8s中部署资源,全部参数控制是最好的,这样要花费更多的时间让程序比较稳定的跑起来。相比默认参数的简单,在开发的前期把经历投入到参数配置是不值得的。如果开发环境的话可以尽量使用新的jdk。对k8s的支持更好,更方便。经过调优验证以后,再用调优后的参数最终给pod里的程序,
在不同的jdk里的解决方法是不一样的,这个稳定性和简易性的一个考量。新版本的jdk稳定性上会比已经跑了很久的版本要弱。所以升级jdk也是一个需要考量的事情,但是在测试的时候,不稳定跑程序,只是验证功能,这个就相对是比较好的选择。
在低版本里如何选择呢,我一般推荐低版本的最高版本,例如jdk8,就选择8的最高版本,在功能稳定的情况下,后面的版本一般都是修正前面的bug。所以越高的版本改动不大,稳定性也有一定的保证。