Contents

容器内获取 CPU 核数问题

Contents

现在越来越多的公司将服务通过容器来部署,但这里其实对Java的应用有一个坑。很多超时敏感的应用其实对GC的要求还是比较高的,减少GC的时间变得很重要,比如你可以根据当前机器的CPU核数得到一个较好的并发GC线程数 -XX:ParallelGCThreads,从而减少STW的时长。

但在早期的JDK版本中,比如我们使用的Jdk1.8u102,当你使用Java的Runtime获取CPU数量时,在容器里面会返回容器所在宿主机的核数,而不是容器自身的:

int cores = Runtime.getRuntime().availableProcessors();

这其实是JDK的一个问题,已经trace在JDK-8140793,原因是获取CPU核数是通过读取两个环境变量,其中

ENVDescription
_SC_NPROCESSORS_CONFnumber of processors configured
_SC_NPROCESSORS_ONLNThe number of processors currently online (available)

其中_SC_NPROCESSORS_CONF 就是我们需要容器真实的CPU数量。 https://img-blog.csdnimg.cn/20200911145803773.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlc3RfNjA5,size_16,color_FFFFFF,t_70#pic_center 获取CPU数量的源码

怎么解决

第一种办法是使用新版本的Jdku131以上的版本1

另外一个办法是使用自编译上面的源代码,通过LD_PRLOAD的方式将修改后的so文件加载进去Mock掉CPU的核数

Java SE support for Docker CPU and memory limits