我正在使用gevent来构建一个服务器,它可以执行一些redis并将结果返回给客户端。但表现不好。经过一些研究,我发现redis只有一个连接。看起来只有一个greenlet产生了。这是我的计划:
#!/usr/bin/env python
from gevent import monkey
monkey.patch_all()
import gevent
from gevent.wsgi import WSGIServer
from gevent.pool import Pool
import gevent.socket
from cgi import parse_qs, escape
import json
import redis
p = redis.ConnectionPool()
def app(environ, start_response):
status = '200 OK'
body = ''
path = environ.get('PATH_INFO', '').lstrip('/')
parameters = parse_qs(environ.get('QUERY_STRING', ''))
r = redis.Redis(connection_pool=p)
if path == 'top':
l = r.zrevrange('online', 0, 50, True)
body = json.dumps({'onlinetime':map(lambda (pid, online): {'pid':pid, 'onlinetime':online}, l)}) + '\n'
headers = [
('Content-Type', 'text/html'),
('Content-Length', str(len(body))),
]
print 'in_use_conn:', len(p._in_use_connections), 'created_connections:', p._created_connections
start_response(status, headers)
yield body
def main():
pool = Pool(1000)
WSGIServer(('', 7332), app, spawn=pool, log=None).serve_forever()
if __name__ == '__main__':
main()
我的程序有问题吗?为什么只有一个连接到redis?
答案 0 :(得分:2)
查看http://gehrcke.de/2013/01/highly-concurrent-connections-to-redis-with-gevent-and-redis-py/
我不是100%是你的猴子补丁正在做的伎俩,但我用它替换它:
import gevent
import redis.connection
redis.connection.socket = gevent.socket
您还可以使用gevent支持的redis连接创建自己的池...
答案 1 :(得分:1)
是什么让你认为你只有一个与redis的连接?实际上我的小测试显示你的服务器确实打开了很多与redis的连接。
为了使测试更清晰,我稍微修改了你的print语句:
print '%s' % parameters['index'], 'in_use_conn:', len(p._in_use_connections), 'created_connections:', p._created_connections, 'available_conn:', len(p._available_connections)
然后运行此脚本发出一些请求:
for i in {1..20}
do
wget http://127.0.0.1:7332/top?index=$i > /dev/null 2>&1 &
done
这就是我得到的:
['1'] in_use_conn: 1 created_connections: 2 available_conn: 1
['2'] in_use_conn: 4 created_connections: 5 available_conn: 1
['3'] in_use_conn: 3 created_connections: 5 available_conn: 2
['4'] in_use_conn: 5 created_connections: 6 available_conn: 1
['6'] in_use_conn: 4 created_connections: 6 available_conn: 2
['5'] in_use_conn: 3 created_connections: 6 available_conn: 3
['7'] in_use_conn: 2 created_connections: 6 available_conn: 4
['10'] in_use_conn: 1 created_connections: 6 available_conn: 5
['8'] in_use_conn: 0 created_connections: 6 available_conn: 6
['14'] in_use_conn: 10 created_connections: 11 available_conn: 1
['11'] in_use_conn: 9 created_connections: 11 available_conn: 2
['12'] in_use_conn: 8 created_connections: 11 available_conn: 3
['16'] in_use_conn: 7 created_connections: 11 available_conn: 4
['15'] in_use_conn: 6 created_connections: 11 available_conn: 5
['13'] in_use_conn: 5 created_connections: 11 available_conn: 6
['20'] in_use_conn: 4 created_connections: 11 available_conn: 7
['19'] in_use_conn: 3 created_connections: 11 available_conn: 8
['9'] in_use_conn: 2 created_connections: 11 available_conn: 9
['17'] in_use_conn: 1 created_connections: 11 available_conn: 10
['18'] in_use_conn: 0 created_connections: 11 available_conn: 11
可以看出,在偷看时你有10个greenlet同时运行,等待套接字。你的代码对我来说非常好。为什么'表现不好'是另一回事。它可能是你排序的“在线”太大了。或者更有可能是使用阻塞客户端来测试服务器,在这种情况下,您只能看到一个与redis的连接。