Nginx FastCGI Cache 설정 및 그누보드5에 적용하기
컨텐츠 정보
- 17,417 조회
- 4 댓글
- 0 추천
- 목록
본문
1. Nginx에 내장된 fastcgi_cache 란?
fastcgi_cache는 기본적으로 php와 같은 동적 컨텐츠를 캐시한다고 보면 됩니다.
캐시라는 것을 간단하게 설명드리면
1 2=3 이라는 계산 및 결과가 있다고 봅시다.
캐시가 없다면 1 2를 서버에서 계산한 후 그 결과값을 보여줍니다.
캐시가 있다면 1 2를 서버에서 계산하지 않고 바로 결과값을 보여준다고 보시면 됩니다.
그러므로 서버에 부하가 거의 생기지 않게 됩니다.
그리고 당연히 속도가 빨라지며, fastcgi_cache의 경우 TTFB(첫 데이터를 받는 시간)이 절반 이하로 내려가더라구요.
또한 F5 무한 공격에 대한 방어도 가능하며, 결과적으로 DDOS에도 효과가 있습니다.
2. 캐시폴더 생성
1] 추천 경로 1
기존 Nginx가 깔려있는 폴더에 cache 라는 폴더를 만들어서 그 경로로 넣는게 좋습니다.
ex) /etc/nginx/cache 또는 /usr/local/nginx/cache
2] 추천 경로 2
/var/cache/nginx
해당 경로의 폴더를 미리 생성해둡니다.
1) 캐시폴더 메모리에 마운트하기
그리고 캐시 폴더를 생성 후 메모리에 마운트하면 메모리를 캐시폴더로 쓸 수 있습니다.
원하는 경로에 캐시 폴더를 생성 후
nano /etc/fstab
위 명령어로 들어가서
tmpfs /your/nginx/path/cache tmpfs size=100M,mode=0755 0 0
위와 같은 형식으로 캐시폴더 경로를 지정하면 됩니다. size=100M 는 메모리가 많다면 더 크게 해줘도 상관없습니다.
컨트롤 O, 엔터, 컨트롤 X 로 저장 후
mount -a
위 명령어로 마운트시킬 수 있습니다.
마운트 해제하려면
umount /your/nginx/path/cache
위 명령어를 넣으면 마운트가 해제됩니다.
2) 캐시폴더 권한 주기
Nginx에 캐시폴더 권한을 줍니다.
chown www-data:www-data /your/nginx/path/cache
3. Nginx의 설정파일 nginx.conf 설정하기
# FastCGI cache settings
fastcgi_cache_path /your/nginx/path/cache levels=1:2 keys_zone=fastcgicache:30m inactive=30m max_size=100m;
fastcgi_cache_key "$scheme$request_method$host$request_uri$mobile_request";
fastcgi_cache_use_stale error timeout invalid_header updating http_500 http_503;
fastcgi_cache_valid 200 301 302 30m;
fastcgi_cache_valid 404 1m;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_keep_conn on;
map $http_user_agent $mobile_request
{
default fullversion;
"~*phone" mobileversion;
"~*samsung" mobileversion;
"~*lgtel" mobileversion;
"~*mobile" mobileversion;
"~*[^A]skt" mobileversion;
"~*nokia" mobileversion;
"~*blackberry" mobileversion;
"~*android" mobileversion;
"~*sony" mobileversion;
"~*iphone" mobileversion;
}
map $request_method $cache_off {
default 0;
POST 1;
}
map $request_uri $cache_off {
default 0;
/bbs/login.php 1;
/bbs/logout.php 1;
/bbs/login_check.php 1;
/bbs/register.php 1;
/bbs/password_lost.php 1;
}
map $http_cookie $cache_off {
default 0;
~bG9naW4= 1; # gnuboard custom autologin-cookie
}
map $http_cookie $cache_off {
default 0;
~bG9naW5fbm9ybWFs 1; # gnuboard custom normal-cookie
}
위 설정에서 하나씩 뜯어보겠습니다.
fastcgi_cache_path /your/nginx/path/cache levels=1:2 keys_zone=fastcgicache:30m inactive=30m max_size=100m;
위 설정에서 보면 /your/nginx/path/cache 캐시폴더의 위치를 지정해주고 있습니다.
그리고 keys_zone=fastcgicache:30m 는 캐시의 이름을 fastcgicache 라고 지정하는 것이고 30m은
메모리를 30m 쓰겠다는 말입니다.
inactive=30m 는 30분 동안 접근되지 않은 캐시파일은 삭제된다는 말입니다.
max_size=100m 는 옵션입니다. 캐시파일의 총용량을 100MB라고 지정한다는 말이고, 100MB가 넘어가면
가장 먼저 생성된 캐시파일부터 삭제됩니다.
위에 100MB 용량을 메모리에 마운트 했다면 max_size 옵션을 필요없습니다. 어짜피 100MB 넘어가면 삭제되니깐요.
그리고 중요하게 봐야 될 것이 fastcgi_cache_valid 200 301 302 30m; 입니다.
응답코드가 200 301 302 로 오는 것을 캐시하고 그 캐시파일의 유효기간을 30분을 잡는 것입니다.
즉 한번 캐시되면 30분 동안 글을 쓰거나 댓글을 써도 업데이트가 되지 않습니다.
제 홈페이지처럼 블로그 역할을 하는 경우 1h 와 같이 1시간동안 캐시해도 상관없지만
커뮤니티 사이트처럼 빠르게 글이 생성되거나 댓글이 많을 경우는 1m (1분) 또는 30s (30초)도 좋은 옵션인 것 같습니다.
이건 사이트를 운영하면서 설정값을 수정해주시는게 좋을 것 같습니다. 참고로 저는 1h로 1시간 동안 유효하게 해뒀습니다.
map $http_user_agent $mobile_request
{
default fullversion;
"~*phone" mobileversion;
"~*samsung" mobileversion;
"~*lgtel" mobileversion;
"~*mobile" mobileversion;
"~*[^A]skt" mobileversion;
"~*nokia" mobileversion;
"~*blackberry" mobileversion;
"~*android" mobileversion;
"~*sony" mobileversion;
"~*iphone" mobileversion;
}
윗 부분은 기본은 fullversion이라고 지정하고, 나머지 지정된 것들은 mobileversion이라고 지정하는 것입니다.
이 부분이 들어가는 이유는, 그누보드의 경우 모바일과 PC 버전의 경로는 같지만 실제 보는 화면이 다르기 때문입니다.
이 부분이 없다면 모바일 화면으로 먼저 캐시되었다면 해당 경로로 PC에서 보면 모바일 화면으로 보입니다.
그래서 꼭 필요한 부분입니다.
map $request_uri $cache_off {
default 0;
/bbs/login.php 1;
/bbs/logout.php 1;
/bbs/login_check.php 1;
/bbs/register.php 1;
/bbs/password_lost.php 1;
}
윗 부분은 해당경로는 캐시하지 않겠다는 말입니다.
로그아웃 유저가 접근할 수 있기 때문에 넣어줬습니다.
map $request_method $cache_off {
default 0;
POST 1;
}
윗 부분은 POST의 경우 캐시를 하지 않는다라는 것입니다.
보통 글을 쓸 경우 그렇죠. 하지만 로그인 상태의 경우는 어짜피 캐시가 되지 않으니 상관없을 것 같긴하지만...
보통 지정을 많이 해두더라구요.
map $http_cookie $cache_off {
default 0;
~bG9naW4= 1; # gnuboard custom autologin-cookie
}
map $http_cookie $cache_off {
default 0;
~bG9naW5fbm9ybWFs 1; # gnuboard custom normal-cookie
}
마지막으로 윗 부분은 bG9naW4= 와 bG9naW5fbm9ybWFs 라는 쿠키가 있다면 캐시를 하지 않는다 라는 말입니다.
뒤에 gnuboard custom cookie를 붙인 이유는 제가 임의로 쿠키를 지정했기 때문입니다.
원래는 워드프레스처럼 wp-login 이라는 내용을 넣고 싶었는데... 실력부족으로 넣지 못했습니다.
이건 아래에 그누보드 쿠키 생성 부분에 좀더 글을 넣어보겠습니다.
4. sites-available의 서버 설정 수정하기
이제 Nginx의 서버 설정 파일을 수정할 차례입니다.
server { 안에 있는
location ~ \.php$ { php 로케이션 부분에 넣는 것입니다.
fastcgi_cache fastcgicache;
add_header X-Cache $upstream_cache_status;
fastcgi_cache_bypass $cache_off;
fastcgi_no_cache $cache_off;
fastcgi_cache fastcgicache; 는 fastcgicache 라는 캐시이름을 캐시로 이용하겠다는 말입니다.
add_header X-Cache $upstream_cache_status; 이 부분은 캐시에 X-Cache라는 헤더를 붙여서 실제
캐시가 HIT(적중)했는지 확인할 수 있게 해줍니다. (이건 옵션)
fastcgi_cache_bypass $cache_off;
fastcgi_no_cache $cache_off;
윗 부분은 cache_off 라고 지정된 것들은 캐시를 하지 않는다 라는 말입니다.
이제 Nginx의 설정은 끝났습니다. 설명은 엄청 길었지만 실제 적용하는 시간은 1분이 채 걸리지 않습니다.
참 쉽죠?
5. 그누보드에 로그인 로그아웃 쿠키 생성 및 제거 코드 넣기
로그인 쿠키를 넣는 이유는 유저가 로그인 했을 경우 캐시를 하지 않기 위함입니다.
이것을 지정하지 않으면 로그인하지 않은 유저가 로그인한 유저의 화면을 볼 수 있기 때문입니다.
1) /bbs/login_check.php 에는 대략 53번째 줄에 있는
// 3.26
// 아이디 쿠키에 한달간 저장
if ($auto_login) {
// 3.27
// 자동로그인 ---------------------------
// 쿠키 한달간 저장
$key = md5($_SERVER['SERVER_ADDR'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] . $mb['mb_password']);
set_cookie('ck_mb_id', $mb['mb_id'], 86400 * 31);
set_cookie('ck_auto', $key, 86400 * 31);
// 자동로그인 end ---------------------------
} else {
set_cookie('ck_mb_id', '', 0);
set_cookie('ck_auto', '', 0);
}
위 코드를
// 3.26
// 아이디 쿠키에 한달간 저장
if ($auto_login) {
// 3.27
// 자동로그인 ---------------------------
// 쿠키 한달간 저장
$key = md5($_SERVER['SERVER_ADDR'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT'] . $mb['mb_password']);
set_cookie('ck_mb_id', $mb['mb_id'], 86400 * 31);
set_cookie('ck_auto', $key, 86400 * 31);
// 자동로그인 end ---------------------------
// 자동로그인 FastCGI_Cache 용 쿠키 한달간 저장 시작 -----
set_cookie("login_check", "login", 86400 * 31);
// 자동로그인 FastCGI_Cache 용 쿠키 한달간 저장 end -----
} else {
set_cookie('ck_mb_id', '', 0);
set_cookie('ck_auto', '', 0);
// 자동로그인 FastCGI_Cache 용 쿠키 제거 시작 -----
set_cookie("login_check", '', 0);
// 자동로그인 FastCGI_Cache 용 쿠키 제거 end -----
// 일반로그인 FastCGI_Cache 용 쿠키 3시간 저장 시작 -----
set_cookie("login_check_normal", "login_normal", 10800);
// 일반로그인 FastCGI_Cache 용 쿠키 3시간 저장 end -----
}
위 코드로 완전 수정합니다.
2) /bbs/logout.php
// 자동로그인 해제 --------------------------------
set_cookie('ck_mb_id', '', 0);
set_cookie('ck_auto', '', 0);
// 자동로그인 해제 end --------------------------------
위 코드 바로 밑에
// 자동로그인 FastCGI_Cache 용 쿠키 제거 시작 -----
set_cookie("login_check", '', 0);
// 자동로그인 FastCGI_Cache 용 쿠키 제거 end -----
// 일반로그인 FastCGI_Cache 용 쿠키 제거 시작 -----
set_cookie("login_check_normal", '', 0);
// 일반로그인 FastCGI_Cache 용 쿠키 제거 end -----
위 코드들 추가
아까 윗부분에 말씀드린 bG9naW4= 쿠키 기억나시나요?
이게 바로 login 이 변환된 값입니다.
워드프레스의 경우 일반 문자인 wp-login 이라는게 들어가는데 저는 아무리해도 일반 문자가 안들어가지더라구요 ㅠㅠ
이건 혹시 아시는 분은 도움 바랍니다. (실제 기능상은 전혀 문제없습니다.)
3) /common.php
대략 386번째 줄
// 자동로그인 end-----
}
위 코드 바로 밑에
//FastCGI Cache 설정 중에 필요한 내용 시작 ---------------
if ($_SESSION['ss_mb_id']) { // 로그인중이라면 노말 쿠키 3시간 생성
set_cookie("login_check_normal", "login_normal", 10800);
} else { // 로그아웃중이라면 노말쿠키 삭제
set_cookie("login_check_normal", '', 0);
}
//FastCGI Cache 설정 중에 필요한 내용 끝 -----------------
위 코드 추가하면 됩니다.
이러면 로그인 중에는 항상 3시간짜리 쿠키가 생성이 되고, 로그인 세션이 끝난 후 로그아웃이 되면 쿠키가 삭제됩니다.
4) 소셜로그인
혹시나 아미나 소셜로그인 플러그인이나 기타 소셜로그인을 사용하고 있다면
소셜로그인 check 부분에도 쿠키 삽입 부분이 들어가야 합니다.
http://amina.co.kr/bbs/board.php?bo_table=skin_amina&wr_id=150
위 링크에 있는 아미나 소셜로그인 플러그인을 예를 들면
/plugin/login-oauth/oauth_check.php
위 파일에서
// 회원정보
$mb = get_member($mb_id);
위 내용 바로 밑에
// 일반로그인 쿠키 설정 시작------------------
// 쿠키 3시간 저장
set_cookie("login_check_normal", "login_normal", 10800);
// 일반로그인 쿠키 설정 end ------------------
위 내용을 넣어주면 됩니다.
6. Nginx Reload 시켜주기
service nginx reload
위 명령어로 리로드 시켜주고 사이트에 들어가보면 캐시된 사이트를 만나실 수 있습니다.
첫 접속은 캐시를 해야되기 때문에 평소가 같은 속도이지만, 다시 접속하거나 F5를 누르면 훨씬 빠르게 느껴시질 겁니다.
실제 캐시파일이 생성되는지 확인해보시려면 /your/nginx/path/cache 폴더에 보면 특이한 이름의 폴더가 몇개 생성된 것을 볼 수 있습니다.
7. 속도 체감을 눈으로 확인하는 방법
크롬 기준 TTFB 보는 방법을 소개해드리겠습니다.
1. F12를 누른 후 Network 항목을 클릭
2. F5를 눌러 새로고침
3. 파일이 주르륵 나오는데 해당 도메인 파일을 클릭하지 말고 오른쪽에 그래프? 같은 것이 있는데 (보라색 네모박스)
그 그래프에 마우스를 갖다대고 있으면 TTFB가 나옵니다.
TTFB는 Time To First Byte 라고 서버에 요청 후 첫번째 데이터를 받는 시간이라고 보시면 됩니다.
네이버나 SIR 같은 좋은 서버의 경우 10 ~ 20ms 정도로 최상급의 성능을 보여준다고 보시면 됩니다.
제 서버는 집에서 직접 돌리고 있는 홈서버에다가 저전력 CPU라 성능이 낮지만 fastcgi_cache로 HIT 하면 TTFB 가 10~30ms로
최상급의 서버와 비슷한 성능을 보여줍니다.
그게 바로 제가 캐시를 적용하고 싶은 이유입니다.
8. 실제 캐시된 파일이 제대로 작동하는지 보는 방법
크롬 기준 x-cache HIT 보는 방법을 소개해드리겠습니다.
F12를 눌러서 Network를 누른 후 F5를 누르면 파일이 주르륵 뜹니다.
제일 위에 있는 도메인 파일을 클릭해서 Header 정보를 보면 x-cache 부분이 있고
HIT이면 캐시된 파일이고, EXPIRED면 새로 캐시 파일을 생성한 것입니다.
그래서 FFTB를 보면 기존의 절반 이하인 것을 확인할 수 있습니다.
9. 알려진 버그
동시에 로그인한 유저가 있다면
먼저 로그인한 계정으로 댓글이 달릴 수 있습니다.
지금 해보니깐 안그런데... 어떤 상황에서 이런 일이 벌어지는지 모르겠네요. ㅠㅠ
https://www.wsgvet.com/home/511
버그는 위 링크에 정리해뒀습니다.
-
등록일 2020.09.18
-
등록일 2020.09.08도커 허브에서 매일 이미지 빌드하기댓글 2
-
등록일 2020.09.08
-
등록일 2020.07.19
관련자료
-
서명우성짱의 NAS를 운영하고 있습니다.
저의 즐거움이 여러분의 즐거움이면 좋겠습니다.
-
링크