jvm已经支持了容器的识别。
-XX:+UseContainerSupport
容器支持的参数已经默认是开启状态。下面我们就来看看作为一个进程,他是如何识别外部的资源限制的。
核心代码
optResult = determineType("/proc/self/mountinfo", "/proc/cgroups", "/proc/self/cgroup");
代码主要围绕着3个文件来进行读取。就是上面方法中的3个参数。我们后面根据代码来看看这3个文件的作用。
了解cgroup的同学,了解资源的限制是写在了文件路径下的。所以代码的核心的就是去找到文件路径。填充如下的class数据数据、
public class CgroupInfo {
private final String name;
private final int hierarchyId;
private final boolean enabled;
private String mountPoint;
private String mountRoot;
private String cgroupPath;
}
第一步从 /proc/cgroups从获取子系统的信息。
jdk默认识别的子系统有6种,他们是作为常量写在java文件中的。
private static final String CPU_CTRL = "cpu";
private static final String CPUACCT_CTRL = "cpuacct";
private static final String CPUSET_CTRL = "cpuset";
private static final String BLKIO_CTRL = "blkio";
private static final String MEMORY_CTRL = "memory";
private static final String PIDS_CTRL = "pids";
第二步是从/proc/self/mountinfo获取mountpoint,mountroot。
这里jdk直接匹配了正则。
private static final Pattern MOUNTINFO_PATTERN = Pattern.compile(
"^[^\\s]+\\s+[^\\s]+\\s+[^\\s]+\\s+" + // (1), (2), (3)
"([^\\s]+)\\s+([^\\s]+)\\s+" + // (4), (5) - group 1, 2: root, mount point
"[^-]+-\\s+" + // (6), (7), (8)
"([^\\s]+)\\s+" + // (9) - group 3: filesystem type
".*$"); // (10), (11)
这里的信息,我们可以通过自己cat或者注释来看。
/*
* From https://www.kernel.org/doc/Documentation/filesystems/proc.txt
*
* 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
* (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
*
* (1) mount ID: unique identifier of the mount (may be reused after umount)
* (2) parent ID: ID of parent (or of self for the top of the mount tree)
* (3) major:minor: value of st_dev for files on filesystem
* (4) root: root of the mount within the filesystem
* (5) mount point: mount point relative to the process's root
* (6) mount options: per mount options
* (7) optional fields: zero or more fields of the form "tag[:value]"
* (8) separator: marks the end of the optional fields
* (9) filesystem type: name of filesystem of the form "type[.subtype]"
* (10) mount source: filesystem specific information or "none"
* (11) super options: per super block options
*/
在获取到mountpoint,mountroot之后,我们还差最后一个cgroupPath。
这个数据就是从/proc/self/cgroup中获取。
/proc/self/cgroup的数据如下
/*
* Sets the path to the cgroup controller for cgroups v1 based on a line
* in /proc/self/cgroup file (represented as the 'tokens' array).
*
* Note that multiple controllers might be joined at a single path.
*
* Example:
*
* 7:cpu,cpuacct:/system.slice/docker-74ad896fb40bbefe0f181069e4417505fffa19052098f27edf7133f31423bc0b.scope
*
* => tokens = [ "7", "cpu,cpuacct", "/system.slice/docker-74ad896fb40bbefe0f181069e4417505fffa19052098f27edf7133f31423bc0b.scope" ]
*/
通过切割字符串,我们获取到了cgroupPath。
通过以上的3个操作,我们最终构造出了完整的cgroup路径,后面的部分就是根据路径读取配置的文件名即可。
小结
- /proc/cgroups可以获取cgroup的子系统
- /proc/self/mountinfo可以获得挂载点
- /proc/self/cgroup可以获取cgroup的path
点击查看更多内容
2人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦