報錯
今天線上遇到故障,php進行因為段錯誤退出了,系統日志中的kernel報錯如下:
Feb 25 22:25:11 web_server_01 kernel: __ratelimit: 250 callbacks suppressed Feb 25 22:25:11 web_server_01 kernel: php-fpm[25942]: segfault at 2c6 ip 00000000000002c6 sp 00007fffdcf9e798 error 14 in php-fpm[400000+a3b000]
查詢
對於__ratelimit: 250 callbacks suppressed的報錯的原因不是很理解,遂做了一番查詢,記錄一下:
__ratelimit: N callbacks suppressed表示內核阻止了N條syslog消息,這是因為系統重復的日志過多(頻率過高),太快輸出,被內核中的net_ratelimit()限制了syslog消息。
源碼參考:http://fxr.watson.org/fxr/source/lib/ratelimit.c?v=linux-2.6
這個rate limit也是Linux為了避免DoS攻擊的一種機制,避免每個消息都被記錄(會導致存儲空間撐爆)。當內核記錄消息,使用printk()通過這種機制來檢查是否輸出日志。
這個限制可以通過/proc/sys/kernel/printk_ratelimit和/proc/sys/kernel/printk_ratelimit_burst來調優。默認配置(RHEL6)分別是5和10。也就是說,內核允許每5秒記錄10條消息。超過這個限制,內核就會拋棄日志,並記錄ratelimit N: callbacks suppressed。
[root@web_server_01 ~]# cat /proc/sys/kernel/printk_ratelimit 5 [root@web_server_01 ~]# cat /proc/sys/kernel/printk_ratelimit_burst 10 [root@web_server_01 ~]#
然而,在內核的網絡代碼中有自己的限制配置(邏輯相同,但是是獨立的配置) /proc/sys/net/core/message_cost和/proc/sys/net/core/message_burst,默認配置也是5和10。這里message_cost也是日志采樣時間。
[root@web_server_01 ~]# cat /proc/sys/net/core/message_cost 5 [root@web_server_01 ~]# cat /proc/sys/net/core/message_burst 10 [root@web_server_01 ~]#
如果要關閉ratelimit機制,也就是允許每個消息都記錄下來,則可以設置message_cost值為0
sysctl -w net.core.message_cost=0
不過,一旦關閉ratelimit,系統就可能存在被日志攻擊的風險。
參考鏈接:https://huataihuang.gitbooks.io/cloud-atlas/content/os/linux/kernel/log/ratelimit.html