Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么在这个gevent程序中只与redis建立了一个连接?_Python_Redis_Gevent - Fatal编程技术网

Python 为什么在这个gevent程序中只与redis建立了一个连接?

Python 为什么在这个gevent程序中只与redis建立了一个连接?,python,redis,gevent,Python,Redis,Gevent,我正在使用gevent构建一个服务器,它执行一些redis操作并将结果返回给客户端。但是性能很差。经过一些研究,我发现只有一个连接到redis。看起来只有一只小青鱼产卵了。这是我的节目: #!/usr/bin/env python from gevent import monkey monkey.patch_all() import gevent from gevent.wsgi import WSGIServer from gevent.pool import Pool import geve

我正在使用gevent构建一个服务器,它执行一些redis操作并将结果返回给客户端。但是性能很差。经过一些研究,我发现只有一个连接到redis。看起来只有一只小青鱼产卵了。这是我的节目:

#!/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?

看看

我不是百分之百地认为你的猴子补丁正在发挥作用,但我想用以下方法来代替它:

import gevent
import redis.connection
redis.connection.socket = gevent.socket

您还可以使用gevent支持的redis连接创建自己的池…

什么让您认为您只有一个redis连接?实际上,我的小测试表明,您的服务器确实打开了许多到redis的连接

为了让测试更清楚,我稍微修改了您的打印语句:

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

可以看出,在peek时间,有10个greenlet同时运行,等待套接字。我觉得你的代码很好。为什么‘表现不好’是另一回事。它可能是你的“在线”分类集太大了。或者更可能的情况是,您正在使用阻塞客户端测试服务器,在这种情况下,您将只看到一个到redis的连接。

如果monkey补丁足够早,我认为这不是解决方案。我在redis python文件中的断点告诉我套接字已经修补好了。