2017-02-13 13 views
0

의 우리는 이벤트 중심의 단일 스레드 서버에서 호스팅되는 WSGI 응용 프로그램이 있다고 가정하자Eventlet 요청에 WSGI 서버와 시간이 많이 걸리는 작업

응용 프로그램 기능 내에서
from eventlet import wsgi 
import eventlet 

def app(env, start_response): 
    # IO opeartions here 
    ... 

wsgi.server(eventlet.listen(('', 8090)), app) 

, 일부 I/O 작업 등을 파일 읽기 또는 DB 액세스가 수행되어야합니다.

이제 응용 프로그램에서 IO 작업을 수행하면 서버가 효과적으로 차단되어 다른 클라이언트를 지원할 수 없습니다.

Q :이 문제점의 가능한 해결책은 무엇입니까? Eventlet wsgi 서버에서 차단되지 않고 시간이 많이 소요되는 작업을 수행하려면 어떻게합니까?

답변

0

TL : DR : mysqldb/psycopg 또는 eventlet.import_patched() 순수 Python DB 드라이버 사용; 파일 및 기타 모든 파일은 tpool.execute()입니다.

사고 프로세스를 Eventlet과의 협력으로 변환 할 수있는 작업과 불가능한 작업으로 분리 해보십시오. 여기에서의 협력은 "코드 실행"- "결과 기다리기"부분으로 나누고 결과가 준비되면 알림 메커니즘을 제공하는 것을 의미합니다. Eventlet의 주요 알림 메커니즘은 파일 설명자입니다.

그래서 파일 설명자를 기다리는 모든 것이 녹색이 ​​될 수 있습니다 (차단하지 않음). 가장 중요한 것은 모든 네트워크 IO에 영향을 미칩니다. 블로킹 기능이 순수한 파이썬으로 작성 되었다면, 과 기타 이벤트릿 그린 버전을 수정하려면 import_patched(module_name)을 사용하십시오. mysqldbpsycopg2은 C 확장 모듈의 특수한 경우로서 저자의 명시적인 지원을 통해 협조 해 주신 데 대해 감사드립니다. 그 밖의 모든 것은 파이썬이 아닌 코드에서 블로킹합니다. 옵션은 OS 스레드입니다.

불행하게도 실제 디스크 파일을 기다리는 것은 단점으로 가득 찼기 때문에 OS 스레드를 사용하는 것이 좋으며이를 지원하는 기본 제공 스레드 풀이 있습니다. blocking_fun(filepath, something_else)eventlet.tpool.execute(blocking_fun, filepath, something_else)으로 변환하면 모든 것을 차단하지 않습니다. 자세한 내용은 tpool 설명서를 확인하십시오.

가능한 경우 전체 응용 프로그램을 차단 및 비 차단 프로세스로 리엔지니어링하고 소켓을 통해 통신하도록합니다. 이것은 코드 재 작성의 관점에서 어렵지만, 런타임, 디버깅에는 매우 간단합니다. 견고하고 오류없는 설계.