【问题标题】:InterfaceError(0, '') when sending concurrent requestsInterfaceError(0, '') 发送并发请求时
【发布时间】:2019-01-05 07:54:56
【问题描述】:

我正在使用 Flask 和 PyMySQL 构建一个简单的应用程序,以使用 JMeter 进行负载测试以用于学术目的。它已经接收请求并发出响应。但是当我发送多个请求时,它会在几个请求(有时只有一个请求)后喷出下面的错误。

Traceback (most recent call last):
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/username/BossFight/python/helloflask.py", line 82, in get_driver
    if (authentication_success(token)):
  File "/home/username/BossFight/python/helloflask.py", line 21, in authentication_success
    cursor.execute("SELECT COUNT(*) AS matches FROM users WHERE id=%s", (id))
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/pymysql/cursors.py", line 170, in execute
    result = self._query(query)
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/pymysql/connections.py", line 515, in query
    self._execute_command(COMMAND.COM_QUERY, sql)
  File "/home/username/BossFight/python/venv/lib/python3.6/site-packages/pymysql/connections.py", line 745, in _execute_command
    raise err.InterfaceError("(0, '')")
pymysql.err.InterfaceError: (0, '')

之后,除了 HTTP 500 之外,它不再响应任何内容,必须重新启动。

以下是源代码的相关部分:

from flask import Flask,jsonify,request
import pymysql.cursors
import bcrypt
import jwt
from pprint import pprint

app = Flask(__name__)
connection = pymysql.connect(
host='localhost',
db='omnibus',
user='starleaf1',
password='alleluia',
cursorclass=pymysql.cursors.DictCursor
)

secret = 'keyboard cat'

def authentication_success(token):
    id=jwt.decode(token, secret, algorithms=['HS256'])["id"]
    cursor=connection.cursor()
    cursor.execute("SELECT COUNT(*) AS matches FROM users WHERE id=%s", (id))
    return (cursor.fetchone()['matches'] == 1)

# Other routes goes here....

@app.route('/api/driver/<string:driver_id>', methods=['GET'])
def get_driver(driver_id):
    cursor = connection.cursor()
    token=request.headers['Authorization'][7:]
    if (authentication_success(token)):
        cursor.execute(query_get_driver_by_id, (driver_id))
        driver=cursor.fetchone()
        if (not(driver is None)):
            return jsonify(message="ok",driver=driver)
        else:
            return jsonify(message="not found"),404
    else:
        return jsonify(message="authentication required"),401

请记住,我是 Python 的初学者。任何帮助将不胜感激。

【问题讨论】:

  • 您的代码不包含追溯中的任何一行。
  • @KlausD。修好了。
  • 那是错误的。
  • @KlausD。哎呀。我现在看到了。我想我修好了。

标签: python flask pymysql


【解决方案1】:

问题可能在于您有一个全局连接。在 Web 应用程序中,每个请求都应该有自己的数据库连接。因此,您的 get_driver 函数应该创建一个连接并在完成后关闭该连接(在 finally 子句中)。

比如:

def create_connection():
    return pymysql.connect(
        host='localhost',
        db='omnibus',
        user='starleaf1',
        password='alleluia',
        cursorclass=pymysql.cursors.DictCursor
    )

@app.route('/api/driver/<string:driver_id>', methods=['GET'])
def get_driver(driver_id):
    connection = create_connection()
    try:
        cursor = connection.cursor()
        token=request.headers['Authorization'][7:]
        if (authentication_success(token)):
            cursor.execute("SELECT COUNT(*) AS matches FROM users WHERE id=%s", (driver_id))
            driver=cursor.fetchone()
            if (not(driver is None)):
                return jsonify(message="ok",driver=driver)
            else:
                return jsonify(message="not found"),404
        else:
            return jsonify(message="authentication required"),401
    finally:
        connection.close()

【讨论】:

  • 我最终实现了一些不同的东西。最值得注意的是,在driver=cursor.fetchone() 之后立即调用connection.close()
猜你喜欢
  • 2018-09-23
  • 2021-01-14
  • 2016-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-24
相关资源
最近更新 更多