Найдите узкое место для применения в колбе
Я написал приложение с флягой. Я нашел это очень медленным, когда я развернул его на удаленном сервере.
Итак, я сделал некоторые профилирующие практики.
Пожалуйста, взгляните на фотографии ниже:
Код, который я использую для профилирования:
#coding: utf-8
from werkzeug.contrib.profiler import ProfilerMiddleware
from app import app
app.config['PROFILE'] = True
app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions = [30])
app.run(debug = True)
Изображение 1
профилирование на удаленном сервере .
Возможно, узким местом является _socket.getaddrinfo
![enter image description here]()
Изображение 2
профилирование на локальной машине.
Ничего не найдено узким местом.
![enter image description here]()
Изображение 3
Иногда даже на удаленном сервере нет узкого места. Нет _socket.getaddrinfo
найдено. Weird!
![enter image description here]()
Я тоже делал профилирование в оболочке python удаленного сервера с помощью cProfile
.
Взгляните на это:
In [10]: cProfile.run("socket.getaddrinfo('easylib.gdufslib.org', 80, 0, 0, socket.SOL_TCP)")
3 function calls in 8.014 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 8.014 8.014 :1()
1 8.014 8.014 8.014 8.014 {_socket.getaddrinfo}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
In [11]: cProfile.run("socket.getaddrinfo('easylib.gdufslib.org', 80, 0, 0, socket.SOL_TCP)")
3 function calls in 8.009 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 8.009 8.009 :1()
1 8.009 8.009 8.009 8.009 {_socket.getaddrinfo}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Возможно, есть факт, что для выполнения некоторого задания dns resolve
требуется много времени, и я не могу сам это изменить.
Может ли кто-нибудь мне сказать: почему вызывается _socket.getaddrinfo
и почему иногда не вызывается?
Как предотвратить вызов _socket.getaddrinfo
? Потому что это замедляет мой веб-сайт, который меня грустно опустил.
Ответы
Ответ 1
Я просто наткнулся на это сам в приложении Flask, работающем на выделенном ящике из Digital Ocean, поэтому я опубликую решение на случай, если кто-то еще ударит его в будущем.
Я заметил несколько дней назад, что запросы API к GitHub были безумно медленными, иногда занимая от 10 до 20 секунд. Но при запуске моего приложения локально не было никаких проблем. Я профилировал свое приложение, и socket.getaddrinfo
действительно был виновником:
1 15058.431 15058.4310 15058.431 15058.4310 {_socket.getaddrinfo}
1 26.545 26.5450 26.545 26.5450 {_ssl.sslwrap}
1 23.246 23.2460 23.246 23.2460 {built-in method do_handshake}
4 22.387 5.5968 22.387 5.5968 {built-in method read}
1 7.632 7.6320 7.632 7.6320 {method 'connect' of '_socket.socket' objects}
103 4.995 0.0485 7.131 0.0692 <s/werkzeug/urls.py:374(url_quote)>
2 2.459 1.2295 2.578 1.2890 <ssl.py:294(close)>
36 1.495 0.0415 10.548 0.2930 <s/werkzeug/routing.py:707(build)>
859 1.442 0.0017 1.693 0.0020 {isinstance}
.... etc.
Работа с поддержкой Digital Ocean, и, подозревая, что это как-то проблема DNS, рабочее решение должно было измениться (в /etc/resolv.conf
)
nameserver 4.2.2.2
nameserver 8.8.8.8
to
nameserver 8.8.4.4
nameserver 8.8.8.8
По какой-то причине 4.2.2.2
(запустил Level3) решил, что он меня ненавидит, но пока я и Google DNS круты.
Обновление: Мой коллега Карл предложил мне пойти и настроить локальный сервер кэширования DNS со связью, чтобы Google DNS не ненавидел меня. Эта ссылка была очень полезна.
Ответ 2
Я считаю, что это вызвано тем, что ваш удаленный хост не кэширует его DNS-запросы или getaddrinfo медленно из-за проблемы с IPv6.
Попробуйте (несколько раз) проверить, что ваши серверы имен кэшируются:
$ time host easylib.gdufslib.org
и проверить, выполняется ли поиск быстрее при форсировании только IPv4:
import socket
socket.getaddrinfo("easylib.gdufslib.org", 80, socket.AF_INET, 0, socket.SOL_TCP)
Если это вызвано первым, вы можете установить локальный кеширующий сервер имен или просто исправить, чтобы кеширование существующих серверов имен. Если последнее является причиной, вы можете попытаться исправить ее в своем коде и libs или отключить IPv6 на своем хосте, если вы его не используете.
Ответ 3
У меня была такая же проблема в ближайшем прошлом. Чтобы узнать, что вызывает медленность, я решил посмотреть, какие из моих конечных точек больше запрашиваются, а какие - узкое место. В этой связи я создал инструмент для анализа запросов. это может помочь вам, посмотрите на него https://github.com/muatik/flask-profiler