PHP 세계에는 다양한 PHP 프레임워크가 있으며, 가장 인기 있는 프레임워크는 Laravel, Phalcon, Symfony 2입니다.
PHP는 WordPress 및 Drupal과 같은 인기 콘텐츠 관리 시스템(CMS)의 기반이 되기도 합니다.
(가장 최근의 Drupal 릴리스인 Drupal 8에는 중요한 심포니 2 통합이 포함되어 있습니다.
이제 PHP 팀은 PHP 5를 도입한 지 10년 만에 새 버전인 PHP 7을 출시합니다.
먼저 웹 서버 소프트웨어와 PHP가 요청을 수신, 해독, 처리하기 위한 프로세스를 가동해야 합니다.
예를 들어 Apache HTTP 서버는 각 데이터 요청을 처리하기 위해 리소스를 할당하는데,
그 요청이 단순(JPEG 파일 검색)하거나 복잡(중첩된 CSS 요청 처리)하든 상관없습니다.
이 모든 작업에는 시간, 시스템 리소스 및 메모리 할당이 필요하며,
요청 처리를 시작하기 전에 OS, PHP 또는 둘 다에서 여러 라이브러리를 로드해야 하는 경우 상당히 큰 용량이 될 수 있습니다.
요청에 응답. PHP는 결과를 웹 서버 소프트웨어에 반환하여 요청자에게 HTTP 응답으로 다시 전송해야 합니다.
웹 서버 소프트웨어와 PHP 모두 최초 수신부터 최종 승인까지 각 요청에 대해 활성 전용 스레드를 실행하고 있다는 점을 기억하세요.
이는 물리적 서버, 가상 머신 또는 클라우드 서버 인스턴스가 모든 요청을 처리하기에는 많은 양입니다.
서버 머신의 물리적 메모리(물리적 또는 가상)가 모두 소진되면 성능이 저하되는 경향이 있습니다.
그러면 서버는 새로운 요청이 들어올 때 현재 세션을 디스크에 페이징하기 시작합니다.
파일 요청이 완료될 때까지 기다리는 대기 상태도 페이징에 영향을 미칩니다.
(매우 제한적인) 시점이 지나면 페이징 작업과 데이터 요청이 처리 작업을 압도하게 되고,
성능은 죽음의 소용돌이에 빠지게 되어 불만을 품은 사용자가 오래 기다리거나 세션이 완전히 종료될 수 있습니다.
성능 문제 해결
PHP의 성능 장벽을 극복하는 것은 분명 가능하며 몇 가지 보완적인 단계를 거쳐야 합니다.
각 단계는 다른 단계와 결합할 수 있습니다. 대략적으로 다음과 같습니다:
- 문제에 하드웨어 투입. 더 많은 메모리, 더 빠른 디스크, 별도의 데이터베이스 서버, 콘텐츠 전송 네트워크, 처리량 증가 및 기타 기계적 솔루션은 성능 문제에 대한 빠르고 손쉬운 해결책입니다. 이러한 솔루션은 가동 시간을 보존하거나 성능을 선형적으로 확장할 수 있습니다.
- PHP 및 애플리케이션 코드 개선. 새로운 버전의 PHP, 새로운 프레임워크, 개선된 애플리케이션 코드가 많은 도움이 될 수 있습니다.
- 다시 말하지만, 새로운 하드웨어에 대한 추가 비용 없이도 성능을 두 배 또는 네 배까지 높일 수 있습니다.
- 개선된 서버 소프트웨어. 대부분의 웹 서버와 PHP는 진행 중인 각 요청에 전용 리소스를 할당합니다.
- NGINX 서버 소프트웨어는 리소스를 묶어두지 않고 요청이 들어오는 대로 처리하여 서버 공간을 최소화합니다.
- 멀티 서버 구현. 역방향 프록시 서버를 구현하여 인터넷 요청을 처리하고 하나 이상의 애플리케이션 서버 간에 공유(로드 밸런스)할 수 있습니다. 역방향 프록시 서버는 파일 캐싱, SSL/TLS 및 HTTP/2와 같은 프로토콜 종료, 여러 애플리케이션 서버의 관리도 처리할 수 있습니다. 애플리케이션 서버가 하나만 있어도 워크로드의 상당 부분을 오프로드할 수 있습니다.
- 부하 분산은 서버가 추가될 때 서버가 자신의 몫 이상의 부하로 인해 수렁에 빠지지 않도록 보장합니다.
이러한 단계를 특별한 순서로 구현할 필요는 없습니다.
예를 들어 웹 서버로 Apache를 사용하고 앱 서버를 PHP 7로 업그레이드하지 않더라도
기존 서버 '앞'에 리버스 프록시로 NGINX를 구현하는 것만으로도 성능이 향상되고
여러 애플리케이션 서버를 병렬로 구현할 수 있습니다.
어떤 방식으로 구현하든 명심해야 할 중요한 사실은 현재 애플리케이션 코드를 거의 또는 전혀 변경하지 않고도
여러 가지 성능 향상 요소를 얻을 수 있으며 심지어 용량을 몇 배로 늘릴 수도 있다는 것입니다.
이미 이러한 놀라운 성능 향상을 달성했거나 달성 중에 있는 사람들의 사례를 살펴보세요.
주: 이 블로그 게시물에서는 다소 간과할 수 있는 멀티서버 최적화가 있습니다.
별도의 데이터베이스 서버와 CDN(콘텐츠 전송 네트워크)을 사용하면
애플리케이션 서버의 부하를 줄이고 성능을 크게 향상시킬 수 있으며,
이러한 종류의 변경 사항은 여기에 설명된 애플리케이션 및 구현 개선 사항과는 별개이며 병행할 수 있습니다.
팁 1 - PHP로 업그레이드하기
조만간 PHP 7로 업그레이드해야 하는 주된 이유는 간단합니다: 애플리케이션 속도(메모리 절약으로 크게 향상됨).
PHP 7은 이전 버전의 PHP보다 2배 더 빠르며 메모리를 훨씬 적게 사용한다고 합니다.
(이 두 가지 측면에서 사용자마다 차이가 있을 수 있습니다.)
웹 애플리케이션에서 응답 시간은 간단히 말해 매우 중요합니다.
더 빠른 웹 앱은 메모리를 덜 사용하므로 페이지 스왑과 그로 인한 성능 문제를 줄일 수 있고, 세 가지를 달성할 수 있습니다:
- 사용자가 더 행복하게 사이트를 방문하고 기사 읽기, 제품 정보 얻기, 택시 호출, 남는 방 빌리기, 물건 구매 등의 작업을 완료할 가능성이 높아집니다. 즉, 애초에 사이트나 앱을 만든 이유입니다.
- 특정 서버가 추가 사용자로 인해 속도가 느려지거나 중단될 위험 없이 더 많은 사용자를 지원할 수 있습니다. 파멸을 미루는 것은 언제나 좋은 일입니다.
- 서버에 과부하를 일으켜 운영 중단을 유도하는 해커의 공격에 덜 취약해집니다. 오늘날에는 누구나 공격을 받지만 취약할수록 더 많이, 더 공격적으로 공격을 받습니다. 따라서 취약성이 훨씬 더 적은 것이 더 좋을 수 있습니다.
이 모든 이유를 종합하면 업그레이드해야 하는 이유는 거의 압도적으로 많습니다.
그리고 성능에 뚜렷한 이점이 없는 경우에도 많은 문제를 해결하기 위해 항상 "최신 버전으로 업그레이드"를 가장 먼저 권장합니다.
그렇다면 왜 모두가 즉시 업그레이드하지 않을까요?
xkcd에 따른 업데이트사람들은 오래된 코드를 건드리는 것을 싫어하며, 그럴 만한 이유가 있습니다.
기존 앱이 충분히 잘 작동하고 있고 개발자가 기존 앱을 업그레이드하는 것보다
새 앱을 만드는 것이 더 나은 결과를 얻는다면 기존 앱은 변경하지 않고 오랫동안 사용할 수 있습니다.
(현재 웹 서버와 앱을 변경하지 않고 NGINX를 사용하여
앱의 성능을 개선하는 방법에 대한 자세한 내용은 이 시리즈의 두 번째 블로그 게시물을 참조하세요.)
하지만 가능하면 PHP 7로 업그레이드하여 성능 향상을 위한 탐구를 시작하는 것이 더 효율적입니다.
하지만 충분한 시간이 확보되기 전에는 시작하지 마시고, 특히 테스트에 소홀함이 없어야 합니다.
PHP 7로 업그레이드하는 데 필요한 사항을 살펴보겠습니다:
- 식 평가로 변경. PHP 7에서 올바르게 평가되도록 일부 표현식을 작성하는 방식을 변경해야 할 수도 있습니다. (또는 모든 PHP 서버를 한꺼번에 업그레이드하지 않는 경우 PHP 5.6과 PHP 7 모두에서 올바르게 평가되도록 해야 합니다.) 가변 변수 또는 가변 속성이 있는 경우 두 PHP 버전에서 동일한 방식으로 평가되도록 코드를 수정해야 합니다.
- 구문 변경. PHP 7은 ASP 또는 스크립트 태그를 지원하지 않습니다. 스위치에 대해 여러 개의 기본 케이스를 가질 수 없습니다. (스위치와 if-then-else에 대한 논란은 차치합니다.)
- 더 이상 사용되지 않는 기능 제거. <다양한 5.x 버전의 PHP에서 더 이상 사용되지 않는 모든 종류의 것은 이제 죽은 앵무새보다 더 죽었습니다. 이들은 단순히 PHP 7에서 작동하지 않습니다. 이러한 코드가 코드에 포함되어 있고 모두 제거하려고 시도했지만 실패하면 사이버 월요일 전날 밤 11시 59분에 쇼핑 카트 코드 기능이 사라지게 됩니다.
- 새로운 기능. PHP 7은 여러 가지 새로운 기능을 추가하여 이전 코드를 업그레이드하려는 사람들을 유혹하지만, 코드 정리 시 새로운 기능을 추가할 때는 주의해야 합니다. 새로운 기능은 종종 훌륭하거나 추가되지 않았을 수도 있지만, PHP가 더 업그레이드됨에 따라 버그(여러분과 다른 사람들의 버그)와 향후 개정판의 자석이 되기도 합니다.
- 일반 코드 검토. 코드를 건드릴 때마다, 즉 코드 파일을 열었을 때 변경했는지 여부가 확실하지 않을 때마다, 특히 변경한 내용이 무엇이든 그 안에 있는 모든 내용을 검토해야 합니다.
- 테스트. 모든 것은 항상 테스트해야 합니다. 변경 사항이 있으면 모든 것을 다시 테스트해야 하며, 그렇다고 해서 모든 버그를 잡을 수 있는 것은 아닙니다. 데브옵스 환경이 잘 구현되어 있으면 이러한 테스트가 비교적 쉬워질 수 있지만, 현재로서는 그 약속의 땅에 살고 있는 사람은 극소수에 불과합니다.
엔진 야드의 이 블로그에 이러한 문제 대부분에 대한 좋은 예가 나와 있습니다.
PHP 7로 업그레이드하기로 결정했다면 PHP 7의 새로운 기능을 활용하여
코드의 전체 성능 검토 및 수정, 또는 최소한 중요한 기능에 대한 수정을 고려하세요.
여러분과 여러분의 팀이 기술을 향상시키는 데 이보다 더 좋은 방법은 없으며,
오늘 변경하고 검토하고 테스트하는 것이 앞으로 수년 동안 도움이 될 것입니다.
또한 최적화된 코드는 최적화된 환경에서 실행될 때 큰 이점을 얻을 수 있으므로
이 블로그 게시물에서 제안하는 다른 성능 향상 방법도 최대한 활용할 수 있습니다.
따라서 사이트에서는 애플리케이션 코드를 건드리지 않고도 더 나은 성능을 얻기 위해 NGINX를 배포하는 경우가 많지만,
조금만 참고 앞으로 나아가는 것이 좋습니다.
전환을 위한 많은 도움이 제공되거나, 직접 소매를 걷어붙이고 스스로 할 수도 있습니다.
공식 PHP 사이트에서 PHP 7 마이그레이션 가이드와 O'Reilly에서 PHP 7 업그레이드 방법 예약이 있습니다.
팁 2 - NGINX 오픈 소스 또는 NGINX 플러스 선택하기
NGINX는 가장 바쁜 웹사이트 10,000개 중 절반을 포함하여 1억 4천만 개 이상의 웹사이트를 실행하는 소프트웨어입니다().
(이 측정값은 단일 서버 사이트에서는 웹 서버를, 멀티 서버 사이트에서는 역방향 프록시 서버를 감지합니다.)
웹 서버로서 두 가지 모두 즉각적인 성능 향상을 제공하며,
경우에 따라 다른 소프트웨어를 실행하는 서버에 과부하가 걸리면서 최대 10배까지 성능이 저하되는 경우도 있습니다.
역방향 프록시 서버로서 둘 다 여러 전용 서버를 사용하여 배포를 필요한 만큼 광범위하게 확장할 수 있습니다.
PHP와 Apache 모두 열려 있는 모든 요청에 리소스를 할당하므로,
둘 중 하나 또는 둘 다 다수의 라이브러리를 로드해야 하는 경우
요청당 시작 시간과 메모리 사용량이 상당히 늘어날 수 있습니다.
웹 서버 소프트웨어로 NGINX로 전환하면 서버 수준에서 이 문제가 해결됩니다.
NGINX의 기능을 사용하여 웹 서버(정적 파일 제공 등) 또는 역방향 프록시 서버(모든 종류의 캐싱, 프로토콜 종료, 부하 분산 등)로 작업을
오프로드하면 PHP가 해야 할 일을 최소화하여 애플리케이션 처리를 간소화하고 속도를 높일 수 있습니다.
사이트에 사용자 정의 또는 독점 Apache 모듈이 있는 경우 해당 모듈을 교체할 때까지
Apache를 NGINX로 대체하지 못할 수 있습니다.
NGINX에 문의하여 쉬운 해결 방법이 있는지 확인하고,
그렇지 않은 경우 변경에 필요한 시간과 노력을 파악하세요.
NGINX를 사용하기로 결정했다면 NGINX 오픈 소스와 NGINX 플러스 중에서 선택할 수 있습니다.
NGINX Open Source에 비해 NGINX Plus의 가장 눈에 띄는 기능은 다음과 같습니다:
- 사전 컴파일된 코드. NGINX Plus는 인기 있는 라이브러리와 즉시 추가 및 제거할 수 있는 동적 모듈을 포함하여 컴파일된 형태로 배포됩니다. (NGINX 오픈 소스는 컴파일된 코드와 컴파일되지 않은 코드로 모두 사용할 수 있습니다.) 서버를 다시 시작하지 않고도 다양한 구성 변경을 수행할 수 있습니다.
- 지원. NGINX Plus에는 지원 패키지가 포함되어 있어 NGINX 엔지니어에게 직접 액세스할 수 있습니다.
- 모니터링 및 관리. DevOps 친화적인 도구를 사용하면 서비스 수준 협약(SLA)을 충족하기 위해 서버를 계속 가동하고 실행할 수 있습니다.
역방향 프록시 서버인 NGINX Plus에는 추가적인 장점이 있습니다:
- 로드 밸런싱. 두 버전 모두 기본 HTTP 부하 분산 기능을 지원하지만, NGINX Plus는 더 정교한 알고리즘과 TCP 부하 분산을 추가합니다.
- 세션 지속성. 로드 밸런싱과 함께 NGINX ․Plus는 PHP 애플리케이션 서버와 관련이 높은 보다 정교한 세션 지속성을 제공합니다.
- 모니터링 및 관리. 멀티서버 배포에서는 < data-dl-uid="91">NGINX의 모든 기능이 작동하며, 더 복잡한 구현에서도 사전 컴파일된 코드와 지원의 가치가 극대화됩니다.
NGINX 오픈 소스와 NGINX Plus는 모두 콘텐츠 캐싱과 마이크로 캐싱(애플리케이션 캐싱이라고도 함)을 지원합니다.
캐싱은 애플리케이션 서버를 오프로드하므로 웹 서버 컨텍스트에서 유용하지만
두 기능 모두 여전히 단일 머신 또는 가상 머신 인스턴스를 공유합니다.
역방향 프록시 서버에서 캐싱은 애플리케이션 서버 장치에서 상당한 양의 작업을 오프로드하여
더 큰 성능 이점을 제공할 수 있습니다.
NGINX 오픈 소스 소프트웨어는 nginx.org에서 직접 다운로드할 수 있으며,
커뮤니티 지원도 찾을 수 있습니다.
단일 NGINX Plus 구독을 시작하려면 30일 무료 평가판 또는 온라인 구매에 등록하세요.
멀티 인스턴스 번들의 경우 NGINX 영업팀에 문의하세요.
팁 3 - Apache 구문을 NGINX 구문으로 변환하기
웹 서버 소프트웨어로 Apache에서 NGINX로 전환하는 경우 몇 가지 변경해야 할 사항이 있으며,
자세한 내용은 sitepoint.com의 훌륭한 기사에서 확인할 수 있습니다:
- 구성 파일 만들기 또는 변환. 구성 코드를 변경하여 NGINX(더 이상 Apache가 아님)가 구성에 사용할 파일을 지정합니다.
- 읽기/쓰기 권한 변경. 웹사이트의 루트 디렉터리에 있는 파일에 대해 CRUD 작업(만들기, 읽기, 업데이트, 삭제)을 수행할 수 있는 권한을 계정에 추가합니다.
- 유효한 검색 패턴 지정. 위치 블록을 추가하여 NGINX가 요청을 처리하는 동안 시도할 수 있는 패턴과 시도할 수 없는 패턴을 지정합니다.
- .htaccess 구성 코드 교체. Apache에 대한 구성 세부 정보는 .htaccess 파일이나 정적 구성 파일(예: mod_rewrite 지시어)에 있는 경우가 많습니다. 이를 NGINX 구성 파일에서 관련 구성 사양으로 대체합니다. 몇 가지 예는 블로그를 참조하세요.
이 블로그 글의 2부에서 설명하는 대로 이러한 변경을 수행하면 NGINX에 익숙해지고
더 복잡한 사이트를 최적화할 수 있는 역량을 갖추게 됩니다.
그러나 이러한 구성 변경으로 인해 사이트 운영에 감당할 수 없는 작업량이나 위험도가 발생하더라도 걱정하지 마세요.
2부에서 설명한 멀티서버 아키텍처는 Apache의 핵심 웹 서버 소프트웨어를 업그레이드하지 않고도
웹 서버 구성 파일을 변경하지 않고도 구현할 수 있습니다.
팁 4 - 정적 파일 캐싱 구현하기
정적 파일은 적어도 웹 서버 측면에서 자주 변경되지 않는 파일을 말합니다.
정적 파일에는 일반적으로 JPEG, PNG와 같은 그래픽 파일과 CSS 및 JavaScript 파일과 같은 코드 파일이 포함됩니다.
이러한 파일을 애플리케이션 서버나 별도의 데이터베이스 서버에 저장하면 애플리케이션 코드에서 요청을 처리해야 하며,
요청을 만들고 처리하는 데 필요한 모든 오버헤드가 발생합니다.
이로 인해 애플리케이션 서버는 더 중요한 작업에 집중하지 못하고 물리적 메모리가 과부하되고
새로운 요청으로 인해 현재 요청이 디스크로 페이지 아웃되는 지점에 가까워질 수 있습니다.
정적 파일 캐싱은 NGINX의 핵심 기능입니다.
웹 서버 또는 역방향 프록시 서버에서 구현할 수 있습니다:
NGINX 역방향 프록시 서버는 웹 서버와 다른 컴퓨터 또는 인스턴스에서 실행되므로
정적 파일 캐싱은 애플리케이션 서버의 리소스를 소모하지 않습니다.
애플리케이션 서버는 애플리케이션 실행에만 집중할 수 있습니다.NGINX에서 정적 파일 캐싱을 구현하는 전체 단계는 세 가지입니다:
- 검색을 위한 루트 디렉터리 지정.
- 요청 처리.
- 응답 속도 최적화.
역방향 프록시 서버가 없는 NGINX 웹 서버에서는 일반적인 의미의 캐싱을 하지 않습니다.
X-Accel-Redirect 헤더를 사용하여 정적 파일에 대한 문의를 웹 서버로 리디렉션하기만 하면 됩니다.
애플리케이션 서버는 요청을 전혀 볼 수 없으며 모든 리소스를 애플리케이션 요청에 집중할 수 있습니다.
역방향 프록시 서버를 사용하면 정적 파일 캐싱을 사용하며 애플리케이션을 실행하는
물리적 서버 또는 가상 서버 인스턴스는 정적 파일 요청에 응답하는 데 아무런 역할도 하지 않습니다.
응답 속도 최적화의 예로, 다음 구성 스니펫은 NGINX가 운영 체제의 sendfile 시스템 호출을 사용하여
파일을 중간 버퍼에 복사하지 않음으로써 파일 전송 단계를 절약할 수 있게 해줍니다:
location /mp3 { sendfile on; sendfile_max_chunk 1m; # ... }정적 파일 캐싱을 위한 NGINX 구성에 대한 자세한 내용은 NGINX Plus 관리자 가이드를 참조하세요.
팁 5 - 마이크로캐싱 구현하기
마이크로캐싱은 혼란스럽게도 애플리케이션 캐싱과 그냥 캐싱 등 여러 가지 이름으로 불립니다.
여기서는 이러한 파일의 유효 기간이 짧다는 점을 강조하기 위해 마이크로캐싱이라는 용어를 사용합니다.
사용자 댓글을 위한 메커니즘을 제공하는 블로그 게시물 페이지가 있다고 가정해 보겠습니다.
새 방문자가 페이지를 방문할 때마다 또는 기존 사용자가 페이지를 새로고침하여
자신 또는 다른 사람의 새 댓글을 볼 때마다 최신 댓글을 포함시키고 싶을 수 있습니다.
이 경우 누군가 페이지를 방문할 때마다 페이지를 새로 생성하는 것이 좋은 생각처럼 보입니다.
하지만 '매번'은 부담이 될 수 있습니다.
페이지가 초당 한 번 방문되는 경우 방문 시마다 페이지를 새로 생성하는 것이 합리적입니다.
하지만 해당 페이지가 사이트의 다른 모든 페이지와 함께 초당 10회, 100회, 1000회 방문을 받는다면
애플리케이션 서버에 과부하가 걸릴 수 있습니다.
사람들에게 새로운 콘텐츠를 제공한다는 목표를 달성하려면 누구도 콘텐츠를 빠르게 얻을 수 없습니다.
마이크로캐싱은 캐시된 버전을 짧은 시간(예: 1초 또는 몇 초) 동안 유효한 것으로 표시하여 페이지를 생성하는 것을 의미합니다.
캐시된 버전이 만료되면 다음 요청은 새 페이지를 생성하라는 메시지를 표시하고
캐시된 버전을 가져온 직후에 요청합니다.
이는 정적 파일의 경우와 동일한 동작이지만 훨씬 더 짧은 주기로 이루어집니다.
마이크로캐싱은 가장 필요할 때만 애플리케이션 서버에서 작업을 제거하고
사용자에게 거의 또는 전혀 피해를 주지 않기 때문에 매우 유용합니다.
일부 시스템에는 마이크로캐싱이 내장되어 있을 정도로 대단한 기능입니다.
Drupal은 강력하고 내장된 마이크로캐싱 기능을 매우 중요하게 생각하며,
Drupal 세계에서는 마이크로캐싱을 간단히 "캐싱"이라고 부릅니다.
그러나 Drupal 솔루션은 약간 부족하며 유사한 솔루션도 마찬가지입니다.
애플리케이션 서버가 하는 일은 적지만 구성, 구현 및 파일 제공을 관리해야 하는 것은 여전히 Drupal(또는 더 일반적으로는 PHP)입니다.
마이크로캐싱에 NGINX를 사용하면 애플리케이션 서버는 마이크로캐시가 지정한 빈도에 따라
새 페이지를 생성하는 것 외에는 모든 작업에서 완전히 오프로드됩니다.
캐시 히트를 위해 아무것도 저장하거나 검색할 필요는 물론 다른 요청도 볼 수 없습니다.
NGINX 또는 기타 도구를 사용하여 사이트를 모니터링하고 마이크로캐싱의 이점을 누릴 수 있는 페이지를 확인할 수 있습니다.
다음 구성 스니펫은 상태 코드가 200인 응답에 대해 1초의 캐싱 기간을 구현합니다.
proxy_cache_path /tmp/cache keys_zone=cache:10m levels=1:2 inactive=600s max_size=100m;server { proxy_cache cache; proxy_cache_valid 200 1s; # ... }1부 마무리
PHP 블로그 글의 첫 번째 파트에서는 단일 서버 솔루션과 단일 서버 구현에 효과적인 캐싱에 초점을 맞추었지만
역방향 프록시 서버가 혼합되어 있는 경우에는 더욱 그렇습니다.
2부에서는 PHP 애플리케이션을 중심으로 역방향 프록시 서버, 멀티서버 구현의 이점에 대해 설명합니다.
지금 바로 30일 무료 체험판을 시작하거나 사용 사례를 논의하려면 저희에게 연락하세요를 통해 NGINX Plus를 체험해 보세요.
소개 - PHP에서 NGINX를 사용하는 방법
PHP는 서버 측 웹 애플리케이션을 만드는 데 가장 널리 사용되는 방법으로, 약 80%의 시장 점유율을 차지하고 있습니다.(ASP.net은 근소한 차이로 2위, Java는 그보다 훨씬 먼 3위입니다.)
PHP는 WordPress 및 Drupal과 같은 인기 콘텐츠 관리 시스템(CMS)의 기반이 되기도 합니다.
(가장 최근의 Drupal 릴리스인 Drupal 8에는 중요한 심포니 2 통합이 포함되어 있습니다.
이제 PHP 팀은 PHP 5를 도입한 지 10년 만에 새 버전인 PHP 7을 출시합니다.
이 기간 동안 웹 사용량과 웹사이트에 대한 수요는 모두 기하급수적으로 증가했습니다.
PHP는 이러한 빠른 성장에 기여했지만, PHP의 한계 또한 이러한 성장과 함께 부각되었습니다.
PHP는 일반적으로 강력하고 유연하다고 여겨지지만 성능 문제가 발생할 수 있습니다.
PHP 기반 사이트는 트래픽이 몇 배만 증가해도 쉽게 '벽에 부딪힐' 수 있습니다.
사이트가 비즈니스 또는 운영 목표를 달성하기 시작하면 트래픽이 증가할 때마다 사이트가 다운되기 시작합니다.
수천, 수만 개의 PHP 기반 애플리케이션의 경우 비교적 간단한 몇 가지 변경만으로도 성능을 개선할 수 있습니다.
여기에는 memcached와 같은 도구를 사용한 캐싱, 데이터베이스 튜닝,
역방향 프록시 및 NGINX Open Source 및 NGINX & amp;Plus를 사용한 로드 밸런싱이 포함됩니다.
NGINX는 앱 응답성을 크게 개선하여 사용자 및 트래픽 수의 대폭적인 증가를 지원합니다.
이 블로그 게시물은 PHP 7을 사용하는 웹사이트의 성능을 극대화하는 2부로 구성된 시리즈 중 첫 번째 글입니다.
여기서는 PHP 7로 업그레이드, 웹 서버 소프트웨어로
NGINX 오픈 소스 또는 NGINX 플러스 구현, URL 재작성(요청이 제대로 처리되는 데 필요),
정적 파일 캐싱, 동적 파일 캐싱(애플리케이션 캐싱 또는 마이크로캐싱이라고도 함) 등을 중점적으로 다룹니다.
다음 블로그 글에서는 역방향 프록시 서버 추가, 여러 애플리케이션 서버로 이동,
여러 서버 간의 부하 분산, 부하 분산 중 세션 지속성 지원,
SSL/TLS 및 관련 HTTP/2 프로토콜과 같은 보안 프로토콜 종료 등
추가 서버로 수행할 수 있는 단계에 대해 집중적으로 설명합니다.
PHP가 벽에 부딪히는 이유
PHP 애플리케이션이 벽에 부딪히는 이유는 무엇인가요?모든 애플리케이션 서버 소프트웨어가 벽에 부딪히는 것과 같은 이유입니다.
사용자 요청이 들어오면 PHP와 그 위에서 실행되는 웹 서버 소프트웨어는 여러 가지 작업을 수행해야 합니다:
예를 들어 Apache HTTP 서버는 각 데이터 요청을 처리하기 위해 리소스를 할당하는데,
그 요청이 단순(JPEG 파일 검색)하거나 복잡(중첩된 CSS 요청 처리)하든 상관없습니다.
이 모든 작업에는 시간, 시스템 리소스 및 메모리 할당이 필요하며,
요청 처리를 시작하기 전에 OS, PHP 또는 둘 다에서 여러 라이브러리를 로드해야 하는 경우 상당히 큰 용량이 될 수 있습니다.
웹 서버 소프트웨어가 요청을 디코딩해야 하므로 시간이 많이 소요될 수 있습니다.
요청에 따라 작업. PHP는 요청을 처리하기 위해 리소스를 한데 모아야 합니다.
이를 위해서는 여러 데이터베이스 호출, 인터넷을 통한 외부 서비스 호출, 복잡한 내부 처리가 필요할 수 있습니다.
웹 서버 소프트웨어와 PHP 모두 최초 수신부터 최종 승인까지 각 요청에 대해 활성 전용 스레드를 실행하고 있다는 점을 기억하세요.
이는 물리적 서버, 가상 머신 또는 클라우드 서버 인스턴스가 모든 요청을 처리하기에는 많은 양입니다.
서버 머신의 물리적 메모리(물리적 또는 가상)가 모두 소진되면 성능이 저하되는 경향이 있습니다.
그러면 서버는 새로운 요청이 들어올 때 현재 세션을 디스크에 페이징하기 시작합니다.
파일 요청이 완료될 때까지 기다리는 대기 상태도 페이징에 영향을 미칩니다.
(매우 제한적인) 시점이 지나면 페이징 작업과 데이터 요청이 처리 작업을 압도하게 되고,
성능은 죽음의 소용돌이에 빠지게 되어 불만을 품은 사용자가 오래 기다리거나 세션이 완전히 종료될 수 있습니다.
성능 문제 해결
PHP의 성능 장벽을 극복하는 것은 분명 가능하며 몇 가지 보완적인 단계를 거쳐야 합니다.
각 단계는 다른 단계와 결합할 수 있습니다. 대략적으로 다음과 같습니다:
이러한 단계를 특별한 순서로 구현할 필요는 없습니다.
예를 들어 웹 서버로 Apache를 사용하고 앱 서버를 PHP 7로 업그레이드하지 않더라도
기존 서버 '앞'에 리버스 프록시로 NGINX를 구현하는 것만으로도 성능이 향상되고
여러 애플리케이션 서버를 병렬로 구현할 수 있습니다.
어떤 방식으로 구현하든 명심해야 할 중요한 사실은 현재 애플리케이션 코드를 거의 또는 전혀 변경하지 않고도
여러 가지 성능 향상 요소를 얻을 수 있으며 심지어 용량을 몇 배로 늘릴 수도 있다는 것입니다.
이미 이러한 놀라운 성능 향상을 달성했거나 달성 중에 있는 사람들의 사례를 살펴보세요.
주: 이 블로그 게시물에서는 다소 간과할 수 있는 멀티서버 최적화가 있습니다.
별도의 데이터베이스 서버와 CDN(콘텐츠 전송 네트워크)을 사용하면
애플리케이션 서버의 부하를 줄이고 성능을 크게 향상시킬 수 있으며,
이러한 종류의 변경 사항은 여기에 설명된 애플리케이션 및 구현 개선 사항과는 별개이며 병행할 수 있습니다.
팁 1 - PHP로 업그레이드하기
조만간 PHP 7로 업그레이드해야 하는 주된 이유는 간단합니다: 애플리케이션 속도(메모리 절약으로 크게 향상됨).
PHP 7은 이전 버전의 PHP보다 2배 더 빠르며 메모리를 훨씬 적게 사용한다고 합니다.
(이 두 가지 측면에서 사용자마다 차이가 있을 수 있습니다.)
웹 애플리케이션에서 응답 시간은 간단히 말해 매우 중요합니다.
더 빠른 웹 앱은 메모리를 덜 사용하므로 페이지 스왑과 그로 인한 성능 문제를 줄일 수 있고, 세 가지를 달성할 수 있습니다:
이 모든 이유를 종합하면 업그레이드해야 하는 이유는 거의 압도적으로 많습니다.
그리고 성능에 뚜렷한 이점이 없는 경우에도 많은 문제를 해결하기 위해 항상 "최신 버전으로 업그레이드"를 가장 먼저 권장합니다.
그렇다면 왜 모두가 즉시 업그레이드하지 않을까요?
xkcd에 따른 업데이트사람들은 오래된 코드를 건드리는 것을 싫어하며, 그럴 만한 이유가 있습니다.
기존 앱이 충분히 잘 작동하고 있고 개발자가 기존 앱을 업그레이드하는 것보다
새 앱을 만드는 것이 더 나은 결과를 얻는다면 기존 앱은 변경하지 않고 오랫동안 사용할 수 있습니다.
(현재 웹 서버와 앱을 변경하지 않고 NGINX를 사용하여
앱의 성능을 개선하는 방법에 대한 자세한 내용은 이 시리즈의 두 번째 블로그 게시물을 참조하세요.)
하지만 가능하면 PHP 7로 업그레이드하여 성능 향상을 위한 탐구를 시작하는 것이 더 효율적입니다.
하지만 충분한 시간이 확보되기 전에는 시작하지 마시고, 특히 테스트에 소홀함이 없어야 합니다.
PHP 7로 업그레이드하는 데 필요한 사항을 살펴보겠습니다:
엔진 야드의 이 블로그에 이러한 문제 대부분에 대한 좋은 예가 나와 있습니다.
PHP 7로 업그레이드하기로 결정했다면 PHP 7의 새로운 기능을 활용하여
코드의 전체 성능 검토 및 수정, 또는 최소한 중요한 기능에 대한 수정을 고려하세요.
여러분과 여러분의 팀이 기술을 향상시키는 데 이보다 더 좋은 방법은 없으며,
오늘 변경하고 검토하고 테스트하는 것이 앞으로 수년 동안 도움이 될 것입니다.
또한 최적화된 코드는 최적화된 환경에서 실행될 때 큰 이점을 얻을 수 있으므로
이 블로그 게시물에서 제안하는 다른 성능 향상 방법도 최대한 활용할 수 있습니다.
따라서 사이트에서는 애플리케이션 코드를 건드리지 않고도 더 나은 성능을 얻기 위해 NGINX를 배포하는 경우가 많지만,
조금만 참고 앞으로 나아가는 것이 좋습니다.
전환을 위한 많은 도움이 제공되거나, 직접 소매를 걷어붙이고 스스로 할 수도 있습니다.
공식 PHP 사이트에서 PHP 7 마이그레이션 가이드와 O'Reilly에서 PHP 7 업그레이드 방법 예약이 있습니다.
팁 2 - NGINX 오픈 소스 또는 NGINX 플러스 선택하기
NGINX는 가장 바쁜 웹사이트 10,000개 중 절반을 포함하여 1억 4천만 개 이상의 웹사이트를 실행하는 소프트웨어입니다().
(이 측정값은 단일 서버 사이트에서는 웹 서버를, 멀티 서버 사이트에서는 역방향 프록시 서버를 감지합니다.)
웹 서버로서 두 가지 모두 즉각적인 성능 향상을 제공하며,
경우에 따라 다른 소프트웨어를 실행하는 서버에 과부하가 걸리면서 최대 10배까지 성능이 저하되는 경우도 있습니다.
역방향 프록시 서버로서 둘 다 여러 전용 서버를 사용하여 배포를 필요한 만큼 광범위하게 확장할 수 있습니다.
PHP와 Apache 모두 열려 있는 모든 요청에 리소스를 할당하므로,
둘 중 하나 또는 둘 다 다수의 라이브러리를 로드해야 하는 경우
요청당 시작 시간과 메모리 사용량이 상당히 늘어날 수 있습니다.
웹 서버 소프트웨어로 NGINX로 전환하면 서버 수준에서 이 문제가 해결됩니다.
NGINX의 기능을 사용하여 웹 서버(정적 파일 제공 등) 또는 역방향 프록시 서버(모든 종류의 캐싱, 프로토콜 종료, 부하 분산 등)로 작업을
오프로드하면 PHP가 해야 할 일을 최소화하여 애플리케이션 처리를 간소화하고 속도를 높일 수 있습니다.
사이트에 사용자 정의 또는 독점 Apache 모듈이 있는 경우 해당 모듈을 교체할 때까지
Apache를 NGINX로 대체하지 못할 수 있습니다.
NGINX에 문의하여 쉬운 해결 방법이 있는지 확인하고,
그렇지 않은 경우 변경에 필요한 시간과 노력을 파악하세요.
NGINX를 사용하기로 결정했다면 NGINX 오픈 소스와 NGINX 플러스 중에서 선택할 수 있습니다.
NGINX Open Source에 비해 NGINX Plus의 가장 눈에 띄는 기능은 다음과 같습니다:
역방향 프록시 서버인 NGINX Plus에는 추가적인 장점이 있습니다:
NGINX 오픈 소스와 NGINX Plus는 모두 콘텐츠 캐싱과 마이크로 캐싱(애플리케이션 캐싱이라고도 함)을 지원합니다.
캐싱은 애플리케이션 서버를 오프로드하므로 웹 서버 컨텍스트에서 유용하지만
두 기능 모두 여전히 단일 머신 또는 가상 머신 인스턴스를 공유합니다.
역방향 프록시 서버에서 캐싱은 애플리케이션 서버 장치에서 상당한 양의 작업을 오프로드하여
더 큰 성능 이점을 제공할 수 있습니다.
NGINX 오픈 소스 소프트웨어는 nginx.org에서 직접 다운로드할 수 있으며,
커뮤니티 지원도 찾을 수 있습니다.
단일 NGINX Plus 구독을 시작하려면 30일 무료 평가판 또는 온라인 구매에 등록하세요.
멀티 인스턴스 번들의 경우 NGINX 영업팀에 문의하세요.
팁 3 - Apache 구문을 NGINX 구문으로 변환하기
웹 서버 소프트웨어로 Apache에서 NGINX로 전환하는 경우 몇 가지 변경해야 할 사항이 있으며,
자세한 내용은 sitepoint.com의 훌륭한 기사에서 확인할 수 있습니다:
이 블로그 글의 2부에서 설명하는 대로 이러한 변경을 수행하면 NGINX에 익숙해지고
더 복잡한 사이트를 최적화할 수 있는 역량을 갖추게 됩니다.
그러나 이러한 구성 변경으로 인해 사이트 운영에 감당할 수 없는 작업량이나 위험도가 발생하더라도 걱정하지 마세요.
2부에서 설명한 멀티서버 아키텍처는 Apache의 핵심 웹 서버 소프트웨어를 업그레이드하지 않고도
웹 서버 구성 파일을 변경하지 않고도 구현할 수 있습니다.
팁 4 - 정적 파일 캐싱 구현하기
정적 파일은 적어도 웹 서버 측면에서 자주 변경되지 않는 파일을 말합니다.
정적 파일에는 일반적으로 JPEG, PNG와 같은 그래픽 파일과 CSS 및 JavaScript 파일과 같은 코드 파일이 포함됩니다.
이러한 파일을 애플리케이션 서버나 별도의 데이터베이스 서버에 저장하면 애플리케이션 코드에서 요청을 처리해야 하며,
요청을 만들고 처리하는 데 필요한 모든 오버헤드가 발생합니다.
이로 인해 애플리케이션 서버는 더 중요한 작업에 집중하지 못하고 물리적 메모리가 과부하되고
새로운 요청으로 인해 현재 요청이 디스크로 페이지 아웃되는 지점에 가까워질 수 있습니다.
정적 파일 캐싱은 NGINX의 핵심 기능입니다.
웹 서버 또는 역방향 프록시 서버에서 구현할 수 있습니다:
NGINX 역방향 프록시 서버는 웹 서버와 다른 컴퓨터 또는 인스턴스에서 실행되므로
정적 파일 캐싱은 애플리케이션 서버의 리소스를 소모하지 않습니다.
애플리케이션 서버는 애플리케이션 실행에만 집중할 수 있습니다.
NGINX에서 정적 파일 캐싱을 구현하는 전체 단계는 세 가지입니다:
역방향 프록시 서버가 없는 NGINX 웹 서버에서는 일반적인 의미의 캐싱을 하지 않습니다.
X-Accel-Redirect 헤더를 사용하여 정적 파일에 대한 문의를 웹 서버로 리디렉션하기만 하면 됩니다.
애플리케이션 서버는 요청을 전혀 볼 수 없으며 모든 리소스를 애플리케이션 요청에 집중할 수 있습니다.
역방향 프록시 서버를 사용하면 정적 파일 캐싱을 사용하며 애플리케이션을 실행하는
물리적 서버 또는 가상 서버 인스턴스는 정적 파일 요청에 응답하는 데 아무런 역할도 하지 않습니다.
응답 속도 최적화의 예로, 다음 구성 스니펫은 NGINX가 운영 체제의 sendfile 시스템 호출을 사용하여
파일을 중간 버퍼에 복사하지 않음으로써 파일 전송 단계를 절약할 수 있게 해줍니다:
location /mp3 { sendfile on; sendfile_max_chunk 1m; # ... }정적 파일 캐싱을 위한 NGINX 구성에 대한 자세한 내용은 NGINX Plus 관리자 가이드를 참조하세요.
팁 5 - 마이크로캐싱 구현하기
마이크로캐싱은 혼란스럽게도 애플리케이션 캐싱과 그냥 캐싱 등 여러 가지 이름으로 불립니다.
여기서는 이러한 파일의 유효 기간이 짧다는 점을 강조하기 위해 마이크로캐싱이라는 용어를 사용합니다.
사용자 댓글을 위한 메커니즘을 제공하는 블로그 게시물 페이지가 있다고 가정해 보겠습니다.
새 방문자가 페이지를 방문할 때마다 또는 기존 사용자가 페이지를 새로고침하여
자신 또는 다른 사람의 새 댓글을 볼 때마다 최신 댓글을 포함시키고 싶을 수 있습니다.
이 경우 누군가 페이지를 방문할 때마다 페이지를 새로 생성하는 것이 좋은 생각처럼 보입니다.
하지만 '매번'은 부담이 될 수 있습니다.
페이지가 초당 한 번 방문되는 경우 방문 시마다 페이지를 새로 생성하는 것이 합리적입니다.
하지만 해당 페이지가 사이트의 다른 모든 페이지와 함께 초당 10회, 100회, 1000회 방문을 받는다면
애플리케이션 서버에 과부하가 걸릴 수 있습니다.
사람들에게 새로운 콘텐츠를 제공한다는 목표를 달성하려면 누구도 콘텐츠를 빠르게 얻을 수 없습니다.
마이크로캐싱은 캐시된 버전을 짧은 시간(예: 1초 또는 몇 초) 동안 유효한 것으로 표시하여 페이지를 생성하는 것을 의미합니다.
캐시된 버전이 만료되면 다음 요청은 새 페이지를 생성하라는 메시지를 표시하고
캐시된 버전을 가져온 직후에 요청합니다.
이는 정적 파일의 경우와 동일한 동작이지만 훨씬 더 짧은 주기로 이루어집니다.
마이크로캐싱은 가장 필요할 때만 애플리케이션 서버에서 작업을 제거하고
사용자에게 거의 또는 전혀 피해를 주지 않기 때문에 매우 유용합니다.
일부 시스템에는 마이크로캐싱이 내장되어 있을 정도로 대단한 기능입니다.
Drupal은 강력하고 내장된 마이크로캐싱 기능을 매우 중요하게 생각하며,
Drupal 세계에서는 마이크로캐싱을 간단히 "캐싱"이라고 부릅니다.
그러나 Drupal 솔루션은 약간 부족하며 유사한 솔루션도 마찬가지입니다.
애플리케이션 서버가 하는 일은 적지만 구성, 구현 및 파일 제공을 관리해야 하는 것은 여전히 Drupal(또는 더 일반적으로는 PHP)입니다.
마이크로캐싱에 NGINX를 사용하면 애플리케이션 서버는 마이크로캐시가 지정한 빈도에 따라
새 페이지를 생성하는 것 외에는 모든 작업에서 완전히 오프로드됩니다.
캐시 히트를 위해 아무것도 저장하거나 검색할 필요는 물론 다른 요청도 볼 수 없습니다.
NGINX 또는 기타 도구를 사용하여 사이트를 모니터링하고 마이크로캐싱의 이점을 누릴 수 있는 페이지를 확인할 수 있습니다.
다음 구성 스니펫은 상태 코드가 200인 응답에 대해 1초의 캐싱 기간을 구현합니다.
proxy_cache_path /tmp/cache keys_zone=cache:10m levels=1:2 inactive=600s max_size=100m;server { proxy_cache cache; proxy_cache_valid 200 1s; # ... }1부 마무리
PHP 블로그 글의 첫 번째 파트에서는 단일 서버 솔루션과 단일 서버 구현에 효과적인 캐싱에 초점을 맞추었지만
역방향 프록시 서버가 혼합되어 있는 경우에는 더욱 그렇습니다.
2부에서는 PHP 애플리케이션을 중심으로 역방향 프록시 서버, 멀티서버 구현의 이점에 대해 설명합니다.
지금 바로 30일 무료 체험판을 시작하거나 사용 사례를 논의하려면 저희에게 연락하세요를 통해 NGINX Plus를 체험해 보세요.
위 내용과 같이 NGINX Plus를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기