화면 음악 c 프레임 워 크 메 이 킹 노트 의 wgi 프로 토 콜 의 장단 점 및 인터페이스 구현

선언:
또 WSGI 입 니 다.이것 은 제 가 잘 알 고 있 는 협의 입 니 다.예전 에 wgi server 를 실현 한 유 니 콘 과 uwsgi 에 대해 소스 코드 분석 글 을 쓴 적 이 있 습 니 다.  사실 그들의 실현 도 간단 하 다.바로 fllask,django 와 같은 application 에 environ,start 를 전달 하 는 것 이다.response 。

WSGI 프로 토 콜 이 무엇 인지,WSGI 서버 가 무엇 인지,그들의 차 이 는 무엇 입 니까?
온라인 구조 도 는 다른 사람 을 오도 하기 쉽다.얼핏 보면 nginx 와 같은 웹 서버 도 있 고 gunicorn 과 같은 wgi server 도 있다.  우 리 는 먼저 wgi 와 wgi server 의 관 계 를 설명 합 니 다.wgi 는 프로 토 콜 이 고 웹 바 텀 과 application 의 결합 을 해제 하 는 프로 토 콜 입 니 다.wgi server 는 스스로 웹 서버 를 만 들 고 wgi 프로 토 콜 을 빌려 애플 리 케 이 션 을 호출 합 니 다.nginx 는 fllask application 과 직접 통신 할 수 없 으 며,wgi server 를 빌려 야 한 다 는 점 을 명확 하 게 해 야 합 니 다.flask 자체 에 도 웹 서버 가 werkzeug 이 므 로 서 비 스 를 시작 하고 포트 를 감청 할 수 있 습 니 다.예전 에 uwsgi 가 이름 이 없 을 때 우 리 는 모두 apache+mode 를 사 용 했 던 것 을 기억한다.wgi 모드,apache 도 tornado 와 직접 통신 할 수 없습니다.wgi 는 torando 를 유 닉 스 socket 서비스 로 만 들 었 고,솔직히 도 하나의 서 비 스 를 시작 하여 apache 로 전송 했다.
nginx,apache 는 여기 서 proxy 의 역할 만 작 동 했 습 니 다.그런데 왜 uwsgi 와 gunicorn 을 직접 노출 하지 않 았 습 니까?nginx 의 정적 파일 처리 능력 이 매우 강하 기 때 문 입 니 다.

WSGI 는 어떻게 일 하 세 요?
wgi 는 주로 2 층,서버 측 과 응용 프로그램 입 니 다.
1  서버 측:http 분석 을 바 텀 에서 분석 한 다음 에 응용 프로그램 을 호출 하여 응용 프로그램 에(환경 정보)와(리 셋 함수)를 제공 합 니 다.이 리 셋 함 수 는 응용 프로그램 이 설정 한 http header 와 status 등 정 보 를 서버 측 에 전달 하 는 데 사 용 됩 니 다.
2  응용 프로그램:서버 측 에 되 돌아 갈 수 있 도록 돌아 오 는 header,body,status 를 생 성 합 니 다.
WSGI 는 socket 에서 온 패 킷 을 http 형식 으로 해석 한 다음 에 environ 변수 로 변 경 했 습 니 다.이 environ 변수 에는 wgi 자체 의 정보(예 를 들 어 host,post,프로 세 스 모드 등)가 있 고 client 의 header 와 body 정보 도 있 습 니 다.start_respnse 는 메 일 함수 입 니 다.두 개의 인 자 를 추가 해 야 합 니 다.하 나 는 status(http 상태),response 입 니 다.headers.
fllask,django,tornado 는 모두 WSGI 프로 토 콜 의 입 구 를 노출 합 니 다.우 리 는 WSGI 프로 토 콜,wgi server 를 실현 한 후에 fllask 에 environ 과 start 를 전달 해 야 합 니 다.response,application 이 값 을 되 돌려 준 후에 socket send 는 클 라 이언 트 로 돌아 갑 니 다.
WSGI 의 장점 과 단점 은 무엇 입 니까?
장점:
다양한 배치 선택 과 구성 요소 간 의 고도 결합
위 에서 언급 한 고도 의 디 결합 특성 으로 인해 이론 적 으로 WSGI 규범 에 부합 되 는 모든 App 은 WSGI 규범 을 실현 한 서버 에 배치 할 수 있 고 이것 은 Python 웹 응용 배치 에 큰 유연성 을 가 져 왔 다.
Flask 는 Werkzeug 기반 디 버 깅 서버 를 자체 가지 고 있 습 니 다.Flask 문서 에 따 르 면 생산 환경 에서 내 장 된 디 버 깅 서버 를 사용 하지 말고 다음 과 같은 방식 으로 배치 해 야 합 니 다.
GUNICORN
UWSGI
단점:
없다
우 리 는 wgi 층 에서 어떤 패션 을 할 수 있 습 니까?
  • 흑백 명단 규칙 방어
  • 환경 변 수 를 재 작성 하고 목표 URL 에 따라 요청 메 시 지 를 서로 다른 응용 대상 으로 이동 할 수 있 습 니 다.이 는 nginx location proxy 와 유사 한 규칙 을 실현 하면 고성능 을 tornado 에 전달 할 수 있다 는 뜻 이다.물론 이것 은 이상 적 인 조작 이다.
  • 한 프로 세 스에 서 여러 프로그램 이나 응용 프레임 워 크 를 동시에 실행 할 수 있 습 니 다
  • 4.567917.부하 균형 과 원 격 처 리 를 통 해 네트워크 에서 요청 과 응답 메 시 지 를 전달 합 니 다.4.567918.
    우 리 는 python 으로 이 wgi server 와 협 의 를 구체 적 으로 실현 합 니 다.
    
    #xiaorui.cc
     
    import socket
    import StringIO
    import sys
     
    class WSGIServer(object):
     
     address_family = socket.AF_INET
     socket_type = socket.SOCK_STREAM
     request_queue_size = 1
     
     def __init__(self, server_address):
      #        socket
      self.listen_socket = listen_socket = socket.socket(
       self.address_family,
       self.socket_type
      )
      #socket     
      listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      # Bind
      listen_socket.bind(server_address) #    
      # Activate
      listen_socket.listen(self.request_queue_size) #       
      # Get server host name and port
      host, port = self.listen_socket.getsockname()[:2]
      self.server_name = socket.getfqdn(host)
      self.server_port = port
      self.headers_set = []
     
     def set_app(self, application):
      self.application = application
     
     def serve_forever(self): #  WSGI server  ,        socket  。
      listen_socket = self.listen_socket
      while True:
        self.client_connection, client_address = listen_socket.accept()
       self.handle_one_request() #     
     
     def handle_one_request(self): #      
      self.request_data = request_data = self.client_connection.recv(1024)
      print(''.join(
       '< {line}
    '.format(line=line) for line in request_data.splitlines() )) self.parse_request(request_data) env = self.get_environ() # flask\tornado ,environ,start_response result = self.application(env, self.start_response) # Construct a response and send it back to the client self.finish_response(result) def parse_request(self, text): # socket http request_line = text.splitlines()[0] request_line = request_line.rstrip('\r
    ') # Break down the request line into components (self.request_method, # GET self.path, # /hello self.request_version # HTTP/1.1 ) = request_line.split() def get_environ(self): # environ env = {} env['wsgi.version'] = (1, 0) env['wsgi.url_scheme'] = 'http' env['wsgi.input'] = StringIO.StringIO(self.request_data) env['wsgi.errors'] = sys.stderr env['wsgi.multithread'] = False env['wsgi.multiprocess'] = False env['wsgi.run_once'] = False env['REQUEST_METHOD'] = self.request_method # GET env['PATH_INFO'] = self.path # /hello env['SERVER_NAME'] = self.server_name # localhost env['SERVER_PORT'] = str(self.server_port) # 8888 return env def start_response(self, status, response_headers, exc_info=None): # . server_headers = [ ('Date', 'Tue, 31 Mar 2015 12:54:48 GMT'), ('Server', 'WSGIServer 0.3'), ] self.headers_set = [status, response_headers + server_headers] def finish_response(self, result): # application WSGI 。 try: status, response_headers = self.headers_set response = 'HTTP/1.1 {status}\r
    '.format(status=status) for header in response_headers: response += '{0}: {1}\r
    '.format(*header) response += '\r
    ' for data in result: response += data # Print formatted response data a la 'curl -v' print(''.join( '> {line}
    '.format(line=line) for line in response.splitlines() )) self.client_connection.sendall(response) finally: self.client_connection.close() SERVER_ADDRESS = (HOST, PORT) = '', 8888 def make_server(server_address, application): server = WSGIServer(server_address) server.set_app(application) return server if __name__ == '__main__': if len(sys.argv) < 2: sys.exit('Provide a WSGI application object as module:callable') app_path = sys.argv[1] module, application = app_path.split(':') module = __import__(module) # application = getattr(module, application) # application WSGI 。 httpd = make_server(SERVER_ADDRESS, application) print('WSGIServer: Serving HTTP on port {port} ...
    '.format(port=PORT)) httpd.serve_forever()
    다음은 fllask application 의 인 스 턴 스 입 니 다.python 의 흔 한 웹 프레임 워 크 는 모두 wgi 인 터 페 이 스 를 호 환 하 는 것 을 발견 할 수 있 습 니 다.예외 가 없습니다.
    
    #xiaorui.cc
    from flask import Flask
    from flask import Response
    flask_app = Flask('flaskapp')
     
    @flask_app.route('/search')
    def hello_world():
     return Response(
      'xiaorui.cc Golang vs python !
    ', mimetype='text/plain' ) app = flask_app.wsgi_app
    실행 방식 은 매우 간단 하 다.
    
    python webserver2.py flaskapp:app
    다음 에는 이 wgi 프레임 워 크 를 빌려 prefork wgi server 로 확장 하 겠 습 니 다.   예전 에 wgi 에서 애플 리 케 이 션 의 분 류 를 한 적 이 있 지만 높 은 동시 다발 장면 에서 의 분 류 는 nginx 차원 에서 직접 하 는 것 을 권장 합 니 다.현재 nginx lua 의 프로 그래 밍 능력 이 점점 강해 지고 있 습 니 다.모두 nginx lua 를 사용 하여 게 이 트 웨 이 및 입구 개발 을 하고 있 습 니 다.
    참고 글:
    https://ruslanspivak.com/lsbaws-part2/
    총결산
    이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기