我有一个 C++ 编译的可执行文件,program
它可以通过 systemd 作为后台进程运行。
它也可以通过命令行作为常规进程运行(主要用于调试)。
该进程在其他应用程序和外部设备之间进行常规 IO 操作。设备通信通过 TCP/IP 以太网进行,而应用程序通信都是进程间通信。
问题是,当该应用程序作为独立可执行文件运行时,其 CPU 使用率约为 0.7% - 1.3%。
当同一应用程序作为 systemd 后台进程运行时,CPU% 使用率会跳升至CPUQuota
配置允许的最大值左右。在本例中,我们将其设置为 5%。
这是为什么?systemd 中是否发生了什么导致此问题?从代码角度来看,作为应用程序运行和作为守护进程运行之间的唯一区别是,当作为守护进程运行时,我们会以发送的间隔发送心跳。
答案1
应用这些调整:
1. 将 I/O 调度程序更改为 mq-deadline,如下所示:
确保mq-deadline 调度程序通过在以下位置添加条目来在启动时加载/etc/modules-load.d/modules.conf
:
echo mq-deadline >> /etc/modules-load.d/modules.conf
然后编辑/etc/default/grub
并确保多队列截止时间调度程序已启用:
GRUB_CMDLINE_LINUX_DEFAULT="scsi_mod.use_blk_mq=1 elevator=mq-deadline"
完成后,发出:
sudo update-grub
然后重启。注意从 Linux 5.x 开始,单队列调度器被删除。
这样做的目的是确保 CFQ(完全公平队列)被覆盖。这可能是你的 Linux 发行版上的默认调度程序,不过最近喜欢 OpenSUSE已开始将多队列截止时间调度程序设置为默认调度程序。多队列截止时间调度程序的主要优势是其 CPU 开销非常低。
2. 最重要的:禁用自动分组功能(默认情况下启用)并调整 sched_migration_cost 变量的值/etc/sysctl.conf
。
将这些行放入/etc/sysctl.conf
:
kernel.sched_autogroup_enabled=0
kernel.sched_migration_cost_ns = 5000000
然后运行sysctl -p
并重新启动。
我在生产过程中遇到了类似的问题,通过上述调整解决了该问题。这线程非常有用,后续跟进也是如此与Proxmox类似的情况。