Uwsgi与gevent vs线程

OLM*_*MER 8 python django multithreading gevent uwsgi

首先,抱歉我的英语不好.在我的项目中,我有很多I/O网络请求.主数据存储在另一个项目中,并且访问由Web API(JSON/XML)提供,轮询.我们为每个新用户会话使用此API(获取有关用户的信息).有时,我们在等待回复时遇到问题.我们使用nginx + uwsgi + django.如您所知,Django是同步(或阻塞).我们使用uwsgi和多线程来解决网络IO等待的问题.我决定读一下gevent.我理解合作和先发制人多任务之间的区别.我希望gevent可以更好地解决这个问题的uwsgi线程(网络I/O瓶颈).但结果几乎相同.有时gevent较弱.也许某个地方我错了.请告诉我.

这是uwsgi配置示例.GEVENT:

$ uwsgi --http :8001 --module ugtest.wsgi --gevent 40 --gevent-monkey-patch
Run Code Online (Sandbox Code Playgroud)

线程:

$ uwsgi --http :8001 --module ugtest.wsgi --enable-threads --threads 40
Run Code Online (Sandbox Code Playgroud)

控制器示例:

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
Run Code Online (Sandbox Code Playgroud)

测试(使用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
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我都有类似的时间.gevent/greenlets和合作多任务在类似问题(API代理)中有什么优势?

rob*_*rto 7

并发40不是让gevent闪耀的水平.Gevent是关于并发而不是并行(或每请求性能),因此具有这种"低"并发级别并不是获得改进的好方法.

一般来说,你会看到gevent并发,数千,而不是40 :)

对于阻塞I/O python线程也不错(GIL在I/O期间发布),gevent的优势在于资源使用(拥有1000个python线程将是矫枉过正)并且需要考虑锁定和朋友.

显然,请记住,您的整个应用程序必须是gevent友好的才能获得优势,而django(默认情况下)需要进行一些调整(例如,数据库适配器必须通过gevent友好的方式进行更改).