5 razones por las que New Relic es el mejor amigo de un desarrollador

Una vez que comience a indagar en New Relic, comenzará a darse cuenta de la cantidad de características interesantes que tiene el servicio para ayudar a monitorear el rendimiento y el estado de su aplicación. Fue realmente difícil elegir solo cinco cosas de las que hablar, así que en lugar de centrarse en las características obvias, echemos un vistazo a algunas de las funciones menos publicitadas que ofrece New Relic y cómo podemos usarlas de manera interesante y, a veces, poco ortodoxa..

Cuando te dejamos la última vez, teníamos una aplicación básica de 'Hello World' Rails (llamada New Relic_rails1, viviendo en ~ / project / tmp / New Relic). Continuaremos usando esta aplicación, la extenderemos y veremos si podemos usarla para demostrar las características de New Relic que veremos.

Contenido Patrocinado

Este contenido fue encargado por New Relic y fue escrito y / o editado por el equipo de Tuts +. Nuestro objetivo con el contenido patrocinado es publicar tutoriales relevantes y objetivos, estudios de casos y entrevistas inspiradoras que ofrezcan un valor educativo genuino a nuestros lectores y nos permitan financiar la creación de contenido más útil..


Monitoreo de disponibilidad

Esta es una característica de New Relic que normalmente no aparece en la portada del material de marketing. No hay mucho que hacer, pero si lo piensa, lo más importante es asegurarse de que su aplicación esté en funcionamiento y sea accesible para sus usuarios.?

En primer lugar, cuando configura la supervisión de disponibilidad, su aplicación obtiene un bonito asterisco en el panel principal de sus aplicaciones:


Es un buen recordatorio visual, para que pueda ver qué aplicaciones aún necesitan la supervisión de disponibilidad activada.

Veamos ahora cómo podemos configurar el monitoreo de disponibilidad y qué podemos obtener de él. En primer lugar, debe saltar a su aplicación y luego ir a Configuración-> Monitoreo de disponibilidad. Verás algo como esto:


Debe proporcionar una URL que desee que New Relic haga ping, marque la casilla, guarde los cambios y estará listo. New Relic comenzará a golpear tu URL cada 30 segundos. Pero la diversión no se detiene ahí. New Relic hará ping a su URL a través de una solicitud HTTP HEAD (y considerará que todo está bien si recibe un código de respuesta 200), pero puede proporcionar una cadena de respuesta que desea que New Relic busque, en cuyo caso realizará una solicitud GET Examine la respuesta de la cadena que proporcionó. Esto puede ser muy útil si tiene una página personalizada de "Comprobación de estado" que desea golpear..

También puede configurar una notificación por correo electrónico si se produce un tiempo de inactividad:


Ahora que está monitoreando la disponibilidad, tendrá acceso a un buen informe que le mostrará visualmente cuándo se ha producido un tiempo de inactividad:


De hecho, muchos de sus gráficos (por ejemplo, el resumen de la aplicación) tendrán esta indicación visual:


Tienes que admitir que es una funcionalidad bastante agradable por tan poco esfuerzo..

Por supuesto, puede deshabilitar y volver a habilitar la supervisión (a través de la API REST de New Relic) cuando realice implementaciones, para asegurarse de que no se produzcan eventos de tiempo de inactividad no deseado..

Otro efecto secundario interesante de esto es que si está implementando su proyecto de mascota en Heroku en un solo dinamómetro, puede usar esta función de ping para evitar que su dinamómetro duerma, lo que puede hacer que su sitio sea extremadamente lento si no tiene mucho tráfico.


Grabación de errores personalizada

Si se producen errores inesperados en su aplicación, New Relic los grabará por usted y le dará un buen gráfico. Nuestra pequeña aplicación 'Hello World' se ha desempeñado admirablemente por el momento, así que no hay nada que podamos ver en ese frente. Pero, a propósito, podemos romper nuestra aplicación y ver qué nos ofrece New Relic.

Modifiquemos nuestro HelloController para elevar un error al azar aproximadamente el 50% del tiempo:

clase HelloController < ApplicationController def index if rand(2) == 0 raise 'Random error' end end end

Ahora haremos unos cientos de llamadas a nuestra aplicación y veremos qué sucede:

ab -n 300 -c 10 http://127.0.0.1:3000/

Nuestro gráfico de error de New Relic ahora parece mucho más interesante:


Y podemos profundizar para obtener algunos detalles:


Como puede ver, podemos ordenar nuestros errores y filtrarlos, así como ver los errores de las solicitudes web y las tareas en segundo plano por separado. Estas son algunas cosas increíblemente poderosas para ayudarlo a diagnosticar y solucionar problemas con su aplicación. Por supuesto, también puede ver el seguimiento de pila para cada error:


Existen servicios específicamente dedicados a capturar errores de su aplicación, algunos de los más conocidos son Airbrake y Bugsnag. Estos son servicios de pago utilizados por muchas aplicaciones, pero la funcionalidad que proporciona New Relic hace que estos servicios sean redundantes. De hecho, si pudiéramos enviar errores personalizados a New Relic (en lugar de dejar que capturen errores que no habíamos rescatado) podríamos presentar un caso convincente para no utilizar un servicio de recopilación de errores por separado (y ahorrar algo de dinero y eliminar un extra). gema en el proceso).

Aunque New Relic no documenta ninguna forma de hacer esto, siempre podemos ir a la fuente para ver si lo que queremos hacer es difícil. Me parece que debería ser bastante trivial para que enviemos errores personalizados a New Relic, así que intentémoslo. Volveremos a modificar la acción de nuestro controlador para rescatar todos los errores y enviar un error personalizado a New Relic:

clase HelloController < ApplicationController def index if rand(2) == 0 raise 'Random error' end rescue New Relic::Agent.notice_error(StandardError.new("I caught and reraised an error")) end end

Después de hacer algunas llamadas y esperar a que lleguen los datos, vemos lo siguiente:


Funcionó, nuestro error personalizado está llegando a través! New Relic definitivamente puede actuar como nuestro servicio de recopilación de errores. Por supuesto, estamos usando una interfaz privada que no es muy agradable, pero podemos poner el notice_error llamar detrás de una fachada que nos facilitará las cosas si la interfaz cambia.

Un enfoque aún mejor podría ser no tratar los errores personalizados como errores regulares, sino crear una métrica personalizada para rastrear y luego construir un tablero personalizado para visualizar. De esta manera, no utilizaremos ninguna funcionalidad no documentada y aún obtendremos todos los beneficios: brillante!


Seguimiento clave de transacciones

New Relic normalmente rastreará sus transacciones por usted:


Podrá ver dónde pasa la aplicación la mayor parte del tiempo (por ejemplo, en el controlador, el modelo, la base de datos, etc.). Sin embargo, New Relic no capturará un seguimiento detallado a menos que la transacción demore más que Appdex * 4 segundos. Normalmente esto está bien, pero en algún momento usted tiene transacciones que son mucho más importantes para su aplicación o para su negocio. Quizás estas transacciones sean de un volumen extremadamente alto o se ocupen de eventos importantes como los pagos. Basta con decir que necesita asegurarse de que este tipo de transacción siempre se desempeña extremadamente bien.

Sin embargo, cuando se trata de una transacción tan importante, es probable que ya hayas recibido mucho amor de ti y que esté funcionando bastante bien. Digamos que tiene una transacción con un rendimiento extremadamente alto (ocurre muchas veces por minuto). Si esta transacción se realiza de manera óptima, todo está bien, pero si el rendimiento se degradara ligeramente, debido al volumen del tráfico, puede tener un efecto perjudicial desproporcionado en su aplicación. Lo que quieres es algo como:

  • un valor Apdex T separado solo para esta transacción
  • la capacidad de recibir alertas cuando el rendimiento de esta transacción se degrada
  • un seguimiento detallado cada vez que esta transacción se realiza de forma ligeramente no óptima

Esto es exactamente lo que las transacciones clave le dan!

Antes de configurar una transacción clave para nuestra aplicación 'Hello World', debemos crear una transacción más interesante que generalmente tendrá un buen desempeño, pero a veces tendrá un mal desempeño. Desarrollaremos la capacidad de observar las marcas y modelos de automóviles y obtener una marca particular de automóviles para ralentizar la transacción. En primer lugar la ruta:

New RelicRails1 :: Application.routes.draw obtiene 'random_car', to: 'cars # show_random' root 'hello # index' end

Queremos poder obtener un automóvil al azar, esto se asignará a la Cochescontrolador:

clase CarsController < ApplicationController def show_random @car = Car.offset(rand(Car.count)).first if @car.make == 'Ford' sleep(2) end end end

Obtenemos un automóvil aleatorio de la base de datos y si el fabricante es 'Ford' tendremos una transacción lenta en nuestras manos. Por supuesto que necesitamos un Coche modelo:

clase de coche < ActiveRecord::Base end

Tendremos que configurar nuestra base de datos para usar MySql en el desarrollo (lo hice, pero puede quedarse con sqlite):

base: & BASE adaptador: mysql2 codificación: utf8 host: "localhost" nombre de usuario: "root" max_connections: 10 timeout: 5000 desarrollo: & DEV <<: *BASE database: "New Relic_rails1_development" sql_log_level: debug

Necesitamos una migración para crear un coches mesa:

carros de clase < ActiveRecord::Migration def change create_table :cars, force: true do |t| t.string :make t.string :model end end end

Y necesitamos algunos datos semilla que pondremos en nuestro db / seeds.rb expediente:

Car.create (marca: 'Ford', modelo: 'Mondeo') Car.create (marca: 'Honda', modelo: 'Accord') Car.create (marca: 'Audi', modelo: 'A4') Car. create (marca: 'Lamborghini', modelo: 'Murcielago') Car.create (marca: 'Toyota', modelo: 'Prius')

Por último, probablemente deberíamos tener una vista coches / show_random.html.erb:

Hacer: <%= @car.make %>

Modelo: <%= @car.model %>

También necesitarás agregar el mysql2 gema para el Gemfile Si has ido con MySql. Después de esto solo necesitamos crear y completar la base de datos, reiniciar nuestro servidor y estamos listos para comenzar:

paquete rake db: create && rake db: migrate && rake db: seed rails s

Tendrá que ir a la URL para asegurarse de que New Relic reconozca que existe esta transacción:

curl localhost: 3000 / random_car

Ahora estamos listos para monitorear esta transacción como una transacción clave. En primer lugar, saltar a la pestaña de transacción:


Haga clic en el botón 'Rastrear una transacción clave' y elija nuestra transacción recién creada:


Podemos asignar un nombre a nuestra nueva transacción clave, seleccionar el Apdex T con el que estamos contentos y configurar algunas alertas. Cuando nuestra transacción demore más que el Apdex que hemos elegido, New Relic capturará un rastreo detallado que podremos usar para averiguar de dónde proviene el problema de rendimiento. Hagamos algunas llamadas a nuestra nueva URL y veamos qué datos obtenemos:

ab -n 300 -c 20 http://127.0.0.1:3000/random_car

Hmm, parece que algunas de nuestras transacciones están frustrando a nuestros usuarios:


A ver si New Relic ha capturado algunos rastros de transacciones para nosotros:


Echemos un vistazo a uno de estos rastros. Tomó alrededor de 2 segundos responder, pero solo 10 milisegundos estaban usando la CPU:


Todas nuestras declaraciones SQL fueron rápidas, por lo que la base de datos no es el problema:


Parece que la mayor parte del tiempo se pasa en la acción del controlador:


Vamos a profundizar en la traza un poco. Parece que el SQL SELECT fue rápido, un Car.find También fue rápido. Luego perdemos unos 2 segundos, lo que es seguido por un procesamiento de plantillas muy rápido:


New Relic nos ha destacado amablemente dónde perdimos esos dos segundos. Tenemos que mirar nuestro código de controlador después de una Car.find llamada:

clase CarsController < ApplicationController def show_random @car = Car.offset(rand(Car.count)).first if @car.make == 'Ford' sleep(2) end end end

Hmm, el SELECT inicial debe ser el Car.count llamar, y el Car.find, debe ser debido a la Coche.offset llamada. Nuestro gran retraso es justo después de esto. Ahh mira esto, una persona tonta ha puesto un retraso de 2 segundos en nuestro código cuando la marca del auto es 'Ford'. Eso explicaría por qué nuestro retraso de 2 segundos ocurre solo parte del tiempo. Mejor hago un git culpa en nuestro repositorio para averiguar quién puso ese horrible código allí! Pensándolo bien, mejor que no, porque podría decir que fui yo.


Servicio externo de grabación de llamadas

Siempre que realice llamadas a otros servicios desde su aplicación (por ejemplo, una solicitud HTTP a una API como Twitter), New Relic los controlará como llamadas externas. En estos días, una aplicación seria puede integrarse con varias API externas. A menudo, estos servicios externos pueden degradar significativamente el rendimiento de su aplicación, especialmente si realiza estas llamadas en proceso. New Relic puede mostrar cuáles de sus llamadas externas son más lentas, a cuáles llama más y cuáles responden más lentamente en promedio. También puede ver el rendimiento de cada uno de los servicios externos que utiliza de forma individual. Hagamos un intento.

Crearemos un servicio externo propio, construyendo una pequeña aplicación de Sinatra. Primero instalamos la gema:

gema instalar sinatra

Crea un nuevo archivo para nuestro servicio:

toque external_service.rb

Y ponga el siguiente código allí:

requiere 'sinatra' get '/ hello' do sleep_time = rand (2000) /1000.0 sleep (sleep_time) "Hola mundo externo # sleep_time!" fin

Este servicio se suspenderá durante un tiempo aleatorio (entre 0 y 2000 milisegundos) y luego devolverá una respuesta de "Hola" con el tiempo que durmió. Ahora todo lo que tenemos que hacer es iniciarlo:

ruby external_service.rb

De vuelta en nuestra aplicación Rails, construiremos un nuevo controlador para llamar a nuestro servicio externo. Usaremos esta ruta:

New RelicRails1 :: Application.routes.draw do ... get 'external_call', to: 'external_calls # external_call' ... end

Nuestro controlador llamará a nuestro servicio Sinatra a través de HTTP:

requiere clase 'net / http' ExternalCallsController < ApplicationController def external_call url = URI.parse('http://localhost:4567/hello') external_request = Net::HTTP::Get.new(url.to_s) external_response = Net::HTTP.start(url.host, url.port) do |http| http.request(external_request) end @result = external_response.body end end

Y necesitamos una vista para mostrar los resultados:

<%= @result %>

Todo lo que tenemos que hacer ahora es hacer algunas llamadas a nuestro nuevo punto final:

ab -n 100 -c 10 http://127.0.0.1:3000/external_call

Vamos a ver lo que New Relic ha producido para nosotros..


New Relic ha recogido nuestra nueva llamada externa. Tenemos el total de llamadas por minuto que hacemos al punto final externo. Y el total que se gastó respondiendo por el servicio externo. Por supuesto, nuestro gráfico parece un poco escaso ya que solo tenemos un servicio externo, lo que significa que no tenemos nada con lo que comparar.

También podemos obtener datos más detallados sobre la llamada externa específica, así como también desde dónde se realiza esta llamada desde nuestra aplicación:


Podemos ver cuándo se hicieron las llamadas, el rendimiento y el tiempo de respuesta promedio. Esto puede parecer simple, pero cuando tiene una aplicación con una gran cantidad de servicios externos, esta característica puede brindarle una buena descripción general del rendimiento de estos servicios externos, así como cuándo y dónde se están utilizando. Esto puede permitirle tomar decisiones sobre el almacenamiento en caché de ciertas respuestas de servicios externos, si es posible, o incluso descartar servicios externos particulares si su desempeño no está a la altura. Y ya no tiene que argumentar estas cosas basándose en mates y en métricas caseras, tendrá datos concretos para demostrar su punto..

Análisis de capacidad y escalabilidad

No hay nada más frustrante para un desarrollador que hacer que su aplicación se caiga debido a un aumento en el tráfico. Todo funcionó sin problemas hasta que llegaron esos cientos de usuarios adicionales y su aplicación explotó. Tenía la sensación de que esto podría suceder, pero no estaba seguro: la actitud de esperar y ver parecía ser el enfoque más pragmático. Bueno, con los informes de capacidad y escalabilidad de New Relic, ya no tiene que "esperar y ver". Puede saber de inmediato qué tan bien está escalando su aplicación, puede hacer pruebas de carga y ver instantáneamente si su aplicación puede manejar la carga. Puede observar las tendencias de tiempo de respuesta de su aplicación a medida que su base de usuarios crece y predecir cuándo necesitará agregar capacidad. Todas esas son cosas verdaderamente maravillosas..

Primero, veamos los informes de capacidad:


Hmm, este muestra un gran pico, pero por lo demás nada. Bueno, estamos corriendo en modo de desarrollo, por lo que esto es comprensible. Ese pico es para cuando hicimos un montón de solicitudes simultáneamente hace un rato. Como puede ver cuando hicimos esas solicitudes concurrentes, maximizamos nuestra pobre y solitaria instancia de Webrick. Si esto fuera producción y esa carga fuera constante, nuestra instancia siempre estaría 100% ocupada, lo que probablemente indicaría que necesitamos otra instancia.

El informe de análisis de instancia es ligeramente diferente:


En nuestro caso, no obtenemos mucho de eso, pero normalmente nos muestra la cantidad de instancias que se están ejecutando y la cantidad de instancias que realmente necesitamos para manejar la carga si todas las instancias estaban 100% ocupadas. Entonces, si estuviéramos ejecutando 10 instancias y la carga de instancias concurrentes fuera 2, podríamos reducir a la mitad (o incluso más de la mitad) el número de instancias en ejecución y no degradar el rendimiento en absoluto. Para una aplicación pequeña que ejecuta solo unas pocas instancias, esto no es un gran problema, pero para una aplicación grande con docenas y cientos de instancias, esto puede traducirse en ahorros significativos de costos.

Y luego están los informes de escalabilidad. El informe de tiempo de respuesta es probablemente el más interesante / importante:


Una vez más, nuestro gráfico está muy distorsionado porque es una aplicación de desarrollo que hemos estado jugando de forma aleatoria. La idea con este informe es que a medida que aumenta el rendimiento de su aplicación (más solicitudes por minuto), el tiempo de respuesta debe permanecer casi constante (es decir, el rendimiento no se degrada cuando hay más tráfico). Esto significa que siempre deberías estar viendo algo parecido a una línea plana aquí. Si su línea se inclina hacia arriba significativamente, es probable que su aplicación tenga dificultades para manejar el tráfico y es posible que deba agregar más capacidad. Donde agregar capacidad es otra pregunta completamente (por ejemplo, capacidad de base de datos, más servidores, etc.). Los otros dos informes de escalabilidad pueden ayudarlo a responderla. Ahí está el informe de la base de datos:


No puede esperar que su base de datos no se vea afectada por una mayor carga, por lo que lo que debería estar viendo aquí es una línea que aumenta lentamente a medida que aumenta el rendimiento de su aplicación. Depende de usted cuando el tiempo de respuesta de la base de datos se considere inaceptable (es decir, afecta demasiado la respuesta de la aplicación), pero cuando decide que las respuestas de la base de datos son demasiado lentas, sabe que es hora de agregar capacidad a la base de datos. El otro informe es la CPU:


Una vez más, realmente no puede esperar que un mayor rendimiento no afecte la carga de la CPU, debería ver una línea que aumenta lentamente con un mayor rendimiento. Esto, junto con los informes de capacidad de los que hablamos anteriormente, le permiten decidir cuándo agregar más procesos / servidores de Rails para garantizar que su rendimiento se mantenga decente..


Conclusión

Si una o todas esas características han levantado una ceja (o dos) para usted, la buena noticia es que solo hemos arañado la superficie. Cada una de esas características más que merece un artículo en profundidad propio. Sin embargo, New Relic también tiene una serie de otras características que son potencialmente aún más potentes, entre las que se incluyen Monitoreo de usuario real, La plataforma de New Relic, Perfil de subprocesos, Umbrales de alerta y notificaciones, y muchas otras. Trataremos de cubrir algunos o quizás todos estos en tutoriales posteriores..

Por ahora, intente New Relic Out, implemente un agente en su idioma favorito y vea si puede descubrir una forma inmediata de usar algunas de las funciones que proporciona New Relic. Y si tiene algunas formas innovadoras de usar New Relic, asegúrese de avisar a todos dejando un comentario..