웹사이트 검색

VPS에서 Nginx로 FastCGI 캐싱을 설정하는 방법


전주곡

Nginx에는 PHP 백엔드에서 제공되는 동적 콘텐츠를 캐싱하기 위한 지시문이 있는 FastCGI 모듈이 포함되어 있습니다. 이를 설정하면 리버스 프록시(Varnish 생각) 또는 애플리케이션별 플러그인과 같은 추가 페이지 캐싱 솔루션이 필요하지 않습니다. 요청 방법, URL, 쿠키 또는 기타 서버 변수에 따라 콘텐츠를 캐싱에서 제외할 수도 있습니다.

VPS에서 FastCGI 캐싱 활성화

이 문서에서는 캐싱을 활성화해야 하는 가상 호스트 구성 파일을 이미 설정하고 구성했다고 가정합니다.

nano /etc/nginx/sites-enabled/vhost

서버 { } 지시문 외부의 파일 맨 위에 다음 줄을 추가합니다.

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

"fastcgi_cache_path” 지시어는 캐시 위치(/etc/nginx/cache), 크기(100m), 메모리 영역 이름(MYAPP), 하위 디렉토리 수준 및 비활성" 타이머

위치는 하드 디스크의 아무 곳이나 될 수 있습니다. 그러나 크기는 드롭릿의 RAM + 스왑보다 작아야 합니다. 그렇지 않으면 "메모리를 할당할 수 없습니다.\라는 오류가 표시됩니다. 제거 섹션에서 "레벨\ 옵션을 살펴보겠습니다. "비활성\ 옵션에 지정된 특정 시간(여기서는 60분) 동안 캐시에 액세스하지 않으면 Nginx가 캐시를 제거합니다.

"fastcgi_cache_key\ 지시어는 캐시 파일 이름을 해시하는 방법을 지정합니다. Nginx는 이 지시어를 기반으로 액세스된 파일을 MD5로 암호화합니다.

다음으로 PHP 요청을 php5-fpm으로 전달하는 위치 지시문을 이동합니다. "location ~ .php${ }\ 안에 다음 줄을 추가합니다.

fastcgi_cache MYAPP;
fastcgi_cache_valid 200 60m;

"fastcgi_cache” 지시어는 우리가 "fastcgi_cache_path” 지시어에 지정한 메모리 영역 이름을 참조하고 이 영역에 캐시를 저장합니다.

기본적으로 Nginx는 X-Accel-Expires/Expires/Cache-Control 헤더에 지정된 기간 동안 캐시된 객체를 저장합니다.

"fastcgi_cache_valid\ 지시문은 이러한 헤더가 누락된 경우 기본 캐시 수명을 지정하는 데 사용됩니다. 위에서 입력한 명령문에서는 상태 코드가 200인 응답만 캐시됩니다. 다른 응답 코드도 지정할 수 있습니다.

구성 테스트 수행

service nginx configtest

모든 것이 정상이면 Nginx를 다시 로드하십시오.

service nginx reload

완전한 vhost 파일은 다음과 같습니다.

fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

server {
    listen   80;
    
	root /usr/share/nginx/html;
	index index.php index.html index.htm;

	server_name example.com;

	location / {
	    try_files $uri $uri/ /index.html;
    }

	location ~ \.php$ {
	    try_files $uri =404;
	    fastcgi_pass unix:/var/run/php5-fpm.sock;
	    fastcgi_index index.php;
	    include fastcgi_params;
	    fastcgi_cache MYAPP;
	    fastcgi_cache_valid 200 60m;
    }
}

다음으로 캐싱이 작동하는지 확인하기 위해 테스트를 수행합니다.

VPS에서 FastCGI 캐싱 테스트

UNIX 타임스탬프를 출력하는 PHP 파일을 만듭니다.

 /usr/share/nginx/html/time.php

끼워 넣다

<?php
echo time();
?>

curl 또는 웹 브라우저를 사용하여 이 파일을 여러 번 요청하십시오.

root@droplet:~# curl http://localhost/time.php;echo
1382986152
root@droplet:~# curl http://localhost/time.php;echo
1382986152
root@droplet:~# curl http://localhost/time.php;echo
1382986152

캐싱이 제대로 작동하면 응답이 캐싱될 때 모든 요청에 동일한 타임스탬프가 표시되어야 합니다.

이 요청의 캐시를 찾으려면 캐시 위치의 재귀적 목록을 작성하십시오.

root@droplet:~# ls -lR /etc/nginx/cache/
/etc/nginx/cache/:
total 0
drwx------ 3 www-data www-data 60 Oct 28 18:53 e

/etc/nginx/cache/e:
total 0
drwx------ 2 www-data www-data 60 Oct 28 18:53 18

/etc/nginx/cache/e/18:
total 4
-rw------- 1 www-data www-data 117 Oct 28 18:53 b777c8adab3ec92cd43756226caf618e

명명 규칙은 제거 섹션에서 설명합니다.

또한 Nginx가 응답에 "X-Cache\ 헤더를 추가하여 캐시가 누락되었는지 적중되었는지 표시할 수 있습니다.

server { } 지시문 위에 다음을 추가합니다.

add_header X-Cache $upstream_cache_status;

Nginx 서비스를 다시 로드하고 curl을 사용하여 자세한 요청을 수행하여 새 헤더를 확인합니다.

root@droplet:~# curl -v http://localhost/time.php
* About to connect() to localhost port 80 (#0)
*   Trying 127.0.0.1...
* connected
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /time.php HTTP/1.1
> User-Agent: curl/7.26.0
> Host: localhost
> Accept: */*
>
* HTTP 1.1 or later with persistent connection, pipelining supported
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 29 Oct 2013 11:24:04 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-Cache: HIT
<
* Connection #0 to host localhost left intact
1383045828* Closing connection #0

캐시 예외 설정

인증이 필요한 페이지와 같은 일부 동적 콘텐츠는 캐시되지 않아야 합니다. 이러한 콘텐츠는 "request_uri\, "request_method\ 및 "http_cookie\와 같은 서버 변수를 기반으로 캐시에서 제외될 수 있습니다.

다음은 server{ } 컨텍스트에서 사용해야 하는 샘플 구성입니다.

#Cache everything by default
set $no_cache 0;

#Don't cache POST requests
if ($request_method = POST)
{
    set $no_cache 1;
}

#Don't cache if the URL contains a query string
if ($query_string != "")
{
    set $no_cache 1;
}

#Don't cache the following URLs
if ($request_uri ~* "/(administrator/|login.php)")
{
    set $no_cache 1;
}

#Don't cache if there is a cookie called PHPSESSID
if ($http_cookie = "PHPSESSID")
{
    set $no_cache 1;
}

"$no_cache” 변수를 적절한 디렉티브에 적용하려면 location ~ .php${ } 안에 다음 줄을 배치합니다.

fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;

"fasctcgi_cache_bypass\ 지시어는 이전에 설정한 조건과 관련된 요청에 대해 기존 캐시를 무시합니다. "fastcgi_no_cache\ 지시어는 지정된 조건이 충족되면 요청을 전혀 캐시하지 않습니다.

캐시 제거

캐시의 이름 지정 규칙은 "fastcgi_cache_key\ 지시문에 대해 설정한 변수를 기반으로 합니다.

fastcgi_cache_key "$scheme$request_method$host$request_uri";

이러한 변수에 따르면 "http://localhost/time.php\를 요청했을 때 다음이 실제 값이었을 것입니다.

fastcgi_cache_key "httpGETlocalhost/time.php";

MD5 해싱을 통해 이 문자열을 전달하면 다음 문자열이 출력됩니다.

b777c8adab3ec92cd43756226caf618e

이것은 "levels=1:2”를 입력한 하위 디렉토리에 대한 캐시의 파일 이름을 형성합니다. 따라서 디렉토리의 첫 번째 수준은 이 MD5 문자열의 마지막 e에서 1 문자로 이름이 지정되고 두 번째 수준은 마지막 2 첫 번째 수준 이후의 문자, 즉 18 따라서 이 캐시의 전체 디렉터리 구조는 다음과 같습니다.

/etc/nginx/cache/e/18/b777c8adab3ec92cd43756226caf618e

이 캐시 이름 지정 형식을 기반으로 원하는 언어로 제거 스크립트를 개발할 수 있습니다. 이 자습서에서는 __POST__ 처리된 URL의 캐시를 제거하는 간단한 PHP 스크립트를 제공합니다.

<코드>/usr/share/nginx/html/purge.php

끼워 넣다

<?php
$cache_path = '/etc/nginx/cache/';
$url = parse_url($_POST['url']);
if(!$url)
{
    echo 'Invalid URL entered';
    die();
}
$scheme = $url['scheme'];
$host = $url['host'];
$requesturi = $url['path'];
$hash = md5($scheme.'GET'.$host.$requesturi);
var_dump(unlink($cache_path . substr($hash, -1) . '/' . substr($hash,-3,2) . '/' . $hash));
?>

제거할 URL과 함께 이 파일에 POST 요청을 보냅니다.

curl -d 'url=http://www.example.com/time.php' http://localhost/purge.php

스크립트는 캐시가 제거되었는지 여부에 따라 true 또는 false를 출력합니다. 이 스크립트를 캐시에서 제외하고 액세스를 제한하십시오.

제출자: 제신A