Trước hết, xin lỗi vì tiếng Anh xấu của tôi. Trong dự án của tôi, tôi có rất nhiều yêu cầu mạng I/O. Dữ liệu chính được lưu trữ trong một dự án khác và quyền truy cập được cung cấp bởi API web (JSON/XML), bỏ phiếu. Chúng tôi sử dụng API này cho mỗi phiên người dùng mới (nhận thông tin về người dùng). Và đôi khi, chúng tôi gặp sự cố khi chờ phản hồi. Chúng tôi sử dụng nginx + uwsgi + django. Như bạn đã biết, Django là đồng bộ (hoặc chặn). Chúng tôi sử dụng uwsgi với đa luồng để giải quyết vấn đề với mạng IO chờ đợi. Tôi quyết định đọc về gevent. Tôi hiểu sự khác biệt giữa đa nhiệm hợp tác và ưu tiên. Và tôi hy vọng rằng gevent là giải pháp tốt hơn sau đó uwsgi chủ đề cho vấn đề này (mạng I/O nút cổ chai). Nhưng kết quả gần như giống nhau. Đôi khi gevent yếu hơn. Có thể một nơi nào đó tôi sai. Làm ơn hãy nói cho tôi.Uwsgi với gevent vs chủ đề
Đây là ví dụ về cấu hình uwsgi. Gevent:
$ uwsgi --http :8001 --module ugtest.wsgi --gevent 40 --gevent-monkey-patch
Threading:
$ uwsgi --http :8001 --module ugtest.wsgi --enable-threads --threads 40
khiển dụ:
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
thử nghiệm (với geventhttpclient):
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
Trong cả hai trường hợp, tôi có thời gian tương tự. Ưu điểm của một gevent/greenlets và đa tác vụ hợp tác trong một vấn đề tương tự (API proxying) là gì?
Tôi đang thử nghiệm nó với một số luồng/greenlets khác. Không phải hàng ngàn mà là hàng trăm. Và kết quả là tương tự. Tôi nghĩ rằng gevent là sự lựa chọn tốt nhất nếu tôi có nhiều hơn một yêu cầu trong hành động điều khiển của tôi (sử dụng join()/joinall()). Nhưng trong vấn đề của tôi ("proxy" -API) Tôi không có lợi ích đáng kể. Trong trường hợp đầu tiên (chủ đề) chúng ta có một cấu hình đơn giản: --threads N. Trong trường hợp thứ hai (gevent), chúng tôi có rất nhiều vấn đề với patching postgres driver (ví dụ), redis, vv. một vấn đề với dấu vết ngăn xếp đầy đủ ... – OLMER
Xin lỗi, không chắc chắn để theo bạn, nếu bạn không thể "vá" django, bạn không thể sử dụng gevent, thats'it. Ứng dụng của bạn phải là 100% không chặn, nếu không nó là một ứng dụng chặn và gevent sẽ không giúp bạn (tốt, nó thậm chí sẽ làm tồi tệ nhất) – roberto