为程序添加配额

  • 前置条件: 安装easyctl

  • 版本支持:v0.7.14-alpha以上

  • 验证性内容参考-测试说明部分

  • 适用平台:

    • [x] CentOS7
    • [?] CentOS6 暂未测试,不建议使用
  • 可限制配额资源:

    • [x] 内存
    • [x] cpu
    • [ ] 网络
    • [ ] 磁盘
  • 实现原理:核心原理基于linux cgroupscgroups 封装实现),流程如下:

    1. 通过boot-app.app-name(服务名称)字段创建控制组
    2. 通过boot-app.resources.limits(资源限制)字段创建控制组子系统(内存、cpu、io等)
    3. 通过boot-app.boot-cmd(启动命令)字段启动程序,并获取进程id
    4. 将进程id添加至控制组内

参数说明

  • boot-app.app-name: 服务名称,用于关联控制组名称。同一主机上该字段不可重复。
  • boot-app.boot-cmd: 程序启动命令
  • boot-app.resources.limits.cpu: CPU限额,可申请vCore数量,正整数字段。(设置为0或不设置,表示不限制)
  • boot-app.resources.limits.memory: CPU限额,可申请vCore数量,可选单位:GBMB。(设置为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数量,可选单位:GBMB。(设置为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_uscpu.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的情况下,若申请2vCore,两个线程将均分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最多使用2vCorecpu线程)

boot-app:
  - app-name: replace_to_your_program_name
    boot-cmd: replace_to_your_program_boot_command
    resources:
      limits:
        cpu: 2

限制内存最大8GBcpu最多使用2vCorecpu线程)

boot-app:
  - app-name: replace_to_your_program_name
    boot-cmd: replace_to_your_program_boot_command
    resources:
      limits:
        cpu: 2
        memory: 8GB
Copyright © weiliang-ms 2021 all right reserved,powered by Gitbook本书发布时间: 2023-09-06 14:36:05

results matching ""

    No results matching ""