php-fpm 메모리 누수, 사용률 확인하기


현재상황
서버 메모리 16GB

php memory limit 기본 설정(128MB)
ㄴ)메모리 리밋은 말그대로 php에서 어떤 작업을 할 때 사용할 수 있는 최대 메모리양이다. 

(예를들어 php를 통해 파일을 업로드할경우 메모리에 먼저 적재가 되기 때문에 memory_limit 값보다 높은파일은 업로드가 안됨)

pm.max_children = 50
ㄴphp-fpm의 자식프로세스 최대 갯수

pm.start_servers = 5

ㄴphp-fpm 실행하면 처음부터 실행돼잇는 자식 프로세스 갯수

pm.min_spare_servers = 5

pm.max_spare_servers = 35

ㄴmin/max값을 벗어나면 서버에서 최대한 저 값을 맞추려고 노력함


엔진엑스-php-fpm 사용중

 ~]# netstat -nlp

Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    

tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      6374/php-fpm: pool  

tcp        0      0 0.0.0.0:2221            0.0.0.0:*               LISTEN      3162/sshd           

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      7420/nginx: master  



~]# sar -r | awk '{print $1"  "$5}'

12:00:01  %memused

12:10:02  48.52

12:20:01  49.46

12:30:01  50.59

12:40:01  51.56

12:50:01  52.74

중략

03:00:01  61.27

03:10:01  61.64

03:20:01  62.09

03:30:01  62.62

03:40:02  62.73

03:50:01  63.13

04:00:01  63.26

04:10:01  63.74

중략

09:10:01  78.38

09:20:01  78.95

09:30:01  79.87

09:40:01  80.27

09:50:01  81.05


[root@ ~]# ps -ef | grep php-fpm | wc -l

37


[root@ ~]# ps -aux | grep php-fpm | awk '{print $1"  " $6/1024" MB"}'

php-fpm  342.27 MB

php-fpm  340.383 MB

php-fpm  302.711 MB

php-fpm  284.441 MB

php-fpm  227.84 MB

php-fpm  227.137 MB

root  30.1016 MB

php-fpm  561.434 MB

php-fpm  562.66 MB

php-fpm  561.309 MB

php-fpm  561.824 MB

php-fpm  561.129 MB

php-fpm  561.129 MB

php-fpm  561.176 MB

php-fpm  562.145 MB

php-fpm  561.16 MB

php-fpm  558.332 MB

php-fpm  221.172 MB

php-fpm  213.012 MB

php-fpm  213.227 MB

php-fpm  212.008 MB

php-fpm  212.664 MB

php-fpm  212.996 MB

php-fpm  213.375 MB

php-fpm  207.363 MB

php-fpm  511.531 MB

php-fpm  509.504 MB

php-fpm  509.344 MB

root  0.953125 MB

php-fpm  182.289 MB

php-fpm  181.621 MB

php-fpm  181.457 MB

php-fpm  176.219 MB

php-fpm  175.359 MB

php-fpm  174.516 MB

php-fpm  172.77 MB

php-fpm  169.117 MB


]# php test.php

echo memory_get_usage(); 349976

echo memory_get_peak_usage(); 384968





현재상황은 위와같이

1.시간이 지날수록 메모리 점유율이 올라간다. 그러다 마지막에는 oom 발생
2.php-fpm 에서의 메모리 사용률이 너무 높다. 처음에는 100MB에서 200MB 300MB 지금처럼 500MB이상까지도 차다가 마지막에 oom 발생
3.php-fpm 자식프로세스의 갯수는 37개로 pm.max_children 수치에는 못미친다. 따라서 해당 설정의 수치를 변경한다해서 해결이되지 않는다. 

4.php 에서 사용한 최대 메모리가 1메가도 안된다. 

ㄴmemory_get_peak_usage(); 384968 바이트 단위임, 메가로 환산하면 0.4메가도 안됨


궁금한점

Q)1.php.ini 의 memory_limit 이랑 php-fpm.conf 의 memory_limit 설정은 같은거고 우선순위가 있는건가 ?? 아니면 다른개념인가 ?

A)같은개념이고 우선순위는 php-fpm.conf가 먼저.. 서버 / htaccess / 소스 순인것처럼 

해당 서버의 php에서 사용된 최대 메모리는 1메가도 안되니까 memory_limit은 튜닝할필요가 없는거고. 또 추가로 자잘자잘한 엄청 수많은 작업이 종료되지않고 계속 사용하고 있따고 봐야할듯


2.php-fpm의 자식프로세스가 사용하는 memory limit은 설정이 없나 ? 


3.php-fpm의 자식프로세스들은 어떡하다가 500MB 이상씩의 메모리를 사용하게 됐지 ? 이걸 확인하는 방법은 ?(누수인지 아닌지 확인하고싶다.)

ㄴphp-fpm 자식프로세스들의 PID를 엔진엑스 어세스 로그에 남겨보는방법 ?

ㄴ아니면 php-fpm status 볼 수 있는 툴이 있나 ?






이제부터 지금 상황이 정말 메모리 누수가 맞는지. 맞다면 왜 누수가 일어나는지 알아보자.

1.netstat -an | grep -v TIME_WAIT 했을 때 수상한거 없이 소켓잘 닫히고 있음.

2.keep alive 65로 설정돼있음



으악 생각보다 너무 쉽게 원인을 찾은것같다.
https://xetown.com/tips/1171902

php-fpm 자체가 기본설정시 메모리 사용 누적이랜다...;; 

나는 소스단에서 뭔가 잘못짜여져 있어서 메모리 누수가 있는줄알았는데.. 


일단 php-fpm 아무설정도 안하면 pm.max_requests 값은 무한대라서 메모리 누수가 계속 쌓이다. 따라서 pm.max_requests 500 으로 설정해주고 한번 지켜보자.


'job > linux' 카테고리의 다른 글

ionice  (1) 2019.04.09
strace debug  (0) 2019.02.21
geoip iptables 설치  (2) 2019.02.15
rsync를 통한 파일 전송시 속도 테스트  (0) 2018.12.06
hpssacli 설치했는데 잘 안됨  (1) 2018.12.05

기존에 geoip iptables 설치하려면



./geoip/xt_geoip_dl"


./geoip/xt_geoip_build GeoIPCountryWhois.csv"


이부분 진행했었는데 이중에서 ./geoip/xt_geoip_dl" 요거 이제 에러난다.


~/geoip/xtables-addons-1.47.1/geoip]# ./xt_geoip_dl  

--2019-02-15 10:45:49--  http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz

Resolving geolite.maxmind.com... 104.16.37.47, 104.16.38.47, 2606:4700::6810:262f, ...

Connecting to geolite.maxmind.com|104.16.37.47|:80... connected.

HTTP request sent, awaiting response... 404 Not Found

2019-02-15 10:45:50 ERROR 404: Not Found.


--2019-02-15 10:45:50--  http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip

Connecting to geolite.maxmind.com|104.16.37.47|:80... connected.

HTTP request sent, awaiting response... 404 Not Found

2019-02-15 10:45:50 ERROR 404: Not Found.


gzip: GeoIPv6.csv.gz: No such file or directory

unzip:  cannot find or open GeoIPCountryCSV.zip, GeoIPCountryCSV.zip.zip or GeoIPCountryCSV.zip.ZIP.




http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz

http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip


위 두 파일이 없다고 한다. 실제로 홈페이지 들어가보면 not found 뜬다. 파일이 없다.

http://geolite.maxmind.com/download/geoip/database/ 여기까지만 들어가보면 홈페이지가 바꼈다.

https://dev.maxmind.com/geoip/geoip2/geolite2/ 여기로 들어가진다.


geolite2가 나오면서 저 파일들도 없어지고 뭐 이것저것 한것같다.


그럼 어떡해야할까 우리는 설치하고싶은데 


http://geolite.maxmind.com/download/geoip/database/GeoIPv6.csv.gz

http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip

위 두파일이 뭐로 대체됐는지 찾으면 되겠찌 ?

사실 가장 정확한 방법은 새로 변경된 geolite2 를 이용해 iptables에 적용을 해야하는데... 모르겠다. 어렵다


하여튼 다운로드 경로 들어가보면 아래 파일들이 보인다.


GeoLite2 City

GeoLite2 Country

GeoLite2 ASN (Autonomous System Number)


이중에서 시티는 말그대로 도시일꺼고 컨츄리는 나라일꺼고 ASN은 들어가보니까 sk 브로드밴드도 있고 kt도 있고한거보니까 통신사 넘버인듯


하여튼 GeoLite2 Country 이거 csv로 다운받는다.


-rw-r--r-- 1 root root 11734000 2019-02-13 07:08 GeoLite2-Country-Blocks-IPv4.csv

-rw-r--r-- 1 root root  3464092 2019-02-13 07:08 GeoLite2-Country-Blocks-IPv6.csv

-rw-r--r-- 1 root root     9864 2019-02-13 07:08 GeoLite2-Country-Locations-de.csv

-rw-r--r-- 1 root root     9937 2019-02-13 07:08 GeoLite2-Country-Locations-en.csv

-rw-r--r-- 1 root root     9992 2019-02-13 07:08 GeoLite2-Country-Locations-es.csv

-rw-r--r-- 1 root root    10230 2019-02-13 07:08 GeoLite2-Country-Locations-fr.csv

-rw-r--r-- 1 root root    14998 2019-02-13 07:08 GeoLite2-Country-Locations-ja.csv

-rw-r--r-- 1 root root    11422 2019-02-13 07:08 GeoLite2-Country-Locations-pt-BR.csv

-rw-r--r-- 1 root root    14932 2019-02-13 07:08 GeoLite2-Country-Locations-ru.csv

-rw-r--r-- 1 root root    11732 2019-02-13 07:08 GeoLite2-Country-Locations-zh-CN.csv


압축 풀어보면 이런식으로 나온다........... 안에 들어가보면 csv 양식이 바꼈따 ...... 흠


https://github.com/mschmitt/GeoLite2xtables

여기에 geolite2 를 기존 geolite .csv 로 컨버팅하는 스크립트가 있다. 요걸로 하면 잘된다 ㅋㅋ


하는방법은 아래와같다.

xt_geoip_dl 파일안의 내용을 
#########

#!/bin/bash


rm -rf GeoLite2-Country-CSV*


wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip

unzip -o -j GeoLite2-Country-CSV.zip '*/GeoLite2-Country-Blocks*'


wget http://download.geonames.org/export/dump/countryInfo.txt


cat GeoLite2-Country-Blocks-IPv{4,6}.csv | ./20_convert_geolite2 CountryInfo.txt > GeoIPCountry.csv

######

20_convert_geolite2 요것만 다운받아주고

ㄴperl 모듈 설치하라고 나오면 cpan -i NetAddr::IP 이거 하면된다.

위와같이 바꿔준다. 그리고 실행하면 된다.

나머지부터는 

check_function "./geoip/xt_geoip_build GeoIPCountry.csv"



mkdir -p /usr/share/xt_geoip

cp -r {BE,LE} /usr/share/xt_geoip/


이거 동일하게 하면됨


ps1.

"perl-Text-CSV_XS"는 쉼표(,)로 이루어진 값들을 구성하고, 분해하는 역할을 하는 패키지입니다. 엑셀 비슷하다고 보시면 됩니다.

"xtables-addons"는 커널/IPTables에서 제공하지 않는 기능을 추가적으로 지원해주는 Addons<확장팩(?) 비슷한 개념>입니다.


출처: https://sata.kr/entry/IPTables-12-IPTables에-GeoIP를-설치해보자-GeoIP-CentOS-6CentOS-7 [SATAz BLOG]

>> Real Server Group 1# cur

Current real server group 1:

  name , metric hash, backup none, realthr 0, ipver v4

  rmetric roundrobin, health tcp, content 

  DSR VIP health: enabled

  Workload Manager: none

  IDS Group: disabled  IDS rport: any   IDS flood: disabled

  Operation: enabled

  adv health: 

  real servers:

     1: 192.168.0.11, enabled, name , weight 1, timeout 10 mins, maxcon 200000

       group ena, backup none, inter 2, retry 4, restr 2

       remote disabled, proxy enabled, submac disabled

       fasthc enabled, subdmac enabled

       cookie assignment server: disabled

       exclusionary string matching: disabled

     2: 192.168.0.12, enabled, name , weight 1, timeout 10 mins, maxcon 200000

       group ena, backup none, inter 2, retry 4, restr 2

       remote disabled, proxy enabled, submac disabled

       fasthc enabled, subdmac enabled

       cookie assignment server: disabled

       exclusionary string matching: disabled

     3: 192.168.0.13, enabled, name , weight 1, timeout 10 mins, maxcon 200000

       group ena, backup none, inter 2, retry 4, restr 2

       remote disabled, proxy enabled, submac disabled

       fasthc enabled, subdmac enabled

       cookie assignment server: disabled

       exclusionary string matching: disabled

  real ports:

    4306: vport 4306, rtspslb none

      virtual server:  1, IP4 192.168.0.10,    enabled


L4 알테온 스위치에서 설정하면 메트릭은 뭔지 알겄는데 r메트릭은 뭐지 ?


metric은 뭐 말그대로 부하분산 방식 설정하는건데 구글링하면 겁내 많이 나온다.

근데 rmetric은 도대체 멀까 ? 


일단

     metric   - Set metric used to select next server in group

     rmetric  - Set metric used to select next rport in server(서버에서 다음 rport를 선택하는데 사용되는 메트릭을 설정)
라는데... 음 그렇군요


+ Recent posts