[{"createTime":1735734952000,"id":1,"img":"hwy_ms_500_252.jpeg","link":"https://activity.huaweicloud.com/cps.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=201905","name":"华为云秒杀","status":9,"txt":"华为云38元秒杀","type":1,"updateTime":1735747411000,"userId":3},{"createTime":1736173885000,"id":2,"img":"txy_480_300.png","link":"https://cloud.tencent.com/act/cps/redirect?redirect=1077&cps_key=edb15096bfff75effaaa8c8bb66138bd&from=console","name":"腾讯云秒杀","status":9,"txt":"腾讯云限量秒杀","type":1,"updateTime":1736173885000,"userId":3},{"createTime":1736177492000,"id":3,"img":"aly_251_140.png","link":"https://www.aliyun.com/minisite/goods?userCode=pwp8kmv3","memo":"","name":"阿里云","status":9,"txt":"阿里云2折起","type":1,"updateTime":1736177492000,"userId":3},{"createTime":1735660800000,"id":4,"img":"vultr_560_300.png","link":"https://www.vultr.com/?ref=9603742-8H","name":"Vultr","status":9,"txt":"Vultr送$100","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":5,"img":"jdy_663_320.jpg","link":"https://3.cn/2ay1-e5t","name":"京东云","status":9,"txt":"京东云特惠专区","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":6,"img":"new_ads.png","link":"https://www.iodraw.com/ads","name":"发布广告","status":9,"txt":"发布广告","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":7,"img":"yun_910_50.png","link":"https://activity.huaweicloud.com/discount_area_v5/index.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=aXhpYW95YW5nOA===&utm_medium=cps&utm_campaign=201905","name":"底部","status":9,"txt":"高性能云服务器2折起","type":2,"updateTime":1735660800000,"userId":3}]
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。所以越高的版本改动不大,稳定性也有一定的保证。