Я специалист по данным / разработчик машинного обучения. Иногда мне нужно раскрыть свои модели, указав конечную точку. Обычно я делаю это через Flask и gunicorn:
exampleproject.py
:
import random
from flask import Flask
app = Flask(__name__)
random.seed(0)
@app.route("/")
def hello():
x = random.randint(1, 100)
y = random.randint(1, 100)
return str(x * y)
if __name__ == "__main__":
app.run(host='0.0.0.0')
wsgi.py
:
from exampleproject import app
if __name__ == "__main__":
app.run()
Бежать
$ gunicorn --bind 0.0.0.0:5000 wsgi:app
Когда я тестирую этот простой скрипт, я получаю:
$ ab -s 30 -c 200 -n 25000 -v 1 http://localhost:5000/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 2500 requests
Completed 5000 requests
Completed 7500 requests
Completed 10000 requests
Completed 12500 requests
Completed 15000 requests
Completed 17500 requests
Completed 20000 requests
Completed 22500 requests
apr_pollset_poll: The timeout specified has expired (70007)
Total of 24941 requests completed
С меньшим количеством запросов все выглядит нормально:
$ ab -l -s 30 -c 200 -n 200 -v 1 http://localhost:5000/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Finished 200 requests
Server Software: gunicorn/19.9.0
Server Hostname: localhost
Server Port: 5000
Document Path: /
Document Length: Variable
Concurrency Level: 200
Time taken for tests: 0.084 seconds
Complete requests: 200
Failed requests: 0
Total transferred: 32513 bytes
HTML transferred: 713 bytes
Requests per second: 2380.19 [#/sec] (mean)
Time per request: 84.027 [ms] (mean)
Time per request: 0.420 [ms] (mean, across all concurrent requests)
Transfer rate: 377.87 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 2 1.2 2 3
Processing: 1 36 16.8 41 52
Waiting: 1 36 16.8 41 52
Total: 4 37 15.8 43 54
Percentage of the requests served within a certain time (ms)
50% 43
66% 51
75% 51
80% 52
90% 52
95% 52
98% 53
99% 53
100% 54 (longest request)
Могу ли я что-то изменить, чтобы улучшить конфигурацию для моей рабочей нагрузки?
Когда я выполняю только один вызов моей реальной модели, я вижу ответ через 0,5 секунды. Я бы сказал, что время выполнения до 1,0 с является разумным. Каждый вызов не имеет состояния, то есть каждый вызов должен быть независимым от других вызовов.
Когда я попытался проанализировать эту проблему, я увидел много TIME_WAIT
:
$ netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n
1 established)
1 Foreign
2 CLOSE_WAIT
4 LISTEN
10 SYN_SENT
60 SYN_RECV
359 ESTABLISHED
13916 TIME_WAIT
Как я могу подтвердить / опровергнуть, что это проблема? Это как-то связано с Flask / gunicorn? Как nginx соотносится с Gunicorn?