为程序添加配额
前置条件: 安装easyctl
版本支持:v0.7.14-alpha以上
验证性内容参考-测试说明部分
适用平台:
- [x]
CentOS7
- [?]
CentOS6
暂未测试,不建议使用
- [x]
可限制配额资源:
- [x] 内存
- [x] cpu
- [ ] 网络
- [ ] 磁盘
实现原理:核心原理基于
linux cgroups
(cgroups 封装实现),流程如下:- 通过
boot-app.app-name
(服务名称)字段创建控制组 - 通过
boot-app.resources.limits
(资源限制)字段创建控制组子系统(内存、cpu、io等) - 通过
boot-app.boot-cmd
(启动命令)字段启动程序,并获取进程id
- 将进程
id
添加至控制组内
- 通过
参数说明
boot-app.app-name
: 服务名称,用于关联控制组名称。同一主机上该字段不可重复。boot-app.boot-cmd
: 程序启动命令boot-app.resources.limits.cpu
:CPU
限额,可申请vCore
数量,正整数字段。(设置为0或不设置,表示不限制)boot-app.resources.limits.memory
:CPU
限额,可申请vCore
数量,可选单位:GB
、MB
。(设置为0或不设置,表示不限制)
使用
1.生成配置文件
$ easyctl boot app-with-cgroups
INFO[0000] 生成配置文件样例, 请携带 -c 参数重新执行 -> config.yaml
2.调整配置
vi config.yaml
,调整以下参数
boot-app.app-name
: 服务名称,用于关联控制组名称。同一主机上该字段不可重复。boot-app.boot-cmd
: 程序启动命令boot-app.resources.limits.cpu
:CPU
限额,可申请vCore
数量,正整数字段。(设置为0或不设置,表示不限制)boot-app.resources.limits.memory
:CPU
限额,可申请vCore
数量,可选单位:GB
、MB
。(设置为0或不设置,表示不限制)
boot-app:
- app-name: eureka-app
boot-cmd: nohup /usr/bin/java -jar eureka.jar &> /dev/null &
resources:
limits:
cpu: 2
memory: 3GB
3.执行启动
$ easyctl boot app-with-cgroups -c config.yaml --debug
4.确认配额是否合法(OOM等会有Kill信息)
$ sudo journalctl -xef
测试说明
针对配额内容进行验证性测试
测试CPU限额
实现原理:基于控制组cpu.cfs_period_us
与cpu.cfs_quota_us
实现对CPU
的强限制
注: 高级/自定义设置建议使用原生cgroups
A.测试用例
1
: 配额1vCore
申请1vCore
boot-app:
- app-name: app1
boot-cmd: stress --cpu 1 --vm 1 --vm-bytes 2G --vm-hang 120 --timeout 120s
resources:
limits:
cpu: 1
memory: 3GB
执行
easyctl boot app-with-cgroups -c config.yaml
top
观测
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
221208 root 20 0 7312 100 0 R 99.7 0.0 0:29.00 stress
290 root 20 0 0 0 0 S 0.3 0.0 0:00.01 ksoftirqd/56
...
证明限制生效
B.测试用例
2
: 配额1vCore
申请2vCore
boot-app:
- app-name: app1
boot-cmd: stress --cpu 2 --vm 2 --vm-bytes 2G --vm-hang 120 --timeout 120s
resources:
limits:
cpu: 1
memory: 3GB
执行
easyctl boot app-with-cgroups -c config.yaml
top
观测
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
222430 root 20 0 7312 100 0 R 49.5 0.0 0:03.34 stress
222428 root 20 0 7312 100 0 R 49.2 0.0 0:03.29 stress
...
配额为1vCore
的情况下,若申请2
个vCore
,两个线程将均分1vCore
使用时间(50%
)
C.测试用例
3
: 配额2vCore
申请1vCore
boot-app:
- app-name: app1
boot-cmd: stress --cpu 1 --vm 2 --vm-bytes 2G --vm-hang 120 --timeout 120s
resources:
limits:
cpu: 2
memory: 3GB
执行
easyctl boot app-with-cgroups -c config.yaml
top
观测
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
223488 root 20 0 7312 100 0 R 99.7 0.0 0:07.42 stress
...
D.测试用例
4
: 配额4vCore
申请4vCore
boot-app:
- app-name: app1
boot-cmd: stress --cpu 4 --vm 2 --vm-bytes 2G --vm-hang 120 --timeout 120s
resources:
limits:
cpu: 4
memory: 3GB
执行
easyctl boot app-with-cgroups -c config.yaml
top
观测
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
224362 root 20 0 7312 100 0 R 99.7 0.0 0:09.68 stress
224364 root 20 0 7312 100 0 R 99.7 0.0 0:09.69 stress
224365 root 20 0 7312 100 0 R 99.7 0.0 0:09.69 stress
224366 root 20 0 7312 100 0 R 99.7 0.0 0:09.69 stress
...
E.测试用例
5
: 不限制cpu
配额
boot-app:
- app-name: app1
boot-cmd: stress --cpu 4 --vm 2 --vm-bytes 2G --vm-hang 120 --timeout 120s
resources:
limits:
memory: 3GB
执行
easyctl boot app-with-cgroups -c config.yaml
top
观测
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
239180 root 20 0 7312 100 0 R 100.0 0.0 0:11.01 stress
239177 root 20 0 7312 100 0 R 99.7 0.0 0:11.00 stress
239181 root 20 0 7312 100 0 R 99.7 0.0 0:11.01 stress
239182 root 20 0 7312 100 0 R 99.7 0.0 0:11.01 stress
...
测试内存限额
实现原理:基于控制组memory.limit_in_bytes
内存配置字段实现
注: 高级/自定义设置建议使用原生cgroups
A.测试用例
1
: 配额1GB
申请512M
boot-app:
- app-name: app1
boot-cmd: stress --vm 1 --vm-bytes 512M --vm-hang 120 --timeout 120s
resources:
limits:
memory: 1GB
执行
$ easyctl boot app-with-cgroups -c config.yaml --debug
[easyctl] localhost.localdomain | 2021-10-25T04:51:21-04:00 | info | 启动命令: stress --vm 1 --vm-bytes 512M --vm-hang 120 --timeout 120s, 进程id: 244051
[easyctl] localhost.localdomain | 2021-10-25T04:51:21-04:00 | info | 限制程序配额 -> CPU: 0核, 内存: 1GB
[easyctl] localhost.localdomain | 2021-10-25T04:51:21-04:00 | info | 创建cpu子系统: /sys/fs/cgroup/cpu/app1 memory子系统: /sys/fs/cgroup/memory/app1
[easyctl] localhost.localdomain | 2021-10-25T04:51:21-04:00 | debug | 0
[easyctl] localhost.localdomain | 2021-10-25T04:51:21-04:00 | debug | Quota: 0 Period: 100000
[weiliang@localhost ~]$ ps -ef|grep 244051
root 244051 1 0 04:51 pts/0 00:00:00 stress --vm 1 --vm-bytes 512M --vm-hang 120 --timeout 120s
root 244052 244051 99 04:51 pts/0 00:00:11 stress --vm 1 --vm-bytes 512M --vm-hang 120 --timeout 120s
root 244053 244051 1 04:51 pts/0 00:00:00 stress --vm 1 --vm-bytes 512M --vm-hang 120 --timeout 120s
...
运行正常 ,证明限制生效
B.测试用例
2
: 配额1GB
申请2GB
boot-app:
- app-name: app1
boot-cmd: stress --vm 1 --vm-bytes 2GB --vm-hang 120 --timeout 120s
resources:
limits:
cpu: 1
memory: 1GB
执行,并查询进程
$ easyctl boot app-with-cgroups -c config.yaml --debug
[easyctl] localhost.localdomain | 2021-10-25T05:01:52-04:00 | info | 启动命令: stress --vm 1 --vm-bytes 2G --vm-hang 120 --vm-stride 64 --timeout 120s, 进程id: 244246
[easyctl] localhost.localdomain | 2021-10-25T05:01:52-04:00 | info | 限制程序配额 -> CPU: 0核, 内存: 1GB
[easyctl] localhost.localdomain | 2021-10-25T05:01:52-04:00 | info | 创建cpu子系统: /sys/fs/cgroup/cpu/app1 memory子系统: /sys/fs/cgroup/memory/app1
[easyctl] localhost.localdomain | 2021-10-25T05:01:52-04:00 | debug | 0
[easyctl] localhost.localdomain | 2021-10-25T05:01:52-04:00 | debug | Quota: 0 Period: 100000
$ ps -ef|grep 244246
weiliang 244250 244014 0 05:02 pts/0 00:00:00 grep --color=auto 244246
进程启动失败。此时查看系统日志,由于OOM
已被kill
掉了
$ journalctl -xef
...
Oct 25 05:01:52 localhost.localdomain kernel: [ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name
Oct 25 05:01:52 localhost.localdomain kernel: [244246] 0 244246 1828 107 8 0 0 stress
Oct 25 05:01:52 localhost.localdomain kernel: [244247] 0 244247 526117 262128 521 0 0 stress
Oct 25 05:01:52 localhost.localdomain kernel: Memory cgroup out of memory: Kill process 244247 (stress) score 971 or sacrifice child
Oct 25 05:01:52 localhost.localdomain kernel: Killed process 244247 (stress) total-vm:2104468kB, anon-rss:1048388kB, file-rss:124kB, shmem-rss:0kB
...
C.测试用例
3
: 配额1GB
申请1GB
boot-app:
- app-name: app1
boot-cmd: stress --vm 1 --vm-bytes 1G --vm-hang 120 --timeout 120s
resources:
limits:
cpu: 1
memory: 1GB
执行,并查询进程
$ easyctl] localhost.localdomain | 2021-10-25T05:28:34-04:00 | info | 启动命令: stress --vm 1 --vm-bytes 1G --vm-hang 120 --vm-stride 64 --timeout 120s, 进程id: 244609
[easyctl] localhost.localdomain | 2021-10-25T05:28:34-04:00 | info | 限制程序配额 -> CPU: 0核, 内存: 1GB
[easyctl] localhost.localdomain | 2021-10-25T05:28:34-04:00 | info | 创建cpu子系统: /sys/fs/cgroup/cpu/app1 memory子系统: /sys/fs/cgroup/memory/app1
[easyctl] localhost.localdomain | 2021-10-25T05:28:34-04:00 | debug | 0
[easyctl] localhost.localdomain | 2021-10-25T05:28:34-04:00 | debug | Quota: 0 Period: 100000
$ ps -ef|grep 244609
root 244609 1 0 05:28 pts/0 00:00:00 stress --vm 1 --vm-bytes 1G --vm-hang 120 --vm-stride 64 --timeout 120s
root 244612 244609 5 05:28 pts/0 00:00:00 stress --vm 1 --vm-bytes 1G --vm-hang 120 --vm-stride 64 --timeout 120s
最佳实践
不限制
cpu
,限制内存最大8GB
boot-app:
- app-name: replace_to_your_program_name
boot-cmd: replace_to_your_program_boot_command
resources:
limits:
memory: 8GB
不限制内存,限制
cpu
最多使用2vCore
(cpu
线程)
boot-app:
- app-name: replace_to_your_program_name
boot-cmd: replace_to_your_program_boot_command
resources:
limits:
cpu: 2
限制内存最大
8GB
、cpu
最多使用2vCore
(cpu
线程)
boot-app:
- app-name: replace_to_your_program_name
boot-cmd: replace_to_your_program_boot_command
resources:
limits:
cpu: 2
memory: 8GB