Infrastructure/nginx
- NGINX 미러링 모듈을 이용한 Proxy 효율성 증진 2024.03.08
- [NGINX] 엔진엑스 조건부 로깅을 활용한 효율적인 로깅 구성 2023.08.11
- "NGINX, 기술 부채가 되지 않으려면?", 라인개발실록 개발자 밋업! 2023.03.11
- nginx 업데이트 후 재시작 되지 않는 문제의 해결 2019.05.22
NGINX 미러링 모듈을 이용한 Proxy 효율성 증진
[NGINX] 엔진엑스 조건부 로깅을 활용한 효율적인 로깅 구성
엔지니어에게 로그는 물과 같습니다.
무슨 일이 일어나더라도 충분한 로그가 있으면 해결할 수 있기 때문입니다.
다양한 환경에서 Proxy로 활용되는 엔진엑스에서도 마찬가지입니다.
문제는 로그가 너무 많은 경우 인스턴스 운용이 어려울 수 있다는 것이죠.
원칙#1, 로그는 일단 끄고 시작하자
이게 무슨말이냐구요?
로그를 왜 끄고 시작하냐구요?
네, 로그를 끄고 시작하는 것을 권장합니다.
엔진엑스 구성 파일은 복잡합니다.
여러개의 분리된 파일을 include 로 쓰는 것이 기본 구성이고
디폴트 구성 자체가 이렇게 되어 있다보니
대부분 nginx.conf 에서 /conf.d/*.conf 로 이어지는 구성을
채택하고 사용하고 계실 겁니다.
권고 드리는 기본 구성은 nginx.conf 에서 access_log를 끄고
location 지시자 등 필요한 경우에 access_log를 활성화하는 방식입니다.
// nginx.conf
http {
...
log_format main '$remote_addr - $remote_user [$time_local] "$scheme" "$request" '
'$status $upstream_status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$http_host" "$upstream_addr"';
access_log off;
...
...
include /etc/nginx/conf.d/*.conf;
}
위 설정은 nginx 기본 설정 파일인 nginx.conf의 예입니다.
http 서빙을 위해 http 블록이 들어가 있고
로그 형식을 지정하는 log_format과 access_log 지시자가 있습니다.
access_log 는 기본적으로 활성화 되어 있기 때문에
off 를 지정하여 http 요청에 대해 기본적으로 로깅을 하지 않도록 구성했습니다.
패키지 저장소에서 nginx를 설치했기 때문에 /etc/nginx/에 필요한 파일들이 위치해 있고
conf.d 경로 아래의 conf 확장자를 가진 파일들을 include 하고 있습니다.
원칙#2, 로그는 필요한 경우에만 켜자
로깅을 껐으면 이제는 필요한 부분에서 로깅을 켜야 합니다.
보통은 location 블록을 활용해 업스트림 서버를 구분하거나
필요한 프록시 기능을 구현하고 계실겁니다.
다음의 설정은 location 블록 내에서 로깅을 활성화하는 예시입니다.
// /conf.d/default.conf
server {
...
location = /no-log-path {
...
## 여러 설정들 ##
...
}
location = /admin {
...
access_log /var/log/nginx/admin.access.log main;
...
}
}
이렇게 구성하면 /no-log-path 경로로 들어오는 요청들은
앞서 http 블록에서 지정한 access_log off 에 따라 로깅을 하지 않습니다.
대신 중요한 경로인 /admin 으로 들어오는 요청들은
앞서 지정한 main 로그 형식에 따라 지정된 경로에 로그를 남기게 됩니다.
원칙#3, 필요한 경우 샘플링해서 로그를 남기자
이렇게 필요한 경우에만 로그를 남기도록 구성했더라도
요청량이 너무 많은 경우에는 제한적으로 로그를 남길 필요가 있습니다.
엔진엑스의 access_log 지시자는 if 구문을 이용해 조건부로 활성화 할 수 있습니다.
위의 예제를 조금 수정해 보겠습니다.
// /conf.d/default.conf
split_clients $remote_addr $is_need_to_logged {
5% 1;
* 0;
}
server {
...
location = /no-log-path {
...
## 여러 설정들 ##
...
}
location = /admin {
...
access_log /var/log/nginx/admin.access.log main if=$is_need_to_logged;
...
}
}
split_clients 지시자를 이용해 사용자 IP중 5%에 대해서
$is_need_to_logged 라는 변수 값을 1로 지정하도록 했습니다.
1은 true의 의미를 갖는다는 것을 활용해 access_log 지시자의 if 구문에 활용했습니다.
이렇게 구성한 설정의 흐름을 정리하면 다음과 같습니다.
- 엔진엑스 서버로 http 요청이 들어오면 일단 로그를 비활성화 한다
- /admin 경로로 들어오는 요청은 main 형식으로 /var/log/nginx/admin.access.log 파일에 로그를 기록한다
- 다만, 요청 사용자 IP기준으로 5%의 사용자에 대해서만 로그를 남긴다
로그는 중요합니다.
하지만 로그는 가장 큰 부담중 하나입니다.
적절한 규모로 로그를 관리하는 것이
편안한 취침의 지름길입니다.
엔진엑스의 다양한 활용에 대해 알고싶다면
제가 번역한 <엔진엑스 쿡북>을 읽어보시는 건 어떨까요? :-)
본 포스팅은 제휴 마케팅을 통해
소정의 수수료를 지급받는 링크를 포함하고 있습니다
"NGINX, 기술 부채가 되지 않으려면?", 라인개발실록 개발자 밋업!
얼마전 회사 공식 유튜브 채널에서 개발자 밋업 영상을 찍었습니다.
근래에 회사 공식 유튜브나 블로그에 뭔가 기여한 기억도 없고 하여
겸사겸사 "NGINX 쿡북" 2판 번역서 출간 홍보도 할겸 전격 촬영에 임했습니다.
유튜브 라이브로 진행되는 회사 관련 액티비티는
신년대응 관련해서 진행했던 세션 이후로 간만이라.. 감회가 새로웠습니다.
재미있는 것은 이 영상을 찍은 이후에도 회사내에서 NGINX 관련한 이슈들에 난입할 계기가 있었고
세션에서 했던 이야기들이 헛되지 않았구나 하는 생각을 했었습니다 ^^;
아무쪼록 재미있게 봐주시면 좋겠습니다.
이것도 벌써 찍은지 2주가 넘어가는..ㅎㅎ
nginx 업데이트 후 재시작 되지 않는 문제의 해결
nginx 에서 mirror 모듈을 쓰기 위해 사용중인 버전 (1.12.x) 에서
해당 모듈을 지원하는 최신 버전으로 업데이트를 했습니다.
특별히 문제가 없겠지라고 생각했지만 역시 문제가 생겼으며
에러 메세지에서 단서를 찾아볼 수 있었습니다. =_=
에러의 내용을 붙여넣어 보자면 아래와 같습니다.
기본적으로 설치된 모듈의 버전과 업데이트를 통해 설치된 버전이 차이가 있었던 것 같습니다.
적절한 경로의 버전을 로딩하게 하는 방법을 찾는 것보다 더 쉬운 방법은 없을까 찾아보니 역시 있더군요.
[emerg] module "/usr/lib64/nginx/modules/ngx_http_geoip_module.so" version 1012002 instead of 1016000 in /usr/share/nginx/modules/mod-http-geoip.conf:1
모듈로 인한 문제가 발생했을 때 가장 쉽게 처리하는 방법은 재설치!
yum 을 이용해서 nginx 공식 레파지토리를 썼기 때문에
일단 현재의 모든 모듈을 삭제하고 공식 레파지토리의 모듈로 재설치를 진행했습니다.
// 설치된 모듈을 삭제합니다
$ sudo yum remove nginx-mod*
// 공식 레파지토리에서 새로운 모듈을 설치합니다
$ sudo yum install nginx-module-*
이후 nginx 를 재기동하니 문제없이 로딩 완료!
참고로 공식 레파지토리를 이용하기 위해서는
아래와 같이 레파지토리 정보를 등록하시면 됩니다.
mainland 버전을 사용하지 않는다면, 두번째의 섹션은 불필요합니다.
// 경로 : /etc/yum.repos.d/nginx.repo
// 참고 : http://nginx.org/en/linux_packages.html#RHEL-CentOS
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key