使用 Docker 可以减少或避免 CPU 使用率达到 100% 的容器
有一个使用foreach循环来监视Server-Sent Events的Docker容器。我启动了容器后没多久,机器开始呼哧呼哧地响起来。我用docker stats命令确认后发现CPU使用率已经超过了100%。我该怎么办?
由于在Qiita文章中无法找到”Docker CPU 使用率 100% コンテナ 軽減”的相关结果,所以我将其作为我的搜索能力。
简介:TL;DR(今北産業)
条件により空ループ(何も処理をしないでループする)箇所が発生していないか確認する。(for/foreach/while ループなど)
該当ループ処理の最後に支障をきたさない範囲で sleep を入れる。(1 〜 0.5 秒入れるだけでも劇的に変わる)
上記を確認した上で Docker もしくは docker-compose の設定で最大使用率に制限をかけるのがベター
TS; DR (kwsk)
对于强制限制(Docker版本),只需一个选项。
最初,Docker 已經提供了一個 –cpus 選項,用於限制每個容器的 CPU 最大使用率。換句話說,我們可以指定容器所使用的 CPU 數量,以便分配資源,用於對症治療。
举例来说,如果有4核心的CPU,将CPU分配给两个任务可以将使用率限制在最高50%。
docker run -it --cpus="2" ubuntu /bin/bash
如果要将其限制在最多80%的情况下,可参考以下选项:
docker run -it --cpus="3.2" ubuntu /bin/bash
-
- 参考文献
Configure the default CFS scheduler | CPU @ Docker 公式ドキュメント
Docker コンテナの CPU 使用率を制限する Tips @ Qiita
对于docker-compose,强制进行限制
如果想要在 docker-compose 中添加限制,请在 deploy 指令中指定 cpus。
version: '3.8'
services:
my-service:
container_name: my-cont1
build: .
deploy:
resources:
limits:
cpus: "3.2"
- docker-compose up myservice
+ docker-compose --compatibility up myservice
-
- 参考文献:
docker-compose –help
How to specify Memory & CPU limit in docker compose version 3 @ StackOverflow
这个设置是为了预先控制容器失控时的损害范围,换句话说,它们只是对容器进行了限制。
反过来说,即使正常运行,也不能使用超过CPU资源以上的资源。
如果不徹底地降低 CPU 使用率,資源將被浪費到限制值。很可能大部分情況下不是 Docker 的問題,而是程式結構的問題可以輕易想像出來。
重新审视程序
本次程序本身非常简单,仅通过SSL连接的套接字读取数据,接收Server-Sent Events的消息并进行字符串替换处理。甚至没有文件访问。
そうなると、メッセージ読み取りと文字列処理のループ箇所が臭います。
そこで、VS Code のデバッグ機能を使いステップインで1行ずつ実行を確認してみます。
玛丽、玛丽、、、玛丽、、、哎呀…
看起来,在数据没有流入的情况下,存在一个部分发生了”空循环”,即执行最快速的循环而没有进行任何处理,我对这一点表示理解,这就是为什么 CPU 使用率会达到100%。
$read = false;
while ($read === false) {
$read = readLine($socket); // データが届いてない間は false で高速ループ
}
因此,我根据PHP的“循环处理时的CPU负载”和.NET的“避免CPU使用率达到100%的方法”作为参考,在循环的最后尝试了一个1秒的睡眠。
$read = false;
while ($read === false) {
$read = readLine($socket);
sleep(1);
}
这真是太有效了!使用率从100〜110%降低到了0.00〜0.01%的波动。即使睡眠只有0.5秒,负载也只达到了0.01〜0.03%左右。
在上述中,不仅限于PHP,首先我认为通过步骤执行等方法来检查循环部分,并在循环不受阻碍的范围内插入sleep是有效的。此外,作为保险措施,我认为使用docker或docker-compose的cpus选项来限制最大值更为稳妥。
引用资料
Dockerのメモリ使用量を確認したい @ Qiita
Dockerリソース使用状況の確認方法 @ Qiita
ループ処理を行った際のCPUの負荷 @ Qiita
CPU使用率100%を回避する方法 | 旧@IT会議室 @ @IT