서버 운영
Nginx에서 gzip을 켰는데 JSON 응답만 그대로였던 이유
gzip on만 보고 압축이 적용됐다고 착각했던 설정 문제를 짧게 정리했다.
숫자가 이상했다
정적 파일은 압축이 잘 되는 것 같았는데, API JSON 응답은 크기가 거의 그대로였다. 서버 설정에는 분명히 gzip on;이 있었다. 그래서 처음에는 브라우저 개발자도구가 압축 전 크기를 보여 주는 줄 알고 넘어가려 했다.
확인은 curl로 했다.
curl -I -H 'Accept-Encoding: gzip' https://example.com/api/items
응답 헤더에 Content-Encoding: gzip이 없었다. 즉 브라우저 표시 문제가 아니라 실제로 압축이 적용되지 않은 상태였다.
gzip on만으로는 부족했다
Nginx는 압축할 MIME 타입을 설정으로 제한한다. 기본값만 믿으면 내가 기대한 타입이 빠질 수 있다. 설정을 열어 보니 gzip_types에 JSON이 없었다.
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types
text/plain
text/css
application/javascript
application/json
application/rss+xml
image/svg+xml;
추가 후에는 설정 검사를 먼저 했다.
sudo nginx -t
sudo systemctl reload nginx
여기서 restart 대신 reload를 쓴 이유는 설정만 다시 읽으면 충분했기 때문이다. 물론 nginx -t가 실패하면 reload도 하지 않았다.
프록시 응답에서 확인한 것
내 API는 Node 서버 뒤에 있었고 Nginx가 reverse proxy 역할을 했다. 그래서 upstream이 이미 압축을 했는지, Nginx가 다시 압축하는지 헷갈렸다. 일단 Node 쪽 압축 미들웨어는 끄고 Nginx에서만 담당하게 했다. 작은 프로젝트에서는 압축 위치가 여러 군데인 것보다 한 군데인 편이 확인하기 쉬웠다.
curl -s -H 'Accept-Encoding: gzip' -D - https://example.com/api/items -o /dev/null
이 명령으로 Content-Encoding만 봐도 적용 여부는 빠르게 알 수 있었다.
적용 전 체크리스트
Accept-Encoding: gzip을 보낸 요청으로 확인한다.gzip_types에 실제 응답의 Content-Type이 들어 있는지 본다.- 너무 작은 응답은
gzip_min_length때문에 압축되지 않을 수 있다. - 이미지처럼 이미 압축된 파일은 gzip 효과가 거의 없다.
- 설정 변경 뒤
nginx -t를 먼저 실행한다.
마무리
이번 실수는 설정 한 줄을 봤다고 전체 동작을 안다고 생각한 데서 나왔다. 압축은 켰는지가 아니라, 내가 줄이려는 응답에 실제로 Content-Encoding이 붙는지까지 확인해야 끝이었다.