우선, 내 나쁜 영어로 유감스럽게 생각합니다. 내 프로젝트에는 많은 I/O 네트워크 요청이 있습니다. 주요 데이터는 다른 프로젝트에 저장되며 액세스는 웹 API (JSON/XML), 폴링에 의해 제공됩니다. 새로운 사용자 세션마다이 API를 사용합니다 (사용자에 대한 정보 얻기). 때로는 응답을 기다리는 데 문제가 있습니다. 우리는 nginx + uwsgi + django를 사용합니다. 아시다시피, Django는 동기식 (또는 블로킹)입니다. 대기중인 네트워크 IO 문제를 해결하기 위해 멀티 스레딩과 함께 uwsgi를 사용합니다. 나는 gevent에 관해 읽는 것을 결심했다. 협동과 선점 멀티 태스킹의 차이점을 이해합니다. 그리고이 문제 (네트워크 I/O 병목 현상)에 대해 gevent가 uwsgi 스레드보다 나은 솔루션이되기를 바랍니다. 그러나 그 결과는 거의 동일했다. 때때로 gevent는 약했다. 어딘가 잘못되었습니다. 말해줘. 제발.gevent 대 스레드가있는 Uwsgi
여기에 uwsgi 구성 예제가 있습니다. Gevent :
$ uwsgi --http :8001 --module ugtest.wsgi --gevent 40 --gevent-monkey-patch
스레딩 :
$ uwsgi --http :8001 --module ugtest.wsgi --enable-threads --threads 40
예 컨트롤러 (geventhttpclient)와
def simple_test_action(request):
# get data from API without parsing (only for simple I/O test)
data = _get_data_by_url(API_URL)
return JsonResponse(data, safe=False)
import httplib
from urlparse import urlparse
def _get_data_by_url(url):
u = urlparse(url)
if str(u.scheme).strip().lower() == 'https':
conn = httplib.HTTPSConnection(u.netloc)
else:
conn = httplib.HTTPConnection(u.netloc)
path_with_params = '%s?%s' % (u.path, u.query,)
conn.request("GET", path_with_params)
resp = conn.getresponse()
print resp.status, resp.reason
body = resp.read()
return body
시험 :
def get_info(i):
url = URL('http://localhost:8001/simpletestaction/')
http = HTTPClient.from_url(url, concurrency=100, connection_timeout=60, network_timeout=60)
try:
response = http.get(url.request_uri)
s = response.status_code
body = response.read()
finally:
http.close()
dt_start = dt.now()
print 'Start: %s' % dt_start
threads = [gevent.spawn(get_info, i) for i in xrange(401)]
gevent.joinall(threads)
dt_end = dt.now()
print 'End: %s' % dt_end
print dt_end-dt_start
두 경우 모두 비슷한 시간이 있습니다. 비슷한 문제 (API 프록 싱)에서 gevent/greenlets 및 협업 멀티 태스킹의 이점은 무엇입니까?
다른 수의 thread/greenlets로 테스트하려고합니다. 수천이 아니라 수백. 결과도 비슷합니다. 컨트롤러 동작에서 join()/joinall()을 사용하여 둘 이상의 요청이있는 경우 gevent가 가장 좋은 선택이라고 생각합니다. 그러나 문제 ("프록시"-API)에서 중요한 이점은 없습니다. 첫 번째 경우 (스레드)에는 간단한 구성이 있습니다. --threads N. 두 번째 경우 (gevent)에는 postgres 드라이버 (예 :), redis 등을 패치하는 데 많은 문제가 있습니다. 또한 전체 스택 추적 문제 ... – OLMER
django를 "패치"할 수 없다면 죄송합니다, 당신을 따라 오지 못할 수도 있습니다. 당신은 gevent를 사용할 수 없습니다. 귀하의 애플 리케이션은 100 % non-blocking이어야합니다. 그렇지 않으면 애플 리케이션을 차단하고 gevent가 도움이되지 않습니다 (글쎄, 최악의 경우도 할 것입니다) – roberto