웹서버의 메모리 누수

웹서버의 메모리 누수

그래서 최근에 서버 성능 문제가 발생했습니다. 현재 우리는 4GB 및 160GB 디스크 공간을 갖춘 Fedora 서버를 실행하고 있습니다. 우리는 우리가 가지고 있는 모든 파일을 사용하여 디스크를 거의 꽉 채우고 있습니다. 우리는 각 웹사이트마다 여러 백업을 갖춘 여러 웹사이트를 운영하고 있습니다. 하지만 실제로는 단 하나의 사이트에서만 트래픽이 발생합니다. 방문자 수가 많은 전자상거래 사이트입니다.

최근에는 로드 시간이 느려지고 여유 메모리가 1GB 미만으로 낮아지는 것을 확인했습니다. 서버를 다시 시작하겠습니다(지금은 하루에 3번 수행해야 함). 그러면 모든 것이 괜찮을 것입니다. 2.2GB의 여유 메모리로 시작하지만 3~4시간 후에는 메모리가 가득 차고 로드 시간이 느려지는 것을 알 수 있습니다. 이것이 어디서 오는 것인지, 아니면 더 나은 서버로 업그레이드할 때가 되었는지 알 수 없습니다. 업그레이드하고 싶지 않은데 MySQL 요청으로 인해 어딘가에 병목 현상이 발생했다는 사실을 깨달았습니다.

어떤 아이디어나 제안이라도 감사하겠습니다.

편집하다-

가상 호스트도 3개 있고 파일이 60,000개가 훨씬 넘습니다.

             total       used       free     shared    buffers     cached
Mem:          4003       3372        630          0        398       1717
-/+ buffers/cache:       1256       2746
Swap:         8189          0       8189

21:21:49 up 46 min,  1 user,  load average: 3.75, 4.20, 4.03

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  2      0 592728 409640 1838360    0    0   165   411  953  473  9  8 47 36  0

그리고 여기 최고의 스냅샷이 있습니다.

 1356 mysql     20   0 1374m 219m 5320 S  5.6  5.5  14:06.21 mysqld
15796 root      20   0  103m  20m  440 D  1.0  0.5   0:04.42 sendmail
 1081 root      20   0  103m  20m  440 D  0.7  0.5   0:21.73 sendmail
24013 root      20   0 97416  22m 2648 D  0.7  0.6   0:15.15 mailq
 1525 root      20   0  247m 7980 3472 S  0.3  0.2   0:06.88 vlogger (access
 1530 apache    20   0  539m  13m 3008 S  0.3  0.3   0:03.56 httpd
 2399 apache    20   0  539m  12m 2748 S  0.3  0.3   0:00.85 httpd
 5763 root      20   0  121m 4932 3868 S  0.3  0.1   0:00.07 sshd
12326 apache    20   0  539m  12m 2992 S  0.3  0.3   0:00.38 httpd
12421 apache    20   0  539m  12m 2988 S  0.3  0.3   0:00.45 httpd
16396 apache    20   0  538m  12m 2284 S  0.3  0.3   0:00.09 httpd
17050 root      20   0 15368 1256  868 R  0.3  0.0   0:00.09 top
    1 root      20   0 37336 4104 1908 S  0.0  0.1   0:02.82 systemd
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd
    3 root      20   0     0    0    0 S  0.0  0.0   0:00.03 ksoftirqd/0
    5 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/0:0H
    6 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kworker/u:0
    7 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/u:0H
    8 root      RT   0     0    0    0 S  0.0  0.0   0:00.11 migration/0
    9 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/0
   10 root      RT   0     0    0    0 S  0.0  0.0   0:00.14 migration/1
   12 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/1:0H
   13 root      20   0     0    0    0 S  0.0  0.0   0:00.02 ksoftirqd/1
   14 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/1
   15 root      RT   0     0    0    0 S  0.0  0.0   0:00.15 migration/2
   17 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/2:0H
   18 root      20   0     0    0    0 S  0.0  0.0   0:00.03 ksoftirqd/2
   19 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/2
   20 root      RT   0     0    0    0 S  0.0  0.0   0:00.11 migration/3
   22 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/3:0H
   23 root      20   0     0    0    0 S  0.0  0.0   0:00.02 ksoftirqd/3
   24 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/3
   25 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 cpuset
   26 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 khelper
   27 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kdevtmpfs
   28 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 netns
   29 root      20   0     0    0    0 S  0.0  0.0   0:00.00 xenwatch

답변1

매분마다 sar를 증가시키고 ps 테이블을 출력합니다. 내 자세한 답변 보기여기.

다음에 서버가 터질 때 sar -r추적에 도움이 되도록 사용하세요.언제그런 일이 일어났습니다. 이제 ps-cronjob 또는 내 출력을 사용하십시오.github의 ps용 perl 래퍼, 어떤 프로세스가 원인일 수 있는지 파악합니다.

서버가 12:00:00에서 13:00:00 사이에 폭발했다고 가정해 보겠습니다. 사용 sar -r -s 12:00:00 -e 13:00:00. 그러면 데이터가 급증하는 것을 볼 수 있습니다. (더 쉽다면 자바 기반 유틸리티를 사용하여 그래프를 그릴 수 있지만 일반적으로 번거로움을 겪을 가치는 없습니다.) 12시 15분에 급등(또는 저점)이 나타난다고 가정해 보겠습니다. 이제 열화된 ps 출력을 스캔하여 12:00에서 12:15 사이의 시간 범위를 검색하고 pid, 시간 순으로 정렬하고 메모리 열을 찾습니다.

awk '/^=== .* 12:00:/,/^=== .* 12:16:/' /var/log/sa/ps/today |
 sort -k 1n -k 16 

(정렬 옵션에서는 시간이 16열에 있다고 가정하는데, 그럴 수도 있고 아닐 수도 있습니다.) 이제 awk를 통해 해당 출력을 다시 필터링하여 출력 라인 간의 차이점을 찾을 수 있습니다.

... | awk 'lastpid && lastpid==$1 && last != $0 { print} /^[0-9]/ { lastpid=$1;last=$0; }'

참 조악한 필터네요. mysql, postgresql 및 snmpd와 같이 명령줄이 항상 변경되는 일부 프로세스의 경우 이는 별로 도움이 되지 않지만 awk를 조정하여 범인을 찾는 데 도움이 되기를 바랍니다.

관련 정보