PHP는 약 80%의 시장 점유율을 기록하며 서버 측 웹 애플리케이션을 만드는 가장 인기 있는 방법입니다. (ASP.net은 2위, Java는 그보다도 훨씬 뒤떨어진 3위를 차지했습니다.)
PHP 세계에는 다양한 PHP 프레임워크가 포함되어 있으며, 가장 인기 있는 프레임워크로는 Laravel, Phalcon, Symfony 2가 있습니다. PHP는 WordPress 와 Drupal 과 같은 인기 있는 콘텐츠 관리 시스템(CMS)의 기반이기도 합니다. (최신 Drupal 릴리스인 Drupal 8에는 Symfony 2가 상당히 통합되어 있습니다.
이제 PHP 팀은 PHP 5가 출시된 지 10년이 넘은 새로운 버전인 PHP 7을 출시합니다. 이 기간 동안 웹 사용과 웹사이트에 대한 수요는 기하급수적으로 증가했습니다. PHP는 그 급속한 성장에 기여했지만 PHP의 한계 또한 PHP가 가능하게 한 성장 그 자체로 인해 더욱 부각됩니다.
PHP는 일반적으로 강력하고 유연한 것으로 여겨지지만 성능 문제가 있습니다. PHP 기반 사이트는 트래픽 수가 몇 배로 늘어나도 쉽게 "벽에 부딪힐" 수 있습니다. 사이트가 사업 또는 운영 목표를 달성하기 시작하자마자 트래픽 양이 늘어날 때마다 충돌이 발생하기 시작합니다.
수천 개의 PHP 기반 애플리케이션의 경우, 비교적 간단한 몇 가지 변경만으로도 성능을 개선하기에 충분했습니다. 여기에는 memcached
와 같은 도구를 사용한 캐싱, 데이터베이스 튜닝, NGINX Open Source 와 NGINX Plus를 사용한 역방향 프록시 및 부하 분산이 포함됩니다. NGINX는 앱 반응성을 크게 개선해 사용자와 트래픽이 엄청나게 증가하는 상황을 지원했습니다.
이 블로그 게시물은 PHP 7을 사용하는 웹사이트의 성능을 극대화하는 방법에 대한 2부작 시리즈의 첫 번째 글입니다. 여기에서는 PHP 7로의 업그레이드, 웹 서버 소프트웨어로 NGINX 오픈 소스 또는 NGINX Plus 구현, URL 재작성(요청을 적절히 처리하는 데 필요), 정적 파일 캐싱 및 동적 파일 캐싱(애플리케이션 캐싱 또는 마이크로 캐싱이라고도 함)에 중점을 둡니다.
다음 블로그 게시물에서는 추가 서버에서 취할 수 있는 단계에 대해 중점적으로 설명하겠습니다. 여기에는 역방향 프록시 서버 추가, 여러 애플리케이션 서버로 이동, 여러 서버 간 로드 밸런싱, 로드 밸런싱 중 세션 지속성 지원, SSL/TLS 및 관련 HTTP/2 프로토콜과 같은 보안 프로토콜 종료 등이 포함됩니다.
PHP 애플리케이션이 벽에 부딪히는 이유는 무엇인가? 같은 이유로 모든 애플리케이션 서버 소프트웨어는 벽에 부딪힙니다. 사용자 요청이 들어오면 PHP와 이를 실행하는 웹 서버 소프트웨어는 여러 가지 작업을 수행해야 합니다.
이는 물리적 서버, 가상 머신 또는 클라우드 서버 인스턴스가 모든 요청을 처리하기에는 너무 많은 양입니다. 서버 머신의 실제 메모리(물리적이든 가상이든)가 소진되면 성능이 저하되는 경향이 있습니다. 그러면 서버는 새로운 요청이 들어오면 현재 세션을 디스크에 페이징하기 시작합니다. 파일 요청이 처리되기를 기다리는 동안 페이징에 영향을 미치는 대기 상태가 발생합니다. 특정 시점(매우 제한적인 시점)을 지나면 페이지 작업과 데이터 요청이 처리 작업에 과부하를 일으키고, 성능은 급격히 떨어져서 좌절한 사용자는 오랜 대기 시간이나 세션 종료를 경험하게 됩니다.
PHP의 성능 장벽을 극복하는 것은 확실히 가능하며, 이를 위해서는 몇 가지 보완적인 단계가 필요합니다. 각 단계는 다른 단계와 결합될 수 있습니다. 대략 다음과 같은 것들이 포함됩니다.
이러한 단계를 어떤 특별한 순서에 따라 구현할 필요는 없습니다. 예를 들어, 웹 서버로 Apache를 유지하고 앱 서버를 PHP 7로 업그레이드하지 않더라도 기존 서버 "앞에" NGINX를 역방향 프록시로 구현하기만 해도 성능이 향상되고 여러 애플리케이션 서버를 병렬로 구현할 수 있습니다.
어떤 방법을 택하든, 가장 중요한 사실은 현재 애플리케이션 코드를 거의 또는 전혀 변경하지 않고도 여러 가지 요소로 성능을 향상시키고 용량도 수십 배 늘릴 수 있다는 것입니다. 계속해서 사람들이 어떻게 이러한 놀라운 성과 향상을 이루었는지, 또는 달성하고 있는지 살펴보겠습니다.
메모 : 이 블로그 게시물에서는 다중 서버 최적화에 대해서는 다소 무시하겠습니다. 별도의 데이터베이스 서버와 콘텐츠 전송 네트워크(CDN)를 사용하면 애플리케이션 서버의 부하를 줄이고 성능을 크게 향상시킬 수 있습니다. 이러한 종류의 변경 사항은 여기에 설명된 애플리케이션 및 구현 개선 사항과 별개이며 병행됩니다.
일찍 PHP 7로 업그레이드하는 주된 이유는 간단합니다. 애플리케이션 속도 때문입니다(메모리 절약으로 상당히 향상됨). PHP 7은 이전 버전의 PHP보다 두 배나 빠르고 메모리 사용량이 훨씬 적다고 합니다. (두 가지 면에서 결과는 틀림없이 다를 것입니다.)
응답 시간은 웹 애플리케이션에 있어서 매우 중요합니다. 더 빠른 웹 앱은 메모리 사용량이 적고 페이지 스와핑과 그로 인한 성능 문제의 가능성을 줄이며 다음 세 가지를 달성합니다.
이 모든 것이 업그레이드를 위한 훌륭한 이유입니다. 이 모든 것을 종합해 보면 업그레이드의 필요성이 압도적으로 느껴집니다. 그리고 "최신 버전으로 업그레이드"는 그렇게 명확한 성능 이점이 없더라도 많은 문제를 해결하기 위한 첫 번째 권장 사항입니다. 그렇다면 왜 모두가 바로 업그레이드하지 않는 걸까요?
간단합니다. 사람들은 오래된 코드를 건드리는 것을 싫어합니다. 그럴 만한 이유가 있습니다. 기존 앱이 충분히 잘 작동하고, 개발자들이 기존 앱을 업그레이드하는 것보다 새로운 앱을 만드는 데서 더 나은 결과를 얻는다면, 기존 앱은 오랜 시간 동안 변경되지 않은 상태로 유지될 수 있습니다. (현재 웹 서버와 앱을 변경하지 않고 NGINX를 사용하여 앱 성능을 개선하는 방법에 대한 자세한 내용은 이 시리즈의 두 번째 블로그 게시물을 참조하세요.)
하지만 가능하다면 더 효율적인 방법은 PHP 7로 업그레이드하여 더 높은 성능을 추구하는 것입니다. 하지만, 특히 테스트를 빼먹지 않고 끝낼 만큼 충분한 시간이 있을 때까지 시작하지 마세요.
PHP 7로 업그레이드하는 데 필요한 사항을 살펴보겠습니다.
switch
와 if-then-else
에 대한 논쟁은 제쳐두겠습니다.) Engine Yard의 블로그 에는 이러한 문제 대부분에 대한 좋은 예가 나와 있습니다.
PHP 7로 업그레이드하기로 결정했다면 코드 또는 적어도 중요 기능에 대한 전체 성능 검토와 수정을 수행하여 PHP 7의 새로운 기능을 활용하는 것을 고려하세요. 귀하와 귀하의 팀이 기술을 향상할 수 있는 더 나은 방법은 없으며, 오늘 귀하가 만들고 검토하고 테스트하는 변경 사항은 향후 수년 동안 귀하에게 도움이 될 가능성이 높습니다. 또한 이 블로그 게시물의 다른 성능 제안도 최대한 활용할 수 있습니다. 최적화된 코드는 최적화된 환경에서 실행하면 큰 이점을 얻을 수 있기 때문입니다.
따라서 사이트에서 애플리케이션 코드를 건드리지 않고 더 나은 성능을 얻기 위해 NGINX를 배포하는 경우가 많지만, 우리는 당신이 그 어려움을 극복하고 계속 나아갈 것을 권장합니다. 이사를 도와줄 사람들은 많이 있지만, 그냥 소매를 걷어붙이고 직접 이사 할 수도 있습니다. 공식 PHP 사이트에는 PHP 7 마이그레이션 가이드가 있고, O'Reilly에는 PHP 7 업그레이드 방법 책이 있습니다 .
NGINX는 10,000개의 가장 바쁜 웹사이트 중 절반을 포함하여 1억 4천만 개 이상의 웹사이트를 운영하는 소프트웨어입니다. (이러한 측정은 단일 서버 사이트에서는 웹 서버를 감지하고 다중 서버 사이트에서는 역방향 프록시 서버를 감지합니다.) 웹 서버로서 두 제품 모두 즉각적인 성능 향상을 제공합니다. 어떤 경우에는 다른 소프트웨어를 실행하는 서버가 과부하되어 최대 10배까지 속도가 느려지는 경우도 있습니다. 둘 다 역방향 프록시 서버로, 여러 개의 전용 서버를 사용하여 배포를 필요한 만큼 광범위하게 확장할 수 있습니다.
PHP와 Apache는 모두 열려 있는 모든 요청에 리소스를 할당합니다. 둘 중 하나 또는 둘 다 여러 개의 라이브러리를 로드해야 하는 경우 요청당 시작 시간과 메모리 사용량이 상당할 수 있습니다. 웹 서버 소프트웨어로 NGINX로 전환하면 서버 수준에서 이런 문제가 해결됩니다. NGINX의 기능을 사용하여 웹 서버(정적 파일 제공 등) 또는 역방향 프록시 서버(모든 종류의 캐싱, 프로토콜 종료, 부하 분산 등)에 작업을 오프로드하면 PHP가 수행해야 하는 작업이 최소화되어 애플리케이션 처리가 간소화되고 속도가 향상됩니다.
사이트에 사용자 정의 또는 독점적인 Apache 모듈이 있는 경우, 모듈을 교체하기 전까지는 Apache를 NGINX로 교체하지 못할 수도 있습니다. NGINX를 확인하여 쉬운 해결 방법이 있는지 확인하세요. 없다면 변경하는 데 필요한 시간과 노력을 고려하세요.
NGINX를 사용하기로 결정하면 NGINX Open Source와 NGINX Plus 중에서 선택할 수 있습니다. NGINX Plus의 가장 두드러진 기능 중 일부는 NGINX 오픈 소스보다 다음과 같습니다.
역방향 프록시 서버로서 NGINX Plus는 다음과 같은 추가적인 장점을 가지고 있습니다.
NGINX 오픈 소스와 NGINX Plus는 모두 콘텐츠 캐싱과 마이크로 캐싱( 애플리케이션 캐싱 이라고도 함)을 지원합니다. 캐싱은 애플리케이션 서버의 부하를 덜어주기 때문에 웹 서버 컨텍스트에서 유용하지만 두 기능 모두 여전히 단일 머신이나 가상 머신 인스턴스를 공유합니다. 역방향 프록시 서버에서 캐싱은 애플리케이션 서버 장치의 작업 부하를 상당히 줄여서 성능 면에서 더 큰 이점을 제공할 수 있습니다.
nginx.org 에서 NGINX 오픈 소스 소프트웨어를 직접 다운로드할 수 있으며, 커뮤니티 지원 도 받을 수 있습니다. 단일 NGINX Plus 구독을 시작하려면 무료 30일 체험판 에 등록하거나 온라인으로 구매하세요 . 다중 인스턴스 번들에 대한 내용은 NGINX 영업팀 에 문의하세요.
웹 서버 소프트웨어로 Apache에서 NGINX로 전환할 경우 변경해야 할 몇 가지 사항이 있습니다. 자세한 내용은 sitepoint.com 의 훌륭한 기사 에서 확인할 수 있습니다.
mod_rewrite
지시문)에 저장됩니다. 이를 NGINX 구성 파일의 관련 구성 사양으로 바꾸세요. 몇 가지 예를 보려면 블로그를 참조하세요.이러한 변경을 통해 NGINX에 익숙해지고 이 블로그 게시물의 2부에서 설명하는 대로 보다 복잡한 사이트를 최적화할 수 있는 역량을 갖추게 됩니다. 하지만 이러한 구성 변경으로 인해 사이트 운영에 허용할 수 없는 양의 작업이나 위험 수준이 초래되는 경우 걱정하지 마십시오. Apache에서 핵심 웹 서버 소프트웨어를 업그레이드하지 않고도 2부에 설명된 다중 서버 아키텍처를 구현할 수 있으며, 따라서 웹 서버 구성 파일을 변경하지 않아도 됩니다.
정적 파일은 적어도 웹 서버 관점에서는 자주 변경되지 않는 파일입니다. 정적 파일에는 일반적으로 JPEG, PNG와 같은 그래픽 파일과 CSS, JavaScript 파일과 같은 코드 파일이 포함됩니다. 이러한 파일을 애플리케이션 서버나 별도의 데이터베이스 서버에 저장하면 해당 파일에 대한 요청은 요청을 만들고 이행하는 데 필요한 모든 오버헤드와 함께 애플리케이션 코드에서 처리되어야 합니다. 이는 애플리케이션 서버를 더 중요한 작업에서 "방해"하고 실제 메모리가 과부하되고 새로운 요청으로 인해 현재 요청이 디스크로 페이지 아웃되는 지점에 더 가까워질 수 있습니다.
정적 파일 캐싱은 NGINX의 핵심 기능입니다. 웹 서버나 역방향 프록시 서버에서 구현할 수 있습니다.
NGINX에서 정적 파일 캐싱을 구현하는 데는 세 가지 단계가 있습니다.
역방향 프록시 서버가 없는 NGINX 웹 서버에서는 일반적인 의미에서 캐시를 수행하지 않습니다. X-Accel-Redirect
헤더를 사용하면 정적 파일에 대한 문의를 웹 서버로 간단히 리디렉션할 수 있습니다. 애플리케이션 서버는 요청을 전혀 보지 못하고 모든 리소스를 애플리케이션 요청에 사용할 수 있습니다. 역방향 프록시 서버를 사용하면 정적 파일 캐싱을 사용할 수 있으며, 애플리케이션을 실행하는 실제 서버나 가상 서버 인스턴스는 정적 파일 요청에 응답하는 데 아무런 역할을 하지 않습니다.
응답 속도를 최적화하는 예로, 다음 구성 스니펫은 NGINX가 운영 체제의 sendfile
시스템 호출을 사용할 수 있도록 합니다. 이 호출은 파일을 중간 버퍼에 복사하지 않음으로써 파일 전송 단계를 절약합니다.
위치 /mp3 { sendfile 켜기;
sendfile_max_chunk 1m;
# ...
}
정적 파일 캐싱을 위해 NGINX를 구성하는 방법에 대한 자세한 내용은 NGINX Plus 관리자 가이드를 참조하세요.
혼란스럽게도 마이크로캐싱은 여러 가지 이름으로 불립니다. 애플리케이션 캐싱 이나 일반 캐싱 도 이에 포함됩니다. NGINX에서는 이러한 파일의 유효 시간이 짧다는 점을 강조하기 위해 마이크로 캐싱이라는 용어를 사용합니다.
사용자 댓글을 위한 메커니즘을 제공하는 블로그 게시물 페이지가 있다고 가정해 보겠습니다. 새로운 방문자가 페이지에 도착할 때마다, 또는 기존 사용자가 페이지를 새로 고쳐 자신이나 다른 사람의 새 댓글을 볼 때마다 최신 및 가장 유용한 댓글을 포함해야 합니다. 이 경우에는 누군가가 페이지를 방문할 때마다 새 페이지를 생성하는 것이 좋은 생각인 듯합니다.
하지만 "매번"이라는 표현이 부담스러울 수도 있습니다. 페이지가 초당 1회 방문된다면, 방문할 때마다 페이지를 새로 생성하는 게 합리적입니다. 하지만 해당 페이지가 초당 10회, 100회, 1,000회 방문을 받고 사이트의 다른 모든 페이지도 방문한다면 애플리케이션 서버에 과부하가 걸릴 수 있습니다. 사람들에게 최신 콘텐츠를 제공한다는 목표를 달성한다는 것은 누구도 콘텐츠를 신속하게 얻을 수 없다는 것을 의미합니다.
마이크로캐싱은 캐시된 버전을 짧은 시간(예: 1~몇 초) 동안 유효한 것으로 표시하여 페이지를 생성하는 것을 의미합니다. 캐시된 버전이 만료되면 다음 요청은 새 페이지를 생성하고, 바로 그 뒤의 요청은 캐시된 버전을 가져옵니다. 이는 정적 파일의 경우와 동일한 동작이지만, 시간 단위가 훨씬 더 짧습니다.
이 이미지는 마이크로캐싱할 수 있는 콘텐츠를 사이트에서 찾을 수 있는 위치를 나타냅니다. 이 글은 우리의 오웬 개럿이 쓴 마이크로캐싱 블로그 게시물 에서 발췌한 것입니다.
마이크로캐싱은 사용자에게 거의 또는 전혀 해를 끼치지 않으면서 가장 필요할 때 애플리케이션 서버에서 작업을 제거하기 때문에 훌륭합니다. 일부 시스템에 내장되어 있다는 게 너무 멋진 일이죠. Drupal은 강력하고 내장된 마이크로캐싱 기능을 매우 중요하게 생각하기 때문에 Drupal 세계에서는 마이크로캐싱을 간단히 "캐싱"이라고 부릅니다.
하지만 Drupal 솔루션은 약간 부족하며, 비슷한 솔루션도 마찬가지입니다. 애플리케이션 서버의 작업은 줄었지만 Drupal(또는 보다 일반적으로 PHP)이 구성, 구현 및 파일 제공을 관리해야 합니다. 마이크로캐싱에 NGINX를 사용함으로써 애플리케이션 서버는 마이크로캐시에서 지정한 빈도로 새 페이지를 생성하는 것 외에는 모든 작업에서 완전히 오프로드됩니다. 다른 요청을 볼 수도 없고, 캐시 히트를 위해 아무것도 저장하거나 검색할 필요도 없습니다.
NGINX Plus나 다른 도구를 사용하면 사이트를 모니터링하고 어떤 페이지가 마이크로 캐싱으로 이익을 얻을 수 있는지 확인할 수 있습니다. 다음 구성 스니펫은 응답에 대한 1초 캐싱 기간을 구현합니다. 200
정상
상태 코드.
proxy_cache_path /tmp/cache 키_존=캐시:10m 레벨=1:2 비활성=600s 최대_크기=100m;서버 {
proxy_cache 캐시;
proxy_cache_valid 200 1s;
# ...
}
PHP 블로그 게시물의 첫 번째 부분은 단일 서버 솔루션과 캐싱에 초점을 맞춥니다. 캐싱은 단일 서버 구현에서 효과적이지만 역방향 프록시 서버가 포함된 경우 더욱 효과적입니다. 2부에서는 PHP 애플리케이션을 중심으로 한 다중 서버 구현인 역방향 프록시 서버의 이점에 대해 설명합니다.
NGINX Plus를 사용해보려면 오늘 무료 30일 체험판을 시작하거나 저희에게 연락해 사용 사례에 대해 논의해 보세요.
"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."