AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

Java服務總在半夜掛,背后的真相竟然是...

來源: 責編: 時間:2023-10-25 15:47:09 240觀看
導讀問題排查問題復現為了復現該問題,寫了個springboot的demo部署在測試環境,其中demo里只做了hello world功能,應用類型為web_tomcat (war包部署),基礎鏡像是base_tomcat/java-centos6-jdk18-60-tom8050-ngx197,鏡像使用的Java

2MO28資訊網——每日最新資訊28at.com


2MO28資訊網——每日最新資訊28at.com

問題排查

問題復現

為了復現該問題,寫了個springboot的demo部署在測試環境,其中demo里只做了hello world功能,應用類型為web_tomcat (war包部署),基礎鏡像是base_tomcat/java-centos6-jdk18-60-tom8050-ngx197,鏡像使用的Java版本是1.8.0_60,有了上次 MySQL被kill的經驗,盲猜是linux limit惹的禍,因此將打好的鏡像分別部署了兩批不同的機器,果不其然,新機器當晚掛掉了,老機器服務正常2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

看一下掛掉的limit設置2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

排查過程

Java進程會受到limits影響?2MO28資訊網——每日最新資訊28at.com

按理說Java進程是不會受到系統limit open files(系統最大句柄數)影響的,但是為了驗證這個問題,我們將他修改為正常機器的值,由于demo是web_tomcat應用,沒法修改啟動腳本,因此我們通過prlimit修改java進程的limit2MO28資訊網——每日最新資訊28at.com

prlimit -p 32672 --nofile=1048576

JJ2MO28資訊網——每日最新資訊28at.com

結果當晚00:00左右還是掛了,看來open files和java進程掛掉沒關系,看dmesg也沒發現什么問題2MO28資訊網——每日最新資訊28at.com


2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

Java版本過低導致內存分配不合理?2MO28資訊網——每日最新資訊28at.com

通過尋求jdos研發組的幫助,jdos研發組的同學認為是java版本的問題,低版本可能沒有限制住申請的內存大小,具體原因如下2MO28資訊網——每日最新資訊28at.com

https://blog.softwaremill.com/docker-support-in-new-java-8-finally-fd595df0ca54?gi=a0cc6736ed142MO28資訊網——每日最新資訊28at.com

異常機器java內存情況2MO28資訊網——每日最新資訊28at.com

Java服務總在半夜掛,背后的真相竟然是... | 京東云技術團隊_EXEC_05Java服務總在半夜掛,背后的真相竟然是... | 京東云技術團隊_EXEC_052MO28資訊網——每日最新資訊28at.com

正常機器java內存情況2MO28資訊網——每日最新資訊28at.com

Java服務總在半夜掛,背后的真相竟然是... | 京東云技術團隊_定時任務_06Java服務總在半夜掛,背后的真相竟然是... | 京東云技術團隊_定時任務_062MO28資訊網——每日最新資訊28at.com

按照這個 文檔描述,使用docker cgroups限制內存可能會導致JVM進程被終止,原因是Java讀取的還是宿主機的CPU,而不是docker cgroups限制的CPU,高版本的Java解決了這個問題,文檔解決方案截圖如下:2MO28資訊網——每日最新資訊28at.com

Java服務總在半夜掛,背后的真相竟然是... | 京東云技術團隊_Java_07Java服務總在半夜掛,背后的真相竟然是... | 京東云技術團隊_Java_072MO28資訊網——每日最新資訊28at.com

對此我們表示懷疑,因為我們的程序里設置了JVM參數2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

保持著試一試的心態,我們增加了一個實驗組,實驗組使用的Java版本是11.0.82MO28資訊網——每日最新資訊28at.com

結果當晚實驗組的Java進程還是死了,看來和Java版本也沒關系2MO28資訊網——每日最新資訊28at.com

容器上存在定時任務導致的?2MO28資訊網——每日最新資訊28at.com

由于基礎鏡像是jdos官方提供的鏡像,所以之前從來沒有懷疑過是定時任務的問題,但是現在別無他法了,檢查下容器的定時任務2MO28資訊網——每日最新資訊28at.com

雖然有定時任務,但是這個執行的時間點和Java掛掉的時間對不上,為此我們決定刪除定時任務試試2MO28資訊網——每日最新資訊28at.com

結果當晚Java進程還是掛了,并且這次有dmesg的日志,發現Java被kill的同時crond也被kill了,被kill的原因是crond內存過高導致oom2MO28資訊網——每日最新資訊28at.com

JJ2MO28資訊網——每日最新資訊28at.com

難道還有系統級cron任務?于是查了一下/etc/crontab,發現果然還有cron任務(這是誰打的鏡像!?。。?span style="display:none">2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

這個時間點和Java進程掛掉的時間點吻合,但是問題來了,執行的任務并沒有logrotate.sh這個腳本,應該不會出現問題才對2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

到底是不是定時任務的問題,我們修改下cron的時間驗證下,調整時間為中午11:00,驗證下Java進程是否會掛,同時使用strace打印進程trace log2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

果然Java進程在中午11.00掛了,看來真的是cron任務導致的,讓我們一起看一下strace2MO28資訊網——每日最新資訊28at.com

19:59:01 close(3)                        = 019:59:01 stat("/etc/pam.d", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 019:59:01 open("/etc/pam.d/crond", O_RDONLY) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=293, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "#/n# The PAM configuration file f"..., 4096) = 29319:59:01 open("/lib64/security/pam_access.so", O_RDONLY) = 519:59:01 read(5, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0000/17/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(5, {st_mode=S_IFREG|0755, st_size=18552, ...}) = 019:59:01 mmap(NULL, 2113800, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7fd76932200019:59:01 mprotect(0x7fd769325000, 2097152, PROT_NONE) = 019:59:01 mmap(0x7fd769525000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x3000) = 0x7fd76952500019:59:01 close(5) = 019:59:01 open("/etc/ld.so.cache", O_RDONLY) = 519:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=16203, ...}) = 019:59:01 mmap(NULL, 16203, PROT_READ, MAP_PRIVATE, 5, 0) = 0x7fd7707f800019:59:01 close(5) = 019:59:01 open("/lib64/libnsl.so.1", O_RDONLY) = 519:59:01 read(5, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0p@/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(5, {st_mode=S_IFREG|0755, st_size=113432, ...}) = 019:59:01 mmap(NULL, 2198192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7fd76910900019:59:01 mprotect(0x7fd76911f000, 2093056, PROT_NONE) = 019:59:01 mmap(0x7fd76931e000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x15000) = 0x7fd76931e00019:59:01 mmap(0x7fd769320000, 6832, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd76932000019:59:01 close(5) = 019:59:01 mprotect(0x7fd76931e000, 4096, PROT_READ) = 019:59:01 mprotect(0x7fd769525000, 4096, PROT_READ) = 019:59:01 munmap(0x7fd7707f8000, 16203) = 019:59:01 open("/etc/pam.d/password-auth", O_RDONLY) = 519:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=692, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)                     = 0x7fd77080300019:59:01 read(5, "#%PAM-1.0/n# This file is auto-ge"..., 4096) = 69219:59:01 open("/lib64/security/pam_unix.so", O_RDONLY) = 619:59:01 read(6, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0/240&/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=51960, ...}) = 019:59:01 mmap(NULL, 2196352, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7fd768ef000019:59:01 mprotect(0x7fd768efc000, 2093056, PROT_NONE) = 019:59:01 mmap(0x7fd7690fb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0xb000) = 0x7fd7690fb00019:59:01 mmap(0x7fd7690fd000, 45952, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd7690fd00019:59:01 close(6)                       = 019:59:01 mprotect(0x7fd7690fb000, 4096, PROT_READ) = 019:59:01 read(5, "", 4096)              = 019:59:01 close(5) = 019:59:01 munmap(0x7fd770803000, 4096) = 019:59:01 open("/lib64/security/pam_loginuid.so", O_RDONLY) = 519:59:01 read(5, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0/220/t/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(5, {st_mode=S_IFREG|0755, st_size=10240, ...}) = 019:59:01 mmap(NULL, 2105480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 5, 0) = 0x7fd768ced00019:59:01 mprotect(0x7fd768cef000, 2093056, PROT_NONE) = 019:59:01 mmap(0x7fd768eee000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 5, 0x1000) = 0x7fd768eee00019:59:01 close(5) = 019:59:01 mprotect(0x7fd768eee000, 4096, PROT_READ) = 019:59:01 open("/etc/pam.d/password-auth", O_RDONLY) = 519:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=692, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080300019:59:01 read(5, "#%PAM-1.0/n# This file is auto-ge"..., 4096) = 69219:59:01 open("/lib64/security/pam_keyinit.so", O_RDONLY) = 619:59:01 read(6, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0`/10/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=10224, ...}) = 019:59:01 mmap(NULL, 2105488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0)                      = 0x7fd768aea00019:59:01 mprotect(0x7fd768aec000, 2093056, PROT_NONE)                     = 019:59:01 mmap(0x7fd768ceb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x1000) = 0x7fd768ceb00019:59:01 close(6) = 019:59:01 mprotect(0x7fd768ceb000, 4096, PROT_READ) = 019:59:01 open("/lib64/security/pam_limits.so", O_RDONLY) = 619:59:01 read(6, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0/320/20/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=18600, ...}) = 019:59:01 mmap(NULL, 2113848, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7fd7688e500019:59:01 mprotect(0x7fd7688e9000, 2093056, PROT_NONE) = 019:59:01 mmap(0x7fd768ae8000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x3000) = 0x7fd768ae800019:59:01 close(6) = 019:59:01 mprotect(0x7fd768ae8000, 4096, PROT_READ) = 019:59:01 open("/lib64/security/pam_succeed_if.so", O_RDONLY) = 619:59:01 read(6, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0/340/v/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=14384, ...}) = 019:59:01 mmap(NULL, 2109624, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0) = 0x7fd7686e100019:59:01 mprotect(0x7fd7686e4000, 2093056, PROT_NONE) = 019:59:01 mmap(0x7fd7688e3000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x2000) = 0x7fd7688e300019:59:01 close(6) = 019:59:01 mprotect(0x7fd7688e3000, 4096, PROT_READ)                       = 019:59:01 read(5, "", 4096) = 019:59:01 close(5)                     = 019:59:01 munmap(0x7fd770803000, 4096) = 019:59:01 open("/etc/pam.d/password-auth", O_RDONLY)                      = 519:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=692, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)                      = 0x7fd77080300019:59:01 read(5, "#%PAM-1.0/n# This file is auto-ge"..., 4096) = 69219:59:01 open("/lib64/security/pam_env.so", O_RDONLY) = 619:59:01 read(6, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0/300/r/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=18592, ...}) = 019:59:01 mmap(NULL, 2113776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0)                       = 0x7fd7684dc00019:59:01 mprotect(0x7fd7684e0000, 2093056, PROT_NONE) = 019:59:01 mmap(0x7fd7686df000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0x3000) = 0x7fd7686df00019:59:01 close(6) = 019:59:01 mprotect(0x7fd7686df000, 4096, PROT_READ)                     = 019:59:01 open("/lib64/security/pam_deny.so", O_RDONLY) = 619:59:01 read(6, "/177ELF/2/1/1/0/0/0/0/0/0/0/0/0/3/0>/0/1/0/0/0000/5/0/0/0/0/0/0"..., 832) = 83219:59:01 fstat(6, {st_mode=S_IFREG|0755, st_size=5952, ...}) = 019:59:01 mmap(NULL, 2101272, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 6, 0)                       = 0x7fd7682da00019:59:01 mprotect(0x7fd7682db000, 2093056, PROT_NONE) = 019:59:01 mmap(0x7fd7684da000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 6, 0)                      = 0x7fd7684da00019:59:01 close(6) = 019:59:01 mprotect(0x7fd7684da000, 4096, PROT_READ) = 019:59:01 read(5, "", 4096) = 019:59:01 close(5) = 019:59:01 munmap(0x7fd770803000, 4096) = 019:59:01 read(3, "", 4096)             = 019:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096)                      = 019:59:01 open("/etc/pam.d/other", O_RDONLY)                      = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=154, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)   = 0x7fd77080400019:59:01 read(3, "#%PAM-1.0/nauth     required     "..., 4096) = 15419:59:01 read(3, "", 4096) = 019:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC)   = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "root:x:0:0:root:/root:/bin/bash/n"..., 4096) = 105719:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 uname({sys="Linux", node="host-11-159-73-176", ...}) = 019:59:01 open("/etc/security/access.conf", O_RDONLY) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=4620, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "# Login access control table./n#/n"..., 4096) = 409619:59:01 read(3, " should get access from ipv4 net"..., 4096) = 52419:59:01 read(3, "", 4096) = 019:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 getuid() = 019:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)  = 0x7fd77080400019:59:01 read(3, "root:x:0:0:root:/root:/bin/bash/n"..., 4096) = 105719:59:01 close(3)                       = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 geteuid() = 019:59:01 open("/etc/shadow", O_RDONLY|O_CLOEXEC) = 319:59:01 fstat(3, {st_mode=S_IFREG, st_size=901, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "root:$6$4.53VPrJ$1wxMpbsWYp4VKea"..., 4096) = 90119:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096)                      = 019:59:01 socket(PF_NETLINK, SOCK_RAW, 9)                       = 319:59:01 fcntl(3, F_SETFD, FD_CLOEXEC)   = 019:59:01 readlink("/proc/self/exe", "/usr/sbin/crond", 4096) = 1519:59:01 sendto(3, "p/0/0/0M/4/5/0/1/0/0/0/0/0/0/0op=PAM:accountin"..., 112, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12)                      = 11219:59:01 poll([{fd=3, events=POLLIN}], 1, 500)   = 1 ([{fd=3, revents=POLLIN}])19:59:01 recvfrom(3, "$/0/0/0/2/0/0/1/1/0/0/0/227/7/0/0/0/0/0/0p/0/0/0M/4/5/0/1/0/0/0"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 3619:59:01 recvfrom(3, "$/0/0/0/2/0/0/1/1/0/0/0/227/7/0/0/0/0/0/0p/0/0/0M/4/5/0/1/0/0/0"..., 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 3619:59:01 close(3) = 019:59:01 open("/etc/security/pam_env.conf", O_RDONLY) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=2980, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "#/n# This is the configuration fi"..., 4096) = 298019:59:01 read(3, "", 4096) = 019:59:01 close(3)                      = 019:59:01 munmap(0x7fd770804000, 4096)                       = 019:59:01 open("/etc/environment", O_RDONLY)   = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)               = 0x7fd77080400019:59:01 read(3, "", 4096) = 019:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 socket(PF_NETLINK, SOCK_RAW, 9) = 319:59:01 fcntl(3, F_SETFD, FD_CLOEXEC) = 019:59:01 sendto(3, "p/0/0/0O/4/5/0/2/0/0/0/0/0/0/0op=PAM:setcred a"..., 112, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12)                       = 11219:59:01 poll([{fd=3, events=POLLIN}], 1, 500)   = 1 ([{fd=3, revents=POLLIN}])19:59:01 recvfrom(3, "$/0/0/0/2/0/0/1/2/0/0/0/227/7/0/0/0/0/0/0p/0/0/0O/4/5/0/2/0/0/0"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 3619:59:01 recvfrom(3, "$/0/0/0/2/0/0/1/2/0/0/0/227/7/0/0/0/0/0/0p/0/0/0O/4/5/0/2/0/0/0"..., 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 3619:59:01 close(3) = 019:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "root:x:0:0:root:/root:/bin/bash/n"..., 4096) = 105719:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 open("/proc/self/loginuid", O_WRONLY|O_TRUNC|O_NOFOLLOW)        = 319:59:01 write(3, "0", 1) = 119:59:01 close(3) = 019:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "root:x:0:0:root:/root:/bin/bash/n"..., 4096) = 105719:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 getuid() = 019:59:01 getgid() = 019:59:01 keyctl(0, 0xfffffffd, 0, 0, 0) = 49646638519:59:01 keyctl(0, 0xfffffffb, 0, 0, 0x30) = 78570213219:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "root:x:0:0:root:/root:/bin/bash/n"..., 4096) = 105719:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 getrlimit(RLIMIT_CPU, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_FSIZE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_DATA, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_CORE, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_RSS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_NPROC, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_NOFILE, {rlim_cur=1073741816, rlim_max=1073741816}) = 019:59:01 getrlimit(RLIMIT_MEMLOCK, {rlim_cur=64*1024, rlim_max=64*1024}) = 019:59:01 getrlimit(RLIMIT_AS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_LOCKS, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 getrlimit(RLIMIT_SIGPENDING, {rlim_cur=883632, rlim_max=883632}) = 019:59:01 getrlimit(RLIMIT_MSGQUEUE, {rlim_cur=800*1024, rlim_max=800*1024}) = 019:59:01 getrlimit(RLIMIT_NICE, {rlim_cur=0, rlim_max=0}) = 019:59:01 getrlimit(RLIMIT_RTPRIO, {rlim_cur=0, rlim_max=0}) = 019:59:01 getpriority(PRIO_PROCESS, 0) = 2019:59:01 open("/etc/security/limits.conf", O_RDONLY) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1835, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "# /etc/security/limits.conf/n#/n#E"..., 4096) = 183519:59:01 read(3, "", 4096) = 019:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096) = 019:59:01 open("/etc/security/limits.d", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 319:59:01 getdents(3, /* 3 entries */, 32768) = 8819:59:01 open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY)                       = 519:59:01 fstat(5, {st_mode=S_IFREG|0644, st_size=26060, ...}) = 019:59:01 mmap(NULL, 26060, PROT_READ, MAP_SHARED, 5, 0) = 0x7fd7707f500019:59:01 close(5)  = 019:59:01 getdents(3, /* 0 entries */, 32768) = 019:59:01 close(3) = 019:59:01 open("/etc/security/limits.d/90-nproc.conf", O_RDONLY) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=193, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "# Default limit for number of us"..., 4096) = 19319:59:01 read(3, "", 4096)              = 019:59:01 close(3)                       = 019:59:01 munmap(0x7fd770804000, 4096)   = 019:59:01 setrlimit(RLIMIT_NPROC, {rlim_cur=RLIM_INFINITY, rlim_max=RLIM_INFINITY}) = 019:59:01 setpriority(PRIO_PROCESS, 0, 0) = 019:59:01 getuid() = 019:59:01 open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=1057, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 read(3, "root:x:0:0:root:/root:/bin/bash/n"..., 4096) = 105719:59:01 close(3) = 019:59:01 munmap(0x7fd770804000, 4096)                     = 019:59:01 socket(PF_NETLINK, SOCK_RAW, 9)                      = 319:59:01 fcntl(3, F_SETFD, FD_CLOEXEC)                      = 019:59:01 sendto(3, "t/0/0/0Q/4/5/0/3/0/0/0/0/0/0/0op=PAM:session_o"..., 116, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 11619:59:01 poll([{fd=3, events=POLLIN}], 1, 500) = 1 ([{fd=3, revents=POLLIN}])19:59:01 recvfrom(3, "$/0/0/0/2/0/0/1/3/0/0/0/227/7/0/0/0/0/0/0t/0/0/0Q/4/5/0/3/0/0/0"..., 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 3619:59:01 recvfrom(3, "$/0/0/0/2/0/0/1/3/0/0/0/227/7/0/0/0/0/0/0t/0/0/0Q/4/5/0/3/0/0/0"..., 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, pid=0, groups=00000000}, [12]) = 3619:59:01 close(3) = 019:59:01 setgid(0) = 019:59:01 open("/proc/sys/kernel/ngroups_max", O_RDONLY) = 319:59:01 read(3, "65536/n", 31)         = 619:59:01 close(3)                       = 019:59:01 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 319:59:01 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)19:59:01 close(3) = 019:59:01 socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 319:59:01 connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110)                       = -1 ENOENT (No such file or directory)19:59:01 close(3) = 019:59:01 open("/etc/group", O_RDONLY|O_CLOEXEC) = 319:59:01 fstat(3, {st_mode=S_IFREG|0644, st_size=497, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd77080400019:59:01 lseek(3, 0, SEEK_CUR) = 019:59:01 read(3, "root:x:0:/nbin:x:1:bin,daemon/ndae"..., 4096) = 49719:59:01 read(3, "", 4096)              = 019:59:01 close(3)                       = 019:59:01 munmap(0x7fd770804000, 4096)                     = 019:59:01 setgroups(1, [0]) = 019:59:01 setreuid(0, 4294967295) = 019:59:01 rt_sigaction(SIGCHLD, {SIG_DFL, [CHLD], SA_RESTORER|SA_RESTART, 0x7fd76fa316a0}, {0x558826e03b80, [], SA_RESTORER|SA_RESTART, 0x7fd76fa316a0}, 8) = 019:59:01 pipe([3, 5])                   = 019:59:01 pipe([6, 7])                   = 019:59:01 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fd7707fca70) = 194619:59:01 gettid()                     = 194319:59:01 open("/proc/self/task/1943/attr/exec", O_RDWR) = 819:59:01 write(8, NULL, 0) = -1 EINVAL (Invalid argument)19:59:01 close(8) = 019:59:01 close(3) = 019:59:01 close(7) = 019:59:01 close(5) = 019:59:01 fcntl(6, F_GETFL)                       = 0 (flags O_RDONLY)19:59:01 fstat(6, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 019:59:01 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)                     = 0x7fd77080400019:59:01 lseek(6, 0, SEEK_CUR)                     = -1 ESPIPE (Illegal seek)19:59:01 read(6, "/bin/bash: ./logrotate.sh: /346/262/241/346/234"..., 4096) = 5519:59:01 uname({sys="Linux", node="host-11-159-73-176", ...}) = 019:59:01 getrlimit(RLIMIT_NOFILE, {rlim_cur=1073741816, rlim_max=1073741816}) = 019:59:01 mmap(NULL, 4294967296, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd6682da00019:59:01 --- SIGCHLD (Child exited) @ 0 (0) ---19:59:06 +++ killed by SIGKILL +++

可以看到最后用 mmap 一次分配了 4G 內存,然后就被kill了。2MO28資訊網——每日最新資訊28at.com

mmap前調用了getrlimit,和上次 MySQL的問題一樣,都是根據系統資源限制來分配內存2MO28資訊網——每日最新資訊28at.com

為了確定就是cron導致java掛掉的元兇,我們把cron進程手動kill掉,這樣就不會執行定時任務了,這次我們在驗證下Java進程是否會掛掉2MO28資訊網——每日最新資訊28at.com

果不其然,Java進程并沒有掛掉,看來真的是cron任務導致的

高版本CentOS是否也會出現類似問題?2MO28資訊網——每日最新資訊28at.com

按理說oom killer應該只kill掉占用內存最高的才對,Java進程占用內存又不是最高的,高版本的CentOS系統oom killer策略會不會有升級?2MO28資訊網——每日最新資訊28at.com

讓我們來一起驗證下高版本的CentOS系統是否有這個問題2MO28資訊網——每日最新資訊28at.com

當前鏡像的CentOS版本是CentOS release 6.6 (Final),為了驗證高版本的CentOS是否也有類似的問題,我們將增加兩個實驗組,分別升級基礎鏡像至CentOS release 6.10 (Final)和CentOS Linux release 7.9.2009 (Core),也添加相同的cron任務2MO28資訊網——每日最新資訊28at.com

結果發現CentOS release 6.10 (Final)和CentOS Linux release 7.9.2009 (Core)都沒有kill掉Java進程,只kill掉了cron的子進程2MO28資訊網——每日最新資訊28at.com


2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

結論2MO28資訊網——每日最新資訊28at.com

由于容器limit open files(系統最大句柄數)設置不合理導致cron執行任務時使容器內存飆升,存在內存溢出的風險,linux由于保護機制會kill掉占用內存高的進程,導致cron子任務進程和Java進程一起被kill(但是問題來了,這個jdos基礎鏡像為什么會執行一個完全不存在的shell腳本,而且還是執行兩次???),高版本的CentOS系統不會kill java進程,猜測不同版本的CentOS的kill選擇策略略有不同2MO28資訊網——每日最新資訊28at.com

問題分析

Cron任務執行邏輯2MO28資訊網——每日最新資訊28at.com

在Linux中,crontab工具是由croine軟件包提供的,讓我們一起看下cron的執行過程2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

其中child_process()執行了cron子進程,cron執行子進程時會有發送mail的動作2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

cron_popen在執行時會按照open files(系統最大句柄數)清除內存2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

2MO28資訊網——每日最新資訊28at.com

綜上,cron oom的原因找到了,是由于open files設置過大且cron任務沒有標準輸出,導致執行了發送mail邏輯,而清除的內存大小超出了容器本身內存的大小,導致oom。2MO28資訊網——每日最新資訊28at.com

croine 1.5.4 版本之后修復了該問題,如果想查看當前容器croine版本可執行如下命令:2MO28資訊網——每日最新資訊28at.com

1.rpm -q cronie

2MO28資訊網——每日最新資訊28at.com

Linux內核OOM killer機制2MO28資訊網——每日最新資訊28at.com

Linux 內核有個機制叫OOM killer(Out Of Memory killer),該機制會監控那些占用內存過大,尤其是瞬間占用內存很快的進程,然后防止內存耗盡而自動把該進程殺掉。內核檢測到系統內存不足、挑選并殺掉某個進程的過程可以參考內核源代碼linux/mm/oom_kill.c,當系統內存不足的時候,out_of_memory()被觸發,然后調用select_bad_process()選擇一個”bad”進程殺掉。2MO28資訊網——每日最新資訊28at.com

以下是一些主要的進程選擇策略:2MO28資訊網——每日最新資訊28at.com

  1. 內存使用情況:OOM Killer首先傾向于選擇占用內存最多的進程,因為終止這些進程可以釋放最多的內存。
  2. OOM分數:每個進程都有一個OOM分數,該分數是基于其內存使用情況和其他因素計算出來的。OOM Killer傾向于終止OOM分數最高的進程。
  3. 進程優先級:在選擇要終止的進程時,OOM Killer通常會避免終止對系統至關重要的系統進程。這些進程通常具有較高的優先級,因此它們更不容易成為終止目標。
  4. 進程資源需求:OOM Killer還會考慮進程的資源需求。它傾向于終止那些請求較少資源的進程,以最小化影響其他進程的運行。
  5. 進程屬性:某些進程可能被標記為不可終止,例如通過設置/proc//[PID/]/oom/_score/_adj的值來調整OOM分數。這些進程通常不容易被OOM Killer終止。

注:不同版本的Linux oom killer機制可能會存在一些差異2MO28資訊網——每日最新資訊28at.com

解決方案

使用高版本穩定的CentOS系統,如果業務無法升級CentOS,則需要設置合理的limit open files數量,application/_worker類型應用可以在啟動腳本中手動修改limit,web/_tomcat類型應用沒法修改啟動腳本,可以選擇kill掉cron進程或刪除系統cron任務,也可以手動升級cronie的版本至1.5.7-52MO28資訊網——每日最新資訊28at.com

寫在后面

open files這個坑很大,栽這個坑兩次了,大家一定要檢查自己服務對應容器的CentOS版本和limit設置是否合理,本次案例發生在測試環境,尚不會引起事故,如果在生產出現類似情況,后果不堪設想2MO28資訊網——每日最新資訊28at.com

由于測試環境新增的這批機器都存在這個問題,我們團隊已經聯系機器提供方上報了該問題,后續這批機器會由提供方統一修改系統最大句柄數,如果當前問題影響到了業務的正常使用,可以臨時刪除容器中/etc/crontab中的任務2MO28資訊網——每日最新資訊28at.com

參考文獻

https://cloud.tencent.com/developer/article/11832622MO28資訊網——每日最新資訊28at.com

https://github.com/cronie-crond/cronie2MO28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-14805-0.htmlJava服務總在半夜掛,背后的真相竟然是...

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 理解 Go 調度器并探索其工作原理

下一篇: Java基礎:如何理解面向對象?

標簽:
  • 熱門焦點
  • 小米官宣:2023年上半年出貨量中國第一!

    今日早間,小米電視官方微博帶來消息,稱2023年小米電視上半年出貨量達到了中國第一,同時還表示小米電視的巨屏風暴即將開始。“公布一個好消息2023年#小米電視上半年出貨量中國
  • 對標蘋果的靈動島 華為帶來實況窗功能

    繼蘋果的靈動島之后,華為也在今天正式推出了“實況窗”功能。據今天鴻蒙OS 4.0的現場演示顯示,華為的實況窗可以更高效的展現出實時通知,比如鎖屏上就能看到外賣、打車、銀行
  • 六大權益!華為8月服務日開啟:手機免費貼膜、維修免人工費

    8月5日消息,一年一度的華為開發者大會2023(Together)日前在松山湖拉開帷幕,與此同時,華為8月服務日也式開啟,到店可享六大專屬權益。華為用戶可在華為商城Ap
  • 2023 年的 Node.js 生態系統

    隨著技術的不斷演進和創新,Node.js 在 2023 年達到了一個新的高度。Node.js 擁有一個龐大的生態系統,可以幫助開發人員更快地實現復雜的應用。本文就來看看 Node.js 最新的生
  • K8S | Service服務發現

    一、背景在微服務架構中,這里以開發環境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網關、注冊中心、配置中心等相關服務,可以被集群外部訪問;圖片對于測試「Tes」環境或者
  • 讓我們一起聊聊文件的操作

    文件【1】文件是什么?文件是保存數據的地方,是數據源的一種,比如大家經常使用的word文檔、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存數據,它既可以保
  • 微信語音大揭秘:為什么禁止轉發?

    大家好,我是你們的小米。今天,我要和大家聊一個有趣的話題:為什么微信語音不可以轉發?這是一個我們經常在日常使用中遇到的問題,也是一個讓很多人好奇的問題。讓我們一起來揭開這
  • 當家的盒馬,加速謀生

    來源 | 價值星球Planet作者 | 歸去來自己“當家”的盒馬,開始加速謀生了。據盒馬官微消息,盒馬計劃今年開放生鮮供應鏈,將其生鮮商品送往食堂。目前,盒馬在上海已經與
  • 世界人工智能大會國際日開幕式活動在世博展覽館開啟

    30日上午,世界人工智能大會國際日開幕式活動在世博展覽館開啟,聚集國際城市代表、重量級院士專家、國際創新企業代表,共同打造人工智能交流平臺。上海市副市
Top