[워드프레스 최적화] FastCGI cache 적용 워드프레스 반응 속도 및 서버 로드 줄이기

|

오늘은 워드프레스 속도를 빠르게 하는 방법 중 상당히 효과가 좋은 FastCGI cache에 대해서 알아보도록 하겠습니다.

1. FastCGI cache란?

일반적으로 사용자가 브라우저를 통해서 특정 페이지를 보겠다고 요청하면 NGINX는 PHP와 MySQL이라는 데이타베이스에게 명령을 내려 사용자가 요청한 페이지를 구성하게 하는데요. FastCGI는 NGINX와 PHP 사이에서 기존에 불러왔던 페이지를 저장해 놓고 있다가 사용자 요청이 오면 PHP나 MySQL의 도움없이 바로 사용자에게 보여주어 굉장히 빨리 처리해 속도를 높이고 시스템의 부하를 줄이는 역활을 합니다. 이를 업계에선 Full page caching이라고 부르고 있네요.

아래는 FastCGI가 작동하는 다이어그램인데요. NGINX, PHP-FPM, MySQ 사이의 관계를 잘 보여주고 있습니다.

FastCGI 작동 방식 다이어그램 ashleys-server-architecture

FastCGI cache는 서버 부하를 줄여주고, 사이트 속도를 빠르게 해주는데요. cache된 페이지 중심이긴 하지만 속도가 빨라지고 TTFB(Time To First Byte, 서버에 요청해 첫 데이타를 받기까지 걸리는 시간)가 절반이하로 줄어듭니다.

2. FastCGI cache 적용 방법

그러면 이런 FastCGI cache를 적용하려면 어떻게 해야 할까요?

아래와 같이 순서대로 적용해 보시지요. FastCGI cache는 서버를 설치(NGINX, PHP, MariaDB 등) 시 자동으로 설치되므로 설되어 있는 기준으로 세팅을 어떻게 하는냐를 말씀드리겠습니다.

2.1. Nginx의 설정파일 nginx.conf 설정하기

먼저 Nginx의 설정파일인 nginx.conf에서 FastCGI cache 관련 내용을 설정합니다.

여기는 Nginx의 설정 파일 중 http 구간에 적용하는 코드가 되겠습니다.

FastCGI cache path 위치 지정

FastCGI cache path 위치는 아무 곳이라도 상관이 없습니다. 아래는 FastCGI cache path 위치를 일반 디스크에 할것인지 아니면 빠른 RAM 메모리에 할것인지에 따라 조금씩 달라집니다.

저는 용량은 적지만 빠른 RAM 메모리에 했는데요. 여기서는 두가지 경우를 모두 표현 했습니다.

# 일반 디스크에 6999MB 용량에 cache해 캐시 유효기간을 10분으로 유지하는 WORDPRESS라는 캐시 이름
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=WORDPRESS:699mb inactive=10m; # Disk애 적용 시 

# RAM 메모리 512MB 용량을 할당, 10분동안 유지하는 WORDPRESS라는 캐시 이름
fastcgi_cache_path /dev/shm/fastcgi levels=1:2 keys_zone=WORDPRESS:512m inactive=10m; #RAM에 적용 시

여기서 정말 강조하고 싶은 것은 위치 지정 후 정말 제대로 작동하는지를 꼭 확인하라는 것입니다. path 설정해 놓는다고 다 작동하지는 않으며 RAM에 올리는 방식 또는 Disk에 설정시 스왑등이 제대로 설정되어 있는지에 따라서 제대로 작동하지 않을 수 있습니다.

FastCGI cache 중 발생 상황 대응 지정

그 다음은 FastCGI가 디스크에 파일을 배치하는 방법, FastCGI 서버와의 통신 중에 오류 발생 시 하는 경우 등 오래된 캐시를 사용할 수 있는 경우, 워드프레스 테마 중 종종 부적절한 헤더값을 보내주는 경우 무시하라는 옵션을 표기합니다.

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_ignore_headers Cache-Control Expires Set-Cookie;

FastCGI cache 조건 설정

fastcgi_cache_valid 200 301 302 60m;
fastcgi_cache_valid 404 30s; 
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_keep_conn on;
  • 여기서 fastcgi_cache_valid 200 301 302 60m;은 응답코드가 200 301 302인 것을 캐시하고 그 캐시파일의 유효기간을 60분을 잡는 것입니다. 개인 사이트는 변경 내용이 많지 않으니 넉넉하게 시간을 주어도 좋을 것이고, 커뮤니티 사이트는 빨리 내용이 갱신되므로 1m(1분) 또는 30s(30초) 단위로 짧은 시간을 주는게 좋다고 합니다.

  • fastcgi_cache_valid 404 30s;은 응답코드가 404인 것은 30초마다 다시 갱신토록 했습니다.

  • fastcgi_buffers 16 16k; , fastcgi_buffer_size 32k;는 캐시 버터 크기 설정입니다.

FastCGI 캐시를 메모리에서 작동시키기

FastCGI를 일반 디스크에서 실행하는 것보다도 RAM 메모리에서 실행시키면 더욱 빠르겠죠.
RAM 시스템 메모리는 디스크보다 훨씬 빠르니 반응시간도 훨씬 빨라질 것 입니다.

먼저 RAM 디스크를 등록해 줍니다. /etc/fstab 파일을 nano 편집기를 열어 편집할 수 있도록 합니다.

nano -w /etc/fstab


fstab에서 아래와 같이 RAM 디스크를 등록해 줍니다.

tmpfs /dev/shm/fastcgi tmpfs defaults,size=128M 0 0


다음에는 RAM Disk를 구성할 디렉토리와 소유권등을 정리해 줍니다. RAM Disk로 /dev/shm/fastcgi를 나들겠습니다.

mkdir  /dev/shm/fastcgi
chown www-data:www-data /dev/shm/fastcgi
chmod +x /dev/shm/fastcgi

이러면 자동으로 디렉토리를 만들고

그리고 나서 NGINX 시스템을 다시 실행합니다.

service nginx restart

이제 새로운 RAM Disk를 마운트합니다.

mount -a

참고로 RAM Disk를 없애려면 /etc/fstab에서 Ram 디스크를 지우고, 터미널에서 umount 명령을 사용합니다.

umount /dev/shm/fastcgi


Nginx에 캐시폴더 권한을 줍니다

chown www-data:www-data /dev/shm/fastcgi

2.2. 서버 블락에서 FastCGI cache 설정

지금부터는 서버 블락에서 FastCGI cache 관련 옵션 정리 방법입니다.

캐싱을 하지 말아야 할 경우 설정

캐싱을 하지 말아야 할 경우가 있는데 이 구간을 정의하는 부분입니다.

    set $skip_cache 0;

    # ---------------------------------------------------------------------
    # 캐싱을 하지 말아야 할 경우가 있는데 이를 정의하는 구간 CACHE SKIP RULES - START
    # ---------------------------------------------------------------------

    # Do not cache POST requests - they should always go to PHP
        if ($request_method = POST) {
       set $skip_cache 1;
    }

    # Do not cache URLs with a query string - they should always go to PHP
    if ($query_string != "") {
       set $skip_cache 1;
    }

    # WooCommerce-specific cache skip rules
    if ($request_uri ~* "/store.*|/cart.*|/my-account.*|/checkout.*|/addons.*") {
    set $skip_cache 1;
       set $skip_cache_reason WP_WooCommerce;
    }

    if ($cookie_woocommerce_items_in_cart) { 
       set $skip_cache 1; 
       set $skip_cache_reason WP_WooCommerce;
    }

    if ($request_uri ~* ("/cart.*")) { 
       set $skip_cache 1; 
    }

    # Don't cache URIs containing the following segments (admin panel, sitemaps, feeds, etc.)
    if ($request_uri ~* "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
    set $skip_cache 1;
    }

    # Don't use the cache for logged-in users or recent commenters
    if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
    set $skip_cache 1;
    }

    # ---------------------------------------------------------------------
    # CACHE SKIP RULES - END
    # ---------------------------------------------------------------------

FastCGI와 PHP-FPM과 통합

이제 FastCGI cache와 PHP간 통합을 정의합니다.
이 부분도 마찬가지로 server 블락에 아래 내용을 추가 합니다.

    # Add PHP handler
    location ~ \.php$ {

    try_files $uri =404; # comment out this line if php-fpm is hosted on a remote machine
    include /etc/nginx/fastcgi.conf;
    fastcgi_cache WORDPRESS;
    add_header X-Cache $upstream_cache_status;
    fastcgi_pass unix:/run/php/php7.2-fpm.sock;

    fastcgi_cache_bypass $skip_cache;
    fastcgi_no_cache $skip_cache;

    fastcgi_split_path_info ^(.+?\.php)(/.*)$;
    if (!-f $document_root$fastcgi_script_name) {
        return 404;
        }
    }

3. NGINX 재가동 및 작동 테스트

FastCGI 설정이 완료되면 nginx를 다시 가동시키고 제대로 작동하는지 테스트 해 봅니다.

먼저 문법 상 충돌되거나 오류가 없는지 config test를 진행합니다.

service nginx configtest


“the configuration file /etc/nginx/nginx.conf syntax is ok” 라는 문구가 나오면 정상적으로 작동 가능한 것이므로 nginx를 다시 가동시킴니다.

service nginx restart


이제 FastCGI가 제대로 작동하는지 확인해 봅니다.

ls -alhR /dev/shm/fastcgi


그러면 현재 cache되고 있는 리스트가 주욱 나옵니다. 그러면 정상적으로 작동하는 것이니 기쁜 마음으로 마무리 합니다.

4. 시행 착오

무사히 FastCGI를 설치하고 작동하는 것을 확인하고부터 사이트의 속도가 굉장히 빨라졌습니다. 그리고 욕심을 내어서 몇가지를 조정했습니다.

  • 먼저 cache를 램에 올리고 메모리를 512MB을 할당했습니다.
  • 다음 cache 교체 시간을 1440m으로 상당히 길게 잡았습니다. 내용이 많이 바뀌지 않기 때문에 여유있게 잡아본 것입니다.

이렇게 설정을 바꾼 후 처음 엄청 빠른 속도를 보여 주었던 것이 시간이 지나면서 엄청 느려지기 시작했습니다. 사이트 메인의 TTFB가 처음에는 0.3ms정도였는데 어느 순간 1.3s까지 느려지더군요.

세팅 초기의 webpagetest.org 측정 결과

일정 시간 경과 후 webpagetest.org 측정 결과

왜 이런 문제가 발생했을까 여러가지 설정 테스트를 해보니 cache 유지 시간이 길고, RAM 512MB에 세팅한 cache가 꽉 찬 상태에서는 무엇인가가 제대로 작동하지 않는다는 결론을 얻었습니다.
cache를 비우고 cache 설정 시간을 30m 정도로 줄이니 제대로 작동했으니깐요.

결국 cache 메모리가 적다면 cache 교체 시간을 짧게 설정해야 한다는 결론을 얻었습니다.

5. 참고 포스팅

[워드프레스 최적화] OPcache를 활용한 워드프레스 속도 최적화 방안

[워드프레스 최적화] 워드프레스에서 Memcached 이용해보기 – Ubuntu 16.04 + Nginx + PHP 7

10$ 제휴 프로모션으로 Vultr 가입하기

Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

[…] [워드프레스 최적화] FastCGI cache 적용 워드프레스 반응 속도 및 서버 로드 줄… […]