Python 웹 배포 방법
PHP를 공부한 사람이라면 PHP의 공식 환경 배포가 매우 간단하다는 것을 알고 있습니다. 파일 몇 개만 변경하면 FastCgi 방법을 사용하는 것도 몇 분이면 됩니다. 이에 비해 웹 애플리케이션에서 Python을 배포하는 것은 주로 많은 수의 도구와 주류 서버의 지원 부족으로 인해 훨씬 더 복잡합니다. Python의 프로덕션 환경 배포 방법을 이해하기 전에 몇 가지 개념을 명확히 하겠습니다. 매우 중요합니다!
CGI:
CGI는 Common Gateway Interface(공통 게이트웨이 인터페이스)로, 외부 애플리케이션(CGI 프로그램)과 웹 서버 간의 인터페이스 표준입니다. 프로그램 및 웹 서버 간에 정보를 전송하는 절차. CGI 사양을 사용하면 웹 서버가 외부 프로그램을 실행하고 그 출력을 웹 브라우저로 보낼 수 있습니다. CGI는 웹의 간단한 정적 하이퍼미디어 문서 세트를 완전히 새로운 대화형 미디어로 전환합니다. 일반인의 관점에서 CGI는 웹 페이지와 WEB 서버의 실행 프로그램을 연결하는 다리와 같습니다. HTML에서 받은 명령을 서버의 실행 프로그램에 전달하고, 서버의 실행 프로그램의 결과를 HTML로 반환합니다. 페이지. CGI®는 탁월한 크로스 플랫폼 성능을 제공하며 거의 모든 운영 체제에서 구현될 수 있습니다.
CGI 메소드가 연결 요청(사용자 요청)을 발견하면 먼저 cgi 하위 프로세스를 생성하고 CGI 프로세스를 활성화한 다음 요청을 처리하고 처리 후 하위 프로세스를 종료해야 합니다. 이것이 포크 앤 실행 패턴입니다. 따라서 CGI를 사용하는 서버는 연결 요청 수만큼 많은 CGI 하위 프로세스를 가지게 됩니다. 하위 프로세스의 반복적인 로드는 CGI 성능이 저하되는 주요 원인입니다. 사용자 요청 수가 매우 많으면 메모리, CPU 시간 등 시스템 리소스를 많이 차지하게 되어 성능이 저하됩니다.
CGI 스크립트 작업 흐름:
브라우저는 HTML 양식이나 하이퍼링크를 통해 CGI 애플리케이션을 가리키는 URL을 요청합니다.
서버는 요청을 보내고 받기 위해 서버를 실행합니다. 지정된 CGI 응용 프로그램입니다.
CGI 애플리케이션은 일반적으로 뷰어의 입력을 기반으로 필요한 작업을 수행합니다.
CGI 애플리케이션은 결과를 웹 서버와 브라우저가 이해할 수 있는 문서(일반적으로 HTML 웹 페이지)로 형식화합니다.
웹 서버는 결과를 브라우저에 반환합니다.
Python에는 기본 cgi 프로그램을 지원하는 cgi 모듈이 있습니다.
FastCGI:
FastCGI는 HTTP 서버와 동적 스크립팅 언어 인터페이스 간의 확장 가능한 고속 통신입니다. . 가장 널리 사용되는 HTTP 서버는 Apache, Nginx 및 lighttpd를 포함한 FastCGI를 지원합니다. 동시에 FastCGI는 Python을 포함한 많은 스크립팅 언어에서도 지원됩니다. FastCGI는 CGI에서 개발 및 개선되었습니다. 전통적인 CGI 인터페이스 방법의 가장 큰 단점은 성능이 좋지 않다는 것입니다. 왜냐하면 HTTP 서버가 동적 프로그램을 만날 때마다 구문 분석을 수행하기 위해 스크립트 파서를 다시 시작해야 하고 결과가 HTTP 서버로 반환되기 때문입니다. 높은 동시 액세스를 처리할 때는 거의 사용할 수 없습니다. FastCGI는 항상 실행될 수 있는 CGI와 같습니다. 활성화되어 있는 한 매번 포크하는 데 시간이 걸리지 않습니다(이것은 CGI에서 가장 비판받는 포크 및 실행 모드입니다). . CGI는 소위 단기 애플리케이션이고 FastCGI는 소위 장기 애플리케이션입니다. FastCGI 프로그램은 지속적으로 새로운 프로세스를 생성할 필요가 없기 때문에 서버에 대한 부담을 크게 줄이고 응용 프로그램 효율성을 높일 수 있습니다. 속도 효율성은 CGI 기술보다 최소 5배 이상 높습니다. 또한 분산 컴퓨팅을 지원합니다. 즉, FastCGI 프로그램은 웹 사이트 서버가 아닌 호스트에서 실행될 수 있으며 다른 웹 사이트 서버의 요청을 수락할 수 있습니다.
FastCGI는 언어 독립적이고 확장 가능한 아키텍처 CGI 개방형 확장입니다. 주요 동작은 CGI 인터프리터 프로세스를 메모리에 유지하여 더 높은 성능을 얻는 것입니다.
우리 모두 알고 있듯이 CGI 인터프리터의 반복적인 로딩은 CGI 성능이 저하되는 주된 이유입니다. CGI 인터프리터가 메모리에 남아 있고 FastCGI 프로세스 관리자 스케줄링을 허용한다면 우수한 성능, 확장성, 장애 조치 기능 등을 제공할 수 있습니다. FastCGI 인터페이스는 HTTP 서버와 스크립트 구문 분석 서버를 분리하고 스크립트 구문 분석 서버에서 하나 이상의 스크립트 구문 분석 데몬을 시작할 수 있는 C/S 구조를 채택합니다. HTTP 서버가 동적 프로그램을 만날 때마다 실행을 위해 FastCGI 프로세스로 직접 전달된 다음 결과가 브라우저로 반환됩니다. 이 방법을 사용하면 HTTP 서버가 정적 요청을 독점적으로 처리하거나 동적 스크립트 서버의 결과를 클라이언트에 반환할 수 있으므로 전체 응용 프로그램 시스템의 성능이 크게 향상됩니다.
FastCGI 작업 흐름:
웹 서버가 시작될 때 FastCGI 프로세스 관리자(PHP-CGI, PHP-FPM 또는 스폰-cgi)를 로드합니다.
FastCGI 프로세스 관리자는 자체적으로 초기화되고 여러 CGI 인터프리터 프로세스(여러 php-cgi 표시)를 시작하고 웹 서버의 연결을 기다립니다.
클라이언트 요청이 웹 서버에 도달하면 FastCGI 프로세스 관리자는 CGI 인터프리터를 선택하고 연결합니다. 웹 서버는 CGI 환경 변수와 표준 입력을 FastCGI 하위 프로세스 php-cgi로 보냅니다.
FastCGI 하위 프로세스는 처리를 완료한 후 동일한 연결에서 표준 출력 및 오류 정보를 웹 서버로 반환합니다. FastCGI 하위 프로세스가 연결을 닫으면 요청이 처리됩니다. 그런 다음 FastCGI 하위 프로세스는 FastCGI 프로세스 관리자(웹 서버에서 실행)의 다음 연결을 기다리고 처리합니다. CGI 모드에서는 php-cgi가 여기서 종료됩니다.
FastCGI의 기능:
기존 페이지 처리 기술을 깨뜨립니다. 기존 페이지 처리 기술을 사용하는 경우 프로그램은 웹 서버 또는 응용 프로그램 서버와 동일한 서버에 있어야 합니다. 이러한 역사는 N년 전 FastCGI 기술에 의해 깨졌습니다. FastCGI 기술 응용 프로그램은 서버 그룹의 모든 서버에 설치될 수 있으며 TCP/IP 프로토콜을 통해 웹 서버와 통신할 수 있습니다. 이는 대규모 분산 응용 프로그램을 개발하는 데 적합합니다. 효율적인 데이터베이스 제어에도 적합합니다.
명시적 요청 모드. CGI 기술에는 명확한 역할이 없습니다. FastCGI 프로그램에서는 프로그램에 명확한 역할(응답자 역할, 인증자 역할, 필터 역할)이 할당됩니다.
WSGI:
Python 웹 서버 게이트웨이 인터페이스(Python 웹 서버 게이트웨이 인터페이스, WSGI로 약칭)는 웹 서버와 웹 애플리케이션 또는 Python 언어용으로 정의된 프레임워크 간의 인터페이스입니다. 간단하고 다양한 인터페이스. WSGI가 개발된 이후 유사한 인터페이스가 다른 많은 언어에도 등장했습니다. WSGI는 이식 가능한 웹 애플리케이션 개발의 일관성을 향상시키기 위한 웹 서버와 웹 애플리케이션 또는 애플리케이션 프레임워크 간의 하위 수준 인터페이스입니다. WSGI는 기존 CGI 표준을 기반으로 설계되었습니다.
WSGI는 두 부분으로 나누어집니다. 하나는 "서버" 또는 "게이트웨이"이고 다른 하나는 "애플리케이션" 또는 "애플리케이션 프레임워크"입니다. WSGI 요청을 처리할 때 서버는 애플리케이션에 환경 컨텍스트와 콜백 함수(Callback Function)를 제공합니다. 애플리케이션이 요청 처리를 완료하면 이전 콜백 함수를 통해 결과가 서버로 다시 전송됩니다. 소위 WSGI 미들웨어는 API의 양면을 구현하므로 WSGI 서비스와 WSGI 애플리케이션 사이를 중재할 수 있습니다. WSGI 서버 관점에서는 미들웨어가 애플리케이션 역할을 하고, 애플리케이션 관점에서는 미들웨어 서버 역할을 합니다. "미들웨어" 구성 요소는 다음 기능을 수행할 수 있습니다.
환경 변수를 다시 작성한 후 대상 URL을 기반으로 요청 메시지를 다른 애플리케이션 개체로 라우팅합니다.
여러 애플리케이션 또는 애플리케이션 프레임워크를 하나의 프로세스에서 동시에 실행할 수 있습니다.
네트워크를 통해 요청 및 응답 메시지를 전달하여 로드 밸런싱 및 원격을 수행합니다.
XSLT 스타일 시트 적용과 같은 콘텐츠 사후 처리를 수행합니다.
과거에는 적합한 웹 애플리케이션 프레임워크를 선택하는 방법이 Python 초보자를 괴롭히는 문제가 되었습니다. 이는 일반적으로 웹 애플리케이션 프레임워크를 선택하면 사용 가능한 웹 서버의 선택이 제한되기 때문입니다. 물론 그 반대도 마찬가지입니다. 당시 Python 애플리케이션은 일반적으로 CGI, FastCGI, mod_python 중 하나 또는 특정 웹 서버용 사용자 정의 API 인터페이스용으로 설계되었습니다. WSGI는 프로토콜에 더 가깝기 때문에 WSGI의 공식적인 구현은 없습니다. 이러한 프로토콜을 따르는 한 WSGI 애플리케이션은 모든 서버에서 실행될 수 있으며 그 반대의 경우도 마찬가지입니다. PHP의 CGI 래퍼인 Fastcgi에 비해 WSGI는 Python의 CGI 래퍼입니다.
WSGI는 웹 구성 요소를 웹 서버, 웹 미들웨어, 웹 애플리케이션의 세 가지 범주로 나눕니다. wsgi의 기본 처리 모드는 WSGI 서버 -> (WSGI 미들웨어)* -> WSGI 애플리케이션입니다.
uwsgi:
uwsgi 프로토콜은 uWSGI 서버가 소유한 프로토콜로, 전송될 정보 유형을 정의하는 데 사용됩니다. 각 uwsgi 패킷의 처음 4바이트는 다음과 같습니다. 전송 정보 유형 설명. 이는 WSGI와 비교하여 두 가지 다른 점입니다. 효율성은 fcgi의 10배라고 합니다. 구체적인 프로토콜 내용은 uwsgi 프로토콜을 참조하세요.
위 네 가지 모두 프로토콜로 이해될 수 있습니다! 규약! 규약! 이러한 프로토콜을 구현하면 웹 서버 및 웹 애플리케이션과 관련된 웹 서비스를 구현할 수 있습니다!
uWSGI:
uWSGI 프로젝트는 분산 클러스터 네트워크 애플리케이션을 배포하기 위한 완전한 솔루션을 개발하는 것을 목표로 합니다. uWSGI는 주로 웹과 웹의 표준 서비스를 지향하며 다양한 언어에서 성공적으로 사용되었습니다. uWSGI의 확장 가능한 아키텍처 덕분에 더 많은 플랫폼과 언어를 지원하도록 무한히 확장될 수 있습니다. 현재 C, C++ 및 Objective-C로 플러그인을 작성할 수 있습니다. 프로젝트 이름의 "WSGI"는 WSGI용 첫 번째 플러그인이 프로젝트를 위해 개발되었기 때문에 동일한 이름의 Python 웹 표준에 대한 고개를 끄덕이는 것입니다. uWSGI는 WSGI 프로토콜, uwsgi, http 및 기타 프로토콜을 구현하는 웹 서버입니다. uWSGI는 wsgi 프로토콜이나 FastCGI 프로토콜을 사용하지 않지만 위에서 언급한 대로 자체 uwsgi 프로토콜을 만듭니다.
uWSGI의 주요 기능은 다음과 같습니다.
초고속 성능.
낮은 메모리 사용량(apache2 mod_wsgi의 약 절반으로 측정됨).
여러 앱 관리.
자세한 로깅 기능(앱 성능 및 병목 현상을 분석하는 데 사용할 수 있음)
사용자 정의가 가능합니다(메모리 크기 제한, 특정 횟수 이후 서비스 재시작 등).
Gunicorn:
uWSGi와 유사한 도구로, 레일 배포 도구(Unicorn)에서 이식되었습니다. 그러나 이것이 사용하는 프로토콜은 Python2.5에 정의된 공식 표준(PEP 333?)인 WSGI입니다. 자세한 사용법 튜토리얼을 보려면 여기를 클릭하세요. Gunicorn은 프리포크(prefork) 모드를 채택하고 있으며, 다양한 웹 프레임워크와 호환되며 매우 간단한 실행과 가벼운 리소스 소비가 필요하며 매우 빠릅니다. Django와의 긴밀한 통합과 특히 편리한 배포가 특징입니다. 또한 HTTP 1.1을 지원하지 않고, 동시접속 성능이 높지 않으며, uWSGI, Gevent 등과는 일정한 성능차이가 있는 등 단점도 많습니다.
1. Gunicorn 디자인
Gunicorn은 여러 작업자 프로세스의 웹 서버를 생성하는 마스터 프로세스입니다. 마스터 프로세스는 작업자 프로세스의 생성 및 종료를 제어하며 작업자 프로세스는 요청을 수락하고 처리하기만 하면 됩니다. 이러한 분리로 인해 코드를 매우 편리하게 다시 로드하고 작업자 프로세스를 쉽게 추가하거나 제거할 수 있습니다. 저자는 작업 프로세스에서 Gevent, 동기화 동기 프로세스, Asyc 비동기 프로세스, Eventlet 등과 같은 다양한 IO 방법을 지원할 수 있도록 많은 공간을 제공했습니다. 마스터 프로세스와 작업자 프로세스가 완전히 분리되어 있어 Gunicorn은 본질적으로 프로세스를 제어하는 서비스입니다.
2. Gunicorn 소스 코드 구조
Application.run()에서 시작하여 먼저 구성을 초기화하고 파일에서 읽기, 터미널에서 읽기 등을 수행하여 구성을 완료합니다. 그런 다음 Arbiter를 시작합니다. Arbiter는 기본적으로 마스터 프로세스의 핵심입니다. 먼저 구성 클래스에서 읽고 설정한 다음 신호 처리 기능을 초기화하고 소켓을 설정합니다. 그런 다음 작업자 프로세스 생성을 시작하고 구성된 작업자 프로세스 수에 따라 생성됩니다. 그런 다음 폴링 상태로 들어가 신호를 수신하고 신호를 처리한 후 계속됩니다. 여기서 프로세스를 깨우는 방법은 PIPE를 생성하고 신호 처리 함수를 통해 파이프에 쓴 다음 마스터가 select.select()에서 깨어나는 것입니다.
생성 후 작업자 프로세스는 초기화를 시작한 다음 동일한 방식으로 신호를 처리하고 폴링, HTTP 요청 처리, WSGI 애플리케이션 측 호출 및 응답 반환 가져오기를 시작합니다. 그런 다음 계속하십시오.
동기화 동기화 프로세스의 장점은 각 요청이 격리되어 있어 각 요청의 실패가 다른 요청에 영향을 미치지 않지만 이로 인해 성능 병목 현상이 발생한다는 것입니다.
Tornado:
Tornado는 Python 개발 프레임워크이지만 자체 데이터 출력 구현은 일부 일반 요구 사항을 준수하지 않습니다. 위에서 언급한 프로토콜 자체가 웹 서버이기 때문에 동적 요청은 내부 메커니즘을 통해 사용자가 요청한 동적 콘텐츠로 직접 출력됩니다. 이를 별도의 서버로 사용하고 이를 Flask와 같은 다른 프레임워크와 함께 배포하려면 Tornado에 내장된 tornado.wsgi.WSGIContainer 프로토콜을 사용해야 합니다.
wsgiref:
Python은 WSGI 프로토콜을 구현하는 wsgi 서버와 함께 제공됩니다. wsgi 서버는 wsgi 사양을 준수하는 웹 서버로 이해될 수 있습니다. 요청 요청을 수신하고 일련의 환경 변수를 캡슐화하고 wsgi 사양에 따라 등록된 wsgi 앱을 호출하고 최종적으로 클라이언트에 응답을 반환합니다. Django 자체 서버입니다.
위의 내용은 모두 구현으로 이해하시면 됩니다! 성취하다! 성취하다! 프로토콜을 구현하는 도구!
참고: mod_wsgi(아파치 모듈)는 실제로 wsgi 프로토콜을 구현하는 모듈입니다. 현재는 거의 폐기되지 않았으므로 관심이 있으시면 직접 확인해 보세요.
따라서 Django 프레임워크를 사용하여 애플리케이션을 개발하고 이를 프로덕션 환경에 배포하려는 경우 Django와 함께 제공되는 것을 사용할 수 없습니다. uwsgi 프로토콜을 사용하는 uWSGI 서버를 사용할 수 있습니다. 또는 WSGI 프로토콜을 구현하는 gunicorn을 사용할 수도 있습니다. 또는 Tornado를 사용하거나 CGI 모드에서 FastCGI, Nginx, lighttpd 및 apache 서버를 사용할 수도 있습니다. 다른 프레임워크도 마찬가지입니다! 이러한 개념을 이해하고 나면 배포할 때 이를 인식할 수 있고, 다양한 도구를 일치시킬 때 "그게 무엇인지, 왜 그것이 무엇인지 알" 수 있습니다.
우리 그룹의 프로젝트에는 Django와 Tornado라는 두 가지 프레임워크가 있으며, 프로덕션 환경에서도 두 가지 배포 방식을 사용하고 있습니다. uWSGI 및 Gunicorn:
Django 프로젝트는 Nginx+uWSGI를 사용하여 배포되고 Tornado 프로젝트는 Nginx+Gunicorn을 사용하여 배포됩니다.
Nginx는 로드 밸런싱 및 정적 콘텐츠 전달에 사용됩니다. Tornado 프로젝트는 Supervisord를 사용하여 Gunicorn을 관리하고 Gunicorn을 사용하여 Tornado를 관리합니다. 우리 모두 알고 있듯이 Python의 GIL이 있기 때문에 Python의 동시성은 다중 프로세스 모드를 채택하므로 배포 방법은 하나의 코어와 두 개의 프로세스입니다.