在 Linux 中通过 cgroups 限制 Nginx、MySQL 等服务的资源使用,核心思路是​​为服务创建专属 cgroup,配置资源限制,并将服务进程关联到该组​​。以下是具体配置方法和步骤,涵盖 CPU、内存、磁盘 I/O 等关键资源:


⚙️ 一、通用配置流程(适用于所有服务)

  1. ​安装 cgroup 工具​
    若未安装 cgroup-tools,需先执行:

    sudo apt-get update && sudo apt-get install cgroup-tools  # Debian/Ubuntu
    sudo yum install libcgroup-tools -y                      # CentOS/RHEL
    
  2. ​创建 cgroup 并设置资源限制​

    # 创建名为 nginx_limit 的 cgroup(限制 CPU 和内存)
    sudo cgcreate -g cpu,memory:/nginx_limit
    # 设置 CPU 限制(示例:限制为 50%)
    sudo cgset -r cpu.cfs_period_us=100000 /nginx_limit      # 周期 100ms
    sudo cgset -r cpu.cfs_quota_us=50000 /nginx_limit        # 配额 50ms(即 50%)
    # 设置内存限制(示例:限制为 1GB)
    sudo cgset -r memory.limit_in_bytes=1G /nginx_limit
    
  3. ​将服务进程关联到 cgroup​

    • ​方法 1:启动时直接绑定​​(推荐)
      # 使用 cgexec 启动服务
      sudo cgexec -g cpu,memory:nginx_limit systemctl start nginx
      
    • ​方法 2:对运行中进程绑定​
      # 获取 PID(如 MySQL 主进程)
      sudo systemctl status mysql | grep "Main PID"
      # 绑定到 cgroup
      sudo cgclassify -g cpu,memory:mysql_limit <PID>
      

🖥️ 二、针对 Nginx 的配置示例

  1. ​限制 CPU 和内存​
    参考上述通用流程创建 cgroup(如 nginx_limit),并设置参数:

    • CPU 限制:cpu.cfs_quota_uscpu.cfs_period_us 比例控制。
    • 内存限制:memory.limit_in_bytes 防止内存溢出。
  2. ​补充:文件描述符限制​
    Nginx 需处理大量连接,需单独调整(非 cgroup):

    # 修改 /etc/security/limits.conf
    nginx soft nofile 65535
    nginx hard nofile 65535
    # 在 Nginx 配置中同步
    worker_rlimit_nofile 65535;  # 位于 nginx.conf
    

🗄️ 三、针对 MySQL 的配置示例

  1. ​限制 CPU 和内存​

    # 创建 cgroup
    sudo cgcreate -g cpu,memory:/mysql_limit
    # 限制 CPU 为 4 核等效(400%)
    sudo cgset -r cpu.cfs_quota_us=400000 /mysql_limit
    sudo cgset -r cpu.cfs_period_us=100000 /mysql_limit
    # 限制内存为 4GB
    sudo cgset -r memory.limit_in_bytes=4G /mysql_limit
    
  2. ​磁盘 I/O 限制​​(需额外配置)

    # 创建 blkio cgroup
    sudo cgcreate -g blkio:/mysql_io
    # 限制读写带宽(示例:限制写带宽 50MB/s)
    sudo cgset -r blkio.throttle.write_bps_device="MAJ:MIN 52428800" /mysql_io
    # 查看设备号:`lsblk -o NAME,MAJ:MIN`
    

    ⚠️ 注意:需同时限制带宽和 IOPS 以避免单维度失效。


🔄 四、持久化配置(重启后生效)

临时配置重启后会丢失,需通过 ​​systemd​​ 或 ​​启动脚本​​ 实现持久化:

  1. ​Systemd 服务集成​​(推荐)
    修改服务的 systemd 单元文件(如 /etc/systemd/system/mysql.service):

    [Service]
    ...
    CPUQuota=50%         # 限制 CPU 使用率
    MemoryHigh=1G        # 软内存限制
    MemoryMax=1.5G       # 硬内存限制
    IOWeight=500         # 相对 I/O 权重
    

    执行 sudo systemctl daemon-reload && sudo systemctl restart mysql 生效。

  2. ​通过脚本自动绑定​
    创建 /etc/rc.local 脚本(示例为 MySQL):

    # 获取 PID 并绑定到 cgroup
    PID=$(systemctl show mysql --value -p MainPID)
    cgclassify -g cpu,memory:mysql_limit $PID
    

⚠️ 五、注意事项

  1. ​子进程继承​​:确保 cgroup 设置支持继承(默认开启),否则需手动绑定子进程。

  2. ​Swap 影响​​:内存限制在开启 Swap 时可能失效,建议禁用 Swap。

  3. ​监控验证​​:

    • 使用 tophtop 观察 %CPU%MEM
    • 检查 cgroup 状态:cat /sys/fs/cgroup/memory/mysql_limit/memory.usage_in_bytes
  4. ​多服务隔离​​:若同一主机运行多个 MySQL/Nginx 实例,需为每个实例创建独立 cgroup 避免资源竞争。


📊 配置参数参考表

​资源类型​ ​cgroup参数​ ​Nginx示例值​ ​MySQL示例值​ ​作用​
​CPU​ cpu.cfs_quota_us 50000 (50%) 400000 (4核) 周期内可使用的 CPU 时间
cpu.cfs_period_us 100000 100000 CPU 周期长度(微秒)
​内存​ memory.limit_in_bytes 1G 4G 最大内存使用量
​磁盘 I/O​ blkio.throttle.write_bps_device 未设置 50MB/s 限制写入带宽

通过以上配置,可有效隔离 Nginx、MySQL 等服务的资源使用,避免单个应用耗尽系统资源导致整体服务不可用。建议先在测试环境验证参数,再应用于生产环境。

posted on 2025-07-31 09:18  LeeHang  阅读(39)  评论(0)    收藏  举报