我有一个具有以下设置的Web应用程序:
Django 2.1.7 Web应用程序。我正在使用gunicorn作为我的Web服务器。启动gunicorn服务器的脚本:
gunicorn project_config.wsgi:application --worker-class = gevent --worker-connections = 1000 --workers = 8
我有并发的API请求(它进行了一些繁重的处理,但大多数是存储过程调用-花费在执行IO上的时间最多)。 因此,在提供多个API调用时,我会并行运行多个存储过程调用。
由于我正在使用gevent worker类启动我的gunicorn服务器,因此它会创建8个worker进程(不是绿线程)。这意味着在每个API请求之间不会发生上下文切换。 但是我的存储过程调用执行时间是API调用次数的两倍。因此,一个完成的API请求实际上是10分钟,如果并行提供另一个API调用,则需要20分钟。同样,如果并行处理3个请求,则同一请求需要30分钟才能完成。
最初,我认为这与多线程和GIL锁有关,因为python线程实际上并不并行运行。但是,当我打印PID(使用os.getpid())时,每个请求都打印唯一的PID(gevent worker进程的pid),这意味着它们在单独的进程中进行处理,应该并行运行。
我的存储过程是一个复杂的select语句。它不执行任何DELETE / UPDATE查询,这也意味着不涉及锁定。 为什么然后我的存储过程执行时间随每个请求的增加而增加。
即使我这样做
SELECT * from information_schema.PROCESSLIST;
它向我显示了当前正在执行的MYSQL进程的数量,该数量与API请求的数量完全相同,这再次意味着存在并行运行的存储过程调用。
以上声明的输出:
ID COMMAND TIME STATE INFO
338470 Query 9 Creating sort index SELECT * FROM ....
338312 Query 1 Sending data SELECT * FROM ....
338311 Query 4 Sending data SELECT * FROM ....