Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Отладка и эксплуатация Rails-приложений

678 visualizaciones

Publicado el

Publicado en: Software
  • Sé el primero en comentar

Отладка и эксплуатация Rails-приложений

  1. 1. ОТЛАДКА И ЭКСПЛУАТАЦИЯ RAILS-ПРИЛОЖЕНИЙ
  2. 2. ОБО МНЕ @goganchic Руководитель направления разработки ruby/erlang/nodejs
  3. 3. СЛОЖНОСТИ ЭКСПЛУАТАЦИИ ОТЛАДКА
  4. 4. СЛОЖНОСТИ ЭКСПЛУАТАЦИИ ОТЛАДКА ВЫСОКИЕ НАГРУЗКИ
  5. 5. СЛОЖНОСТИ ЭКСПЛУАТАЦИИ ОТЛАДКА ВЫСОКИЕ НАГРУЗКИ ПРОФИЛАКТИКА
  6. 6. ОРГАНИЗАЦИОННЫЕ РЕШЕНИЯ
  7. 7. ТЕСТИРОВАНИЕ И КОД-РЕВЬЮ Чем раньше найдена ошибка — тем она дешевле Тесты — для продуманных заранее краевых случаев, код-ревью — для возможно пропущенных Unit-тесты не отменяют приемочных
  8. 8. ЗНАТЬ ИСПОЛЬЗУЕМЫЕ ИНСТРУМЕНТЫ Код библиотек не идеален Разные библиотеки могут конфликтовать друг с другом Лучше не использовать то, что сложно понять
  9. 9. МОНИТОРИНГ Слежение за ресурсами (CPU/RAM/HDD) — Zabbix Внутренние метрики — PulseMeter Слежение за внешними системами (DB, Redis, внешние API) — Zabbix+скрипты
  10. 10. PULSEMETER sensors = PulseMeter::Sensor::Configuration.new( root_webpage_requests_per_5_minutes: { sensor_type: 'timelined/counter', args: {interval: 5.minutes, ttl: 1.week} } ) PulseMeter::Observer.observe_method(HomeController, :index, sensors) do root_webpage_requests_per_5_minutes(1) end
  11. 11. PULSEMETER https://github.com/savonarola/pulse-meter
  12. 12. ОПОВЕЩЕНИЯ Определить, что нормально Выставить триггеры Определить приоритеты оповещений
  13. 13. МОНИТОРЬ ЗАРАНЕЕ
  14. 14. ЛОГИ Processing GET "/requests/10" for 1.1.1.1 Completed 200 OK in 336ms (Views: 0.8ms | ActiveRecord: 12.9ms)
  15. 15. ПОСМОТРЮ-КА Я ТВОИ ЛОГИ
  16. 16. ЛОГИ Processing GET "/requests/10" for 1.1.1.1 Completed 200 OK in 336ms (Views: 0.8ms | ActiveRecord: 12.9ms) Когда был сделан запрос? Как получить все логи по запросу? Были ли запросы во внешние API и если были — то какие ответы были получены? Для какого пользователя запрос?
  17. 17. ЛОГИ [2015-04-18 20:11:39] [7d1fe7a2] [user_id=42] Processing GET "/requests/10" for 1.1.1.1 [2015-04-18 20:11:39] [7d1fe7a2] [user_id=42] PartnerApi request: http://example.com/?param=value [2015-04-18 20:11:39] [7d1fe7a2] [user_id=42] PartnerApi response: 403 Forbidden [2015-04-18 20:11:39] [7d1fe7a2] Completed 200 OK in 336ms (Views: 0.8ms | ActiveRecord: 12.9ms) + консолидация логов (logstash или скрипты)
  18. 18. АРХИТЕКТУРНЫЕ РЕШЕНИЯ + ПОЛЕЗНЫЕ УТИЛИТЫ
  19. 19. АСИНХРОННОСТЬ def process_request(params) resp = HttpRequest.perform(params_for(request)) data = ResponseParser.parse(resp) DataProcessor.process(data) end requests.each {|r| process_request(r)}
  20. 20. АСИНХРОННОСТЬ — ЗЛО def process_request(request) AsyncHttpRequest.perform(params_for(request)) do |resp| AsyncResponseParser.parse(resp) do |data| AsyncDataProcessor.process(data) end end end requests.each {|r| process_request(r)}
  21. 21. АСИНХРОННОСТЬ — ЗЛО Код менее читаемый Все библиотеки должны знать про асинхронность Все ошибки должны корректно обрабатываться (т.к. общее состояние)
  22. 22. МНОГОПОТОЧНОЕ ПРОГРАММИРОВАНИЕ ТЕОРИЯ РЕАЛЬНОСТЬ
  23. 23. МНОГОПОТОЧНОСТЬ — БОЛЬ Воспроизвести баг — нереально Получить магию — проще простого Чем выше нагрузка — тем хуже магия
  24. 24. SEGMENTATION FAULTS SEGMENTATION FAULTS EVERYWHERE!
  25. 25. БЫСТРЫЕ ТРАНЗАКЦИИ В БД БД — общий ресурс Заблокировал общий ресурс — повесил всю систему
  26. 26. ДЛИТЕЛЬНЫЕ ОПЕРАЦИИ — В ОЧЕРЕДЬ HTTP обработчиков в Rails-проектах обычно мало Заблокировал несколько обработчиков — повесил всю систему
  27. 27. ПЛАВНАЯ ДЕГРАДАЦИЯ — ЭТО ХОРОШО Возможно без некоторых внешних систем сервис может работать
  28. 28. АКТУАЛЬНЫЕ ВЕРСИИ БИБЛИОТЕК Современные системы делают из готовых компонентов Возможно ваши баги уже кто-то поправил bundle outdated в помощь Избегайте пре-альфа версий
  29. 29. АДМИНСКИЕ ШТУЧКИ Если все совсем плохо strace netstat ps htop tcpdump и т.п.
  30. 30. ДЕЙСТВИЯ ПРИ ЧП! НЕ ПАНИКОВАТЬ, НЕ ВЫКАТЫВАТЬ ХАОТИЧЕСКИЕ «ХОТФИКСЫ» СОБРАТЬ КАК МОЖНО БОЛЬШЕ ИНФЫ НЕ СТЕСНЯТЬСЯ СПРАШИВАТЬ ИДЕЙ У КОЛЛЕГ ГУГЛИТЬ ИСКАТЬ И ИСПРАВЛЯТЬ ПРИЧИНУ, А НЕ СЛЕДСТВИЕ
  31. 31. ПРИМЕР ИЗ ЖИЗНИ
  32. 32. ПРОБЛЕМЫ С ОДНИМ ГЕО-СЕРВИСОМ Проекту около 5 лет Нагрузка средняя Есть внешние API
  33. 33. ПРОБЛЕМЫ С ОДНИМ ГЕО-СЕРВИСОМ Ruby 2.1 Rails 4.1 Unicorn PostgreSQL PostGIS Resque заменили на Sidekiq — начались проблемы
  34. 34. ЧТО СЛУЧИЛОСЬ? RGeo::Error::ParseError: Not enough bytes left to fulfill 1 byte Для пользователя некоторые запросы не обрабатывались, частично функционал не был досутпен.
  35. 35. АНАЛИЗ СИТУАЦИИ Код не менялся Стектрейс ведет в lib/coords.rb @@parser = RGeo::WKRep::WKBParser.new def coords @@parser.parse(geo_coords) end
  36. 36. РЕЗУЛЬТАТ АНАЛИЗА: ОДИН WKBPARSER НА ВСЕ ПОТОКИ WKBParser не является потокобезопасным Активно используются instance-переменные
  37. 37. ЕЩЕ ПРИМЕР
  38. 38. ЧТО СЛУЧИЛОСЬ? 502 на все запросы
  39. 39. АНАЛИЗ СИТУАЦИИ Процессы работают CPU — ОК RAM — ОК Сеть — ОК В логах пусто — кого-то ждем
  40. 40. ПРОБЛЕМА 1 Причина: strace — подвисли на запросе к API без API можно обработать 85% запросов Решение: мониторим состояние API и если все плохо — просто не делаем запросов
  41. 41. ЕЩЕ ПРИМЕР
  42. 42. ЧТО СЛУЧИЛОСЬ? 502 на все запросы Для пользователя тоже самое
  43. 43. АНАЛИЗ СИТУАЦИИ В логах — началась обработка запроса и висит
  44. 44. ПРОБЛЕМА 2 Причина: Длинные транзакции в sidekiq воркерах Превышение лимита одновременных транзакций Решение: Делаем в транзакции только самое необходимое, остальное — вне транзакции.
  45. 45. ЕЩЕ ПРИМЕР
  46. 46. ЧТО СЛУЧИЛОСЬ? 502 на все запросы
  47. 47. АНАЛИЗ СИТУАЦИИ CPU — ОК RAM — ОК Сеть — ОК В логах — пусто. Воспроизводится не регулярно
  48. 48. АДМИНЫ БД ГОВОРЯТ — ПРОБЛЕМА 2 ТВОЙ СОФТ — ГОВНО!
  49. 49. АНАЛИЗ СИТУАЦИИ def fill_location(loc) if loc self.coords_source = loc.source self.coords = loc.coords fill_address_if_required end self.state = 'processed' save! # ← зависает тут end
  50. 50. АНАЛИЗ СИТУАЦИИ BEGIN TRANSACTION; UPDATE ...; COMMIT;
  51. 51. Я ТЕБЕ НЕ ВЕРЮ!
  52. 52. PFF…
  53. 53. ПРОБЛЕМА 3 pg 0.14.1 (2012 год)
  54. 54. ПРОБЛЕМА 3 Зависание — в нативном расширении. Обновление гема pg спасло мир!
  55. 55. ВЫВОД Отладка - набор эвристик + метод научного тыка. Чем лучше эвристики, тем выше вероятность того, что проблема будет решена быстро.
  56. 56. ВОПРОСЫ?

×