Основы мониторинга приложений Rails для достижения лучших результатов.

Как инженеры, успешный запуск программного обеспечения в производство со всеми ожидаемыми вариантами использования, несомненно, является полезным. Однако это достижение не означает конец нашей ответственности.

Обеспечение удовлетворенности клиентов и поддержание качества продукта требует непрерывной обратной связи, регулярных обновлений и иногда выпуска исправлений.

По сути, мы пытаемся получить больше информации о коде, который мы только что развернули, чтобы поддерживать потребности бизнеса в долгосрочной перспективе. Следовательно, мониторинг производительности приложений становится критически важным в жизненном цикле разработки программного обеспечения.

Он включает в себя использование различных инструментов и библиотек для выявления узких мест, оптимизации кода и увеличения задержки запросов к серверу. Мы рассмотрим некоторые из этих инструментов, которые помогут поддерживать стандарты производительности по мере создания дополнительных функций в приложении Rails.

Ориентир

Гем benchmark является частью стандартной библиотеки Ruby, универсальным инструментом, который измеряет время, необходимое для точного выполнения определенных блоков кода или методов. Он предлагает точные показатели производительности, оценивая время ЦП, системное время и реальное время, потребляемое во время выполнения. Его можно использовать для выявления узких мест в вашем приложении и принятия обоснованных решений по оптимизации.

Используйте его для сравнения различных реализаций, чтобы определить, какая из них работает лучше. Это особенно полезно, когда вы хотите оптимизировать определенный метод или часть кода, которые, как вы подозреваете, вызывают проблемы с производительностью.

Benchmark.measureпозволяет нам измерить время, затрачиваемое на одну итерацию блока кода или метода.

require 'benchmark'

def first_method
  sleep(2)
end

def second_method
  sleep(1)
end

t1 = Benchmark.measure { first_method }
t2 = Benchmark.measure { second_method }

# t1 => #<Benchmark::Tms:0x00007fe746956b88 @label="", @real=2.0007329992949963, @stime=0.00018400000000001748, @utime=6.1000000000005494e-05, @total=0.000245000000000023>
# t2 => #<Benchmark::Tms:0x00007fe7468ae910 @label="", @real=1.000093000009656, @stime=3.700000000000925e-05, @utime=3.0000000000002247e-05, @total=6.70000000000115e-05>

Класс Benchmark::Tms представляет собой набор измерений, выполненных эталонным тестом.

  • real: время выполнения блока кода или метода в режиме реального времени.
  • utime: время ЦП, затраченное на выполнение блока кода или метода в пользовательском режиме.
  • stime: время ЦП, затраченное на выполнение блока кода или метода в режиме ядра.
  • total: сумма utime и stime, представляющая общее время процессора.

Значения атрибутов зависят от среды, в которой выполняется код, включая оборудование и операционную систему. В результате точные значения могут различаться на разных машинах.

Модуль Benchmark предоставляет метод bm, который выполняет несколько итераций блока кода и измеряет среднее время, необходимое для выполнения блока.

require 'benchmark'

array = (1..100000).to_a

Benchmark.bm do |x|
  x.report("Array Join") do
    array.join(',')
  end

  x.report("Array Manual Join") do
    str = ""
    array.each do |num|
      str += num.to_s + ','
    end
  end
end

#                    user       system     total     real
# Array Join         0.035221   0.000162   0.035383  (0.035416)
# Array Manual Join  6.331210   7.445371   13.776581 (13.785126)

Как видно выше, он часто используется для сравнения производительности различных реализаций или алгоритмов. Сгенерированные показатели аналогичны measure.

Жемчужиной, расширяющей возможности теста, является benchmark-ips. Он используется для подсчета нет. итераций в секунду для данного фрагмента кода.

«оценивает количество итераций блоков в секунду. Для коротких фрагментов кода ips автоматически определяет, сколько раз нужно запустить код, чтобы получить интересные данные», — цитируется на домашней странице драгоценного камня.

Используя эталонный тест, вы можете получить всестороннее представление о производительности вашего приложения и принимать решения, основанные на данных, для ее улучшения.

Пуля

Gem bullet помогает разработчикам идентифицировать и предотвращать запросы N+1.

Запрос N+1 происходит, когда приложение запрашивает базу данных для набора записей, а затем выдает дополнительные запросы для извлечения связанных записей для каждого элемента в наборе. Это может вызвать чрезмерное количество запросов к базе данных и привести к значительным проблемам с производительностью, особенно при работе с большими наборами данных.

Этот драгоценный камень постоянно отслеживает ваше приложение Rails во время работы в режиме разработки и обнаруживает N+1 проблемы с запросами в режиме реального времени. Когда он обнаруживает потенциальную проблему, он регистрирует предупреждающее сообщение в консоли сервера Rails.

# development.rb
config.after_initialize do
  Bullet.enable = true
  Bullet.bullet_logger = true
end

# GET /stories/ USE eager loading detected 
#   Story => [:publication] 
#   Add to your query: .includes([:publication]) 
# Call stack

Конфигурация предписывает Bullet отслеживать ваше приложение при инициализации и регистрировать любые обнаруженные проблемы. Когда вы запускаете приложение Rails в режиме разработки и выполняете действия, запускающие запросы к базе данных, bullet будет отслеживать выполняемые запросы и выдавать предупреждения, если будет обнаружено N+1 запросов.

Например, если у вас есть модель с именем Story, у которой есть один Publication, попытка загрузить все истории в продукте и запрос публикации для каждой из извлеченных историй вызовет указанное выше предупреждение. Он предлагает активную загрузку публикации, чтобы можно было избежать N+1 запросов на публикацию.

Некоторые из общих опций, поддерживаемых драгоценным камнем:

  • Bullet.rails_logger: добавить предупреждения в журнал Rails.
  • Bullet.alert: всплывающее предупреждение в браузере.
  • Bullet.bullet_logger: войти в лог-файл Bullet.
  • Bullet.raise: вызывать ошибки, чтобы ваши спецификации не сработали.

RackMiniProfiler

rack-mini-profiler — это инструмент профилирования для стоечных приложений. Это помогает разработчикам выявлять и оптимизировать узкие места в производительности, предоставляя информацию о различных аспектах производительности приложений в режиме реального времени.

Гемы действуют как промежуточное ПО, которое можно легко интегрировать в ваше приложение Rails. Он охватывает каждый цикл запроса/ответа, позволяя измерять показатели производительности для каждого запроса.

«Промежуточное ПО, отображающее значок скорости для каждой HTML-страницы, а также (необязательно) пламенные графики и профилирование памяти. Предназначен для работы как в производстве, так и в разработке», как описано в драгоценном камне.

Rack Mini Profiler добавляет небольшой виджет вверху страницы. Этот виджет предоставляет данные о производительности текущего запроса в режиме реального времени, в том числе:

  • Время загрузки страницы: время, необходимое для загрузки страницы.
  • Запросы к базе данных: количество SQL-запросов, выполненных для запроса, а также время, затраченное на каждый запрос.
  • Время рендеринга представления: время, затраченное на рендеринг шаблона представления.
  • Использование памяти и время сборки мусора: время, затраченное сборкой мусора во время запроса. Он использует драгоценный камень memory-profiler.
  • Счетчик запросов: количество запросов к серверу для текущей загрузки страницы.

Он позволяет создавать профили для конкретных запросов и просматривать подробный отчет, включающий графики пламени и трассировку стека. Эти отчеты помогают определить стек вызовов и понять, какие части вашего кода больше всего влияют на время обработки запросов.

Этот драгоценный камень существует уже некоторое время и лучше подходит для приложений Rails, использующих его представления. Если вы ищете аналогичный профайлер для запросов API, посмотритеrails-mini-profiler.

По мере роста и сложности приложений обеспечение оптимальной производительности становится важным. Множество драгоценных камней предоставляют информацию о поведении приложений, узких местах и ​​использовании ресурсов в режиме реального времени.

Более надежные решения APM, такие как New Relic, Skylight и AppSignal, поддерживают более широкие функциональные возможности и поставляются с платными версиями для корпоративных приложений.

Инвестируя в мониторинг, разработчики могут создавать высокопроизводительные приложения, обеспечивающие исключительный пользовательский опыт.