Особенности работы backend для
мобильных приложений или
Python Django UWSGI в продакшен
Дмитрий Швеенков, руководитель команды разработки
О себе
Дмитрий Швеенков
Руководитель команды разработки в Mail.Ru Group
mailto: shveenkov@mail.ru
2
Мобильные приложения
Новости Гороскопы
3
О чем доклад
- Особенности разработки backend для мобильных приложений
- Измерение времени ответа backend
- Особенности работы стека python – django – uwsgi – nginx
- Оптимизация производительности
- Инструменты и подходы, которые мы используем
4
Задачи backend
- Агрегация информации о новостных ресурсах
- Хранение медиа контента
- Кэширование данных
- JSON API
- Работа с изображениями (crop, resize)
5
Особенности разработки API
- Разнообразие устройств и ОС:
- Планшеты
- Смартфоны
- iOS
- Android
- Windows phone
- и т.п.
- Редизайн мобильных приложений
6
Время запуска приложения
Время запуска влияет на ретеншен - http://bit.ly/2cDc60a
7
Допустимое время ответа backend
Каким должен быть response_time?
- 1 секунда, это быстро?
- 5 секунд?
- 200 миллисекунд, норма
8
Как измерить время работы backend?
- Измерения на backend - timeit $ python -m timeit '"-".join(str(n) for n in range(100))'
- Измерения на клиенте - wrk, ab, siege
- Nginx access logs log_format main '$remote_addr - [$time_local] "$request" '
'$status $bytes_sent $request_length '
'$request_time $upstream_response_time'
9
Графики rps и upstream_time
10
upstream_response_time хороший показатель?
Среднее для upstream_response_time
(20 + 10 + 20 + 10 + 10 + 20 + 500 + 500 + 500 + 400) / 10 = 199мс
Персентили http://bit.ly/2d4z5zi
$ fgrep "13/Sep/2016:10:" access.log | awk '{print $NF}' | sort -n | python percentile_stdin.py
11
Сбор метрик в продакшен
- Statsd+Graphite+Grafana
https://github.com/bitly/statsdaemon
http://graphiteapp.org/
http://grafana.org/
- Отправка из uwsgi --carbon 127.0.0.1:2003
- Diamond для cpu, la, network и iostat
https://github.com/python-diamond/Diamond
- Хранение истории
- Группировка по платформам ios/android
- Автоматизация сравнения графиков
http://bit.ly/2d8fcHl
12
- Рост кол-ва пользователей приводит к росту qps к backend
- Рост qps потребляет ресурсы сервера
- Для обработки запросов требуются uwsgi-workers
Как выбрать оптимальное количество workers? http://bit.ly/2cDjGpA
cpu cores x 2
Рост нагрузки, стек python – django – uwsgi – nginx
13
Как uWSGI обрабатывает входящие запросы?
Рост нагрузки
bind
listen
fork
while true:
a
ccept
uWSGI master uWSGI worker
14
Рост нагрузки
- uwsgi options --thunder-lock - http://bit.ly/2ckdRPe
- David Cramer, discus.com - http://bit.ly/2cxckEX
15
Рост нагрузки
Параметры nginx http://bit.ly/2cfxEkh:
- uwsgi_buffers
- uwsgi_buffer_size
location /news {
uwsgi_pass mobs_backend;
include uwsgi_params;
uwsgi_buffers 256 16k;
}
16
Профилирование django-python
Профилирование начинается в голове разработчика ©
http://bit.ly/2cV82Gg
http://bit.ly/2ckeTKS
pip install django-extensions
INSTALLED_APPS += ('django_extensions',)
python manage.py runprofileserver --use-cprofile --prof-path=~/prof
wget -O- -S http://127.0.0.1:8000/news/v2/getNewsById?id=291235
gprof2dot -f pstats ~/prof/out.prof | dot -Tpng -o ~/prof/out.png
17
Визуализация результатов профилирования
18
Визуализация результатов профилирования
19
Тюнинг memcached
- python-memcached pickle/cpickle commit http://bit.ly/2ckfdJL
- модуль pymemcache http://bit.ly/2cDCsir
- упаковка/распаковка через msgpack
- использование опций noreply=true, tcp_nodelay=1
20
К чему мы стремимся при разработке backend
- Меньше обращений
- Легкие запросы
- Простые решения
21
Подводим итоги
- Разработка backend для мобильных приложений отличается от backend
для web приложений
- Производительность стека python – django – uwsgi – nginx требует
экспериментальных проверок в продакшен
- Для мобильного приложения очень важно время ответа backend
- Время ответа backend нужно измерять правильно
22
Вопросы?
Спасибо за внимание!
mailto: shveenkov@mail.ru
23
Настройка mysql
- myISAM, не используем транзакции
- key_buffer_size >= sum(du -hs *.MYI)
- ssd
- mysql_query_cache
- mysql_slow_query_log
24
Пример кода view, чего стараемся избегать
class GetNewsByIdView(BaseNewsView):
def get_response(self, request):
if version == "1.0":
return {...}
elif version == "2.0":
return []
25

Особенности работы backend для мобильных приложений или Python Django UWSGI в продакшен, Дмитрий Швеенков, Mail.Ru Group

  • 1.
    Особенности работы backendдля мобильных приложений или Python Django UWSGI в продакшен Дмитрий Швеенков, руководитель команды разработки
  • 2.
    О себе Дмитрий Швеенков Руководителькоманды разработки в Mail.Ru Group mailto: shveenkov@mail.ru 2
  • 3.
  • 4.
    О чем доклад -Особенности разработки backend для мобильных приложений - Измерение времени ответа backend - Особенности работы стека python – django – uwsgi – nginx - Оптимизация производительности - Инструменты и подходы, которые мы используем 4
  • 5.
    Задачи backend - Агрегацияинформации о новостных ресурсах - Хранение медиа контента - Кэширование данных - JSON API - Работа с изображениями (crop, resize) 5
  • 6.
    Особенности разработки API -Разнообразие устройств и ОС: - Планшеты - Смартфоны - iOS - Android - Windows phone - и т.п. - Редизайн мобильных приложений 6
  • 7.
    Время запуска приложения Времязапуска влияет на ретеншен - http://bit.ly/2cDc60a 7
  • 8.
    Допустимое время ответаbackend Каким должен быть response_time? - 1 секунда, это быстро? - 5 секунд? - 200 миллисекунд, норма 8
  • 9.
    Как измерить времяработы backend? - Измерения на backend - timeit $ python -m timeit '"-".join(str(n) for n in range(100))' - Измерения на клиенте - wrk, ab, siege - Nginx access logs log_format main '$remote_addr - [$time_local] "$request" ' '$status $bytes_sent $request_length ' '$request_time $upstream_response_time' 9
  • 10.
    Графики rps иupstream_time 10
  • 11.
    upstream_response_time хороший показатель? Среднеедля upstream_response_time (20 + 10 + 20 + 10 + 10 + 20 + 500 + 500 + 500 + 400) / 10 = 199мс Персентили http://bit.ly/2d4z5zi $ fgrep "13/Sep/2016:10:" access.log | awk '{print $NF}' | sort -n | python percentile_stdin.py 11
  • 12.
    Сбор метрик впродакшен - Statsd+Graphite+Grafana https://github.com/bitly/statsdaemon http://graphiteapp.org/ http://grafana.org/ - Отправка из uwsgi --carbon 127.0.0.1:2003 - Diamond для cpu, la, network и iostat https://github.com/python-diamond/Diamond - Хранение истории - Группировка по платформам ios/android - Автоматизация сравнения графиков http://bit.ly/2d8fcHl 12
  • 13.
    - Рост кол-вапользователей приводит к росту qps к backend - Рост qps потребляет ресурсы сервера - Для обработки запросов требуются uwsgi-workers Как выбрать оптимальное количество workers? http://bit.ly/2cDjGpA cpu cores x 2 Рост нагрузки, стек python – django – uwsgi – nginx 13
  • 14.
    Как uWSGI обрабатываетвходящие запросы? Рост нагрузки bind listen fork while true: a ccept uWSGI master uWSGI worker 14
  • 15.
    Рост нагрузки - uwsgioptions --thunder-lock - http://bit.ly/2ckdRPe - David Cramer, discus.com - http://bit.ly/2cxckEX 15
  • 16.
    Рост нагрузки Параметры nginxhttp://bit.ly/2cfxEkh: - uwsgi_buffers - uwsgi_buffer_size location /news { uwsgi_pass mobs_backend; include uwsgi_params; uwsgi_buffers 256 16k; } 16
  • 17.
    Профилирование django-python Профилирование начинаетсяв голове разработчика © http://bit.ly/2cV82Gg http://bit.ly/2ckeTKS pip install django-extensions INSTALLED_APPS += ('django_extensions',) python manage.py runprofileserver --use-cprofile --prof-path=~/prof wget -O- -S http://127.0.0.1:8000/news/v2/getNewsById?id=291235 gprof2dot -f pstats ~/prof/out.prof | dot -Tpng -o ~/prof/out.png 17
  • 18.
  • 19.
  • 20.
    Тюнинг memcached - python-memcachedpickle/cpickle commit http://bit.ly/2ckfdJL - модуль pymemcache http://bit.ly/2cDCsir - упаковка/распаковка через msgpack - использование опций noreply=true, tcp_nodelay=1 20
  • 21.
    К чему мыстремимся при разработке backend - Меньше обращений - Легкие запросы - Простые решения 21
  • 22.
    Подводим итоги - Разработкаbackend для мобильных приложений отличается от backend для web приложений - Производительность стека python – django – uwsgi – nginx требует экспериментальных проверок в продакшен - Для мобильного приложения очень важно время ответа backend - Время ответа backend нужно измерять правильно 22
  • 23.
  • 24.
    Настройка mysql - myISAM,не используем транзакции - key_buffer_size >= sum(du -hs *.MYI) - ssd - mysql_query_cache - mysql_slow_query_log 24
  • 25.
    Пример кода view,чего стараемся избегать class GetNewsByIdView(BaseNewsView): def get_response(self, request): if version == "1.0": return {...} elif version == "2.0": return [] 25

Editor's Notes

  • #9 KPI (Key Performance Indicator) – это показатель достижения успеха в определенной деятельности или в достижении определенных целей