Python检查大量请求

时间:2015-05-25 15:43:17

标签: python mysql linux nginx

我正在使用Python脚本来检查用户是否存在请求。 使用:

import MySQLdb 
from flask import Flask, request, abort
app = Flask(__name__)
try:
    db = MySQLdb.connect('xxx1','my_username','my_password','my_db_name')
    db1 = MySQLdb.connect('xxx2','my_username','my_password','my_db_name')
    db2=
    db3=
except MySQLdb.OperationalError as e:
    print "Caught an exception : " + str(.message)

@app.route('/')
@app.route('/<path:path>')
def page(path = ''):
user = request.args.get('user', None)
if not mac: 
    abort (403)

cursor = db.cursor()
query = 'Select ID from f_member where Name=%s'
db.commit()
cursor execute(query, (user, ))
row = cursor.fetchone()
cursor.close()

#cursor.db1 here

if row == None and row1 == None:
    abort (403)
return 'OK', 200

if __name__ == '__main__':
    app.run(host=host, port=port)

然后我有5个nginx服务器:

location = /auth {
proxy_pass http://xxx.xxx$request_uri;
proxy_pass_request_body off;
proxy_set_header Content_Lenght "";
proxy_set_header X-Real-IP $remote_addr;

所以问题是,这个脚本会检查是否找到了用户 数据库,如果为true,则访问该页面。 问题是我的用户列表现在最多可达5k用户。当我运行.py脚本时,它运行得如此之快(即使有403个人试图连接错误),然后断开的管道开始出现。 看起来它正在变得过载,是否有更好的方法来处理我的脚本,以便它运行得更好,效率更高?

2 个答案:

答案 0 :(得分:0)

您可以在Python程序中使用字典作为用户名/ id映射。基本上,当程序启动时,它将对所有用户进行查询并填充地图。之后,每隔20秒左右,它会进行查询以获取f_member中的“更改”以更新字典。查找用户名始终在此地图中发生。如果在地图中找不到用户名,则只进行数据库查询(如果在数据库中找到用户详细信息,则也更新本地地图)。 如果表中没有数百万用户,则此方法可行。否则使用LRU缓存。

答案 1 :(得分:0)

因此,在冗长的评论帖子之后,看起来您的烧瓶实例可能正在争夺数据库资源。还有另一种假设认为,在全球范围内保存你的连接可能会产生一些不良的副作用(我可能会错误,但我会关注超时,而不是关闭连接等)。以下是我可以重写它的方法:

import MySQLdb 
from flask import Flask, request, abort
app = Flask(__name__)

def get_db_connection_args():
    try:
        db_args = { 'host':'xxx1', 'user':'my_username', 'passwd':'my_password', 'db':'my_db_name' }
        db1_args = { 'host':'xxx2', 'user':'my_username', 'passwd':'my_password', 'db':'my_db_name' }
        db2_args = { 'host':'xxx3', 'user':'my_username', 'passwd':'my_password', 'db':'my_db_name' }
        db3_args = { 'host':'xxx4', 'user':'my_username', 'passwd':'my_password', 'db':'my_db_name' }
    except MySQLdb.OperationalError as e:
        print "Caught an exception : " + str(.message)
    return (db_args, db1_args, db2_args, db3_args)

@app.route('/')
@app.route('/<path:path>')
def page(path = ''):
    user = request.args.get('user', None)
    #I don't know what mac is...but it was in your original code.
    if not mac:
        abort (403)

    found = False
    db_connection_args = get_db_connection_args()
    for db_connection_arg_dict in db_connection_args:
        if not found:
            db_conn = MySQLdb.connect(**db_connection_arg_dict)
            try:
                cursor = db_conn.cursor()
                cursor.execute('Select ID from f_member where Name=%s', (user, ))
                row = cursor.fetchone()
                if row:
                    found = True
            finally:
                db_conn.close()

    if found:
        return 'OK', 200

    abort (403)

if __name__ == '__main__':
    app.run(host=host, port=port)