Zodra je begint met het graven rond New Relic, begin je je te realiseren hoeveel interessante functies de service heeft om de prestaties en de gezondheid van je applicatie te controleren. Het was echt moeilijk om slechts vijf dingen te noemen, dus in plaats van ons te concentreren op de voor de hand liggende functies, laten we eens kijken naar de minder gehypte functionaliteit die New Relic biedt en hoe we het op interessante en soms onorthodoxe manieren kunnen gebruiken.
Toen we de laatste keer vertrokken, hadden we een eenvoudige 'Hello World' Rails-applicatie (genaamd Nieuwe Relic_rails1
, leven in ~ / project / tmp / Nieuwe relikwie
). We zullen deze app blijven gebruiken, uitbreiden en bekijken of we deze kunnen gebruiken om de functies van New Relic te demonstreren die we zullen bekijken.
Deze inhoud is gemaakt in opdracht van New Relic en is geschreven en / of bewerkt door het Tuts + -team. Ons doel met gesponsorde inhoud is het publiceren van relevante en objectieve zelfstudies, casestudy's en inspirerende interviews die echte educatieve waarde bieden aan onze lezers en ons in staat stellen om het creëren van bruikbare inhoud te financieren..
Dit is een nieuwe relic-functie die meestal niet de voorpagina van het marketingmateriaal vormt. Er is niet veel aan de hand, maar als u erover nadenkt, is het belangrijker dat u ervoor zorgt dat uw app daadwerkelijk actief is en toegankelijk is voor uw gebruikers.?
Ten eerste, wanneer u beschikbaarheidsbewaking instelt, krijgt uw toepassing een mooie asterisk op uw hoofddashboard:
Het is een mooie visuele herinnering, zodat u kunt zien welke apps nog beschikbaarheidscontrole nodig hebben.
Laten we nu kijken naar hoe we beschikbaarheidmonitoring kunnen instellen en wat we eruit kunnen halen. Allereerst moet je in je applicatie springen en er vervolgens in gaan Instellingen-> Beschikbaarheid Monitoring. Je ziet zoiets als dit:
U moet een URL opgeven die u wilt laten pingelen door New Relic, vink het vakje aan, sla uw wijzigingen op en u bent klaar om te gaan. New Relic begint elke 30 seconden met het raken van uw URL. Maar daar houdt het plezier niet op. New Relic pingt uw URL via een HTTP HEAD-verzoek (en vindt alles OK als het een 200-antwoordcode ontvangt), maar u kunt een antwoordreeks opgeven waarnaar u wilt dat New Relic zoekt, in welk geval het een GET-verzoek uitvoert en onderzoek de reactie voor de reeks die u hebt opgegeven. Dit kan erg handig zijn als u een aangepaste 'Health Check' pagina heeft die u wilt slaan.
U kunt ook een e-mailmelding instellen als er downtime optreedt:
Nu u de beschikbaarheid bijhoudt, heeft u toegang tot een mooi rapport dat u visueel laat zien wanneer er een downtime is opgetreden:
Veel van uw diagrammen (bijvoorbeeld het toepassingsoverzicht) hebben deze visuele indicatie:
Je moet toegeven dat het een aardige functionaliteit is voor zo weinig moeite.
U kunt natuurlijk de monitoring (via de New Relic REST API) uitschakelen en opnieuw inschakelen wanneer u implementeert, om ervoor te zorgen dat u geen valse downtime-evenementen krijgt.
Een ander interessant neveneffect hiervan is dat als je je huisdierenproject in een enkele dyno naar Heroku implementeert, je deze ping-functionaliteit kunt gebruiken om te voorkomen dat je dyno slaapt, waardoor je site hinderlijk traag kan worden als je geen last hebt van de dyno veel verkeer.
Als onverwachte fouten in uw toepassing voorkomen, zal New Relic deze voor u opnemen en u een mooie grafiek geven. Onze kleine 'Hello World'-app heeft op dit moment bewonderenswaardig opgetreden, dus er is niets dat we op dat front kunnen zien. Maar we kunnen onze app doelbewust breken en zien wat New Relic ons geeft.
Laten we onze aanpassen HelloController
om willekeurig ongeveer 50% van de tijd een fout te melden:
klas HelloController < ApplicationController def index if rand(2) == 0 raise 'Random error' end end end
We zullen nu een paar honderd keer bellen naar onze app en kijken wat er gebeurt:
ab -n 300 -c 10 http://127.0.0.1:3000/
Onze New Relic-foutgrafiek ziet er nu veel interessanter uit:
En we kunnen inzoomen om een aantal details te krijgen:
Zoals je ziet, kunnen we onze fouten sorteren en filteren, en fouten van webaanvragen en achtergrondtaken apart bekijken. Dit zijn enkele ongelooflijk krachtige dingen om u te helpen bij het diagnosticeren en oplossen van problemen met uw toepassing. U kunt natuurlijk ook het stacktracering voor elke fout bekijken:
Er zijn services die specifiek zijn bedoeld voor het vastleggen van fouten uit uw toepassing, enkele van de meest bekende zijn Airbrake en Bugsnag. Dit zijn betaalde services die door veel applicaties worden gebruikt, maar de functionaliteit die New Relic biedt, maakt deze services overbodig. Als we aangepaste fouten naar New Relic zouden kunnen sturen (in plaats van fouten te maken die we niet hadden gered), zouden we een overtuigend argument kunnen formuleren voor het niet gebruiken van een afzonderlijke foutoplossingsservice (en wat geld besparen en een extra account verwijderen). edelsteen in het proces).
Hoewel New Relic geen enkele manier vastlegt om dit te doen, kunnen we altijd naar de bron gaan om te zien of wat we willen doen, moeilijk is. Volgens mij zou het vrij triviaal moeten zijn om aangepaste fouten naar New Relic te sturen, dus laten we het eens proberen. We zullen onze controlleractie opnieuw aanpassen om alle fouten te herstellen en een aangepaste fout naar New Relic te sturen:
klas 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
Nadat we nog een paar telefoontjes hebben gepleegd en hebben gewacht tot de gegevens zijn doorgekomen, zien we het volgende:
Het werkte, onze aangepaste fout komt eraan! New Relic kan zeker fungeren als onze foutopvangservice. We gebruiken hier natuurlijk een privé-interface die niet erg leuk is, maar we kunnen de notice_error
bel achter een façade die dingen een beetje makkelijker voor ons zal maken als de interface verandert.
Een nog betere aanpak zou kunnen zijn om aangepaste fouten, zoals normale fouten, helemaal niet te behandelen, maar in plaats daarvan een aangepaste statistiek te maken om een aangepast dashboard te visualiseren en vervolgens te visualiseren. Op deze manier gebruiken we geen ongedocumenteerde functionaliteit en zouden toch alle voordelen krijgen - briljant!
New Relic volgt uw transacties normaal gesproken voor u op:
U zult kunnen zien waar uw applicatie het grootste deel van zijn tijd doorbrengt (bijvoorbeeld in de controller, het model, de database, enz.). New Relic zal echter geen gedetailleerd spoor vastleggen tenzij de transactie langer duurt dan Appdex * 4 seconden. Normaal gesproken is dit OK, maar soms heeft u transacties die veel belangrijker zijn voor uw toepassing of voor uw bedrijf. Misschien zijn deze transacties extreem hoog of gaan ze over belangrijke gebeurtenissen zoals betalingen. Het volstaat te zeggen dat u ervoor moet zorgen dat dit type transactie altijd buitengewoon goed presteert.
Het ding is echter, wanneer een transactie zo belangrijk is, heeft het waarschijnlijk al heel veel liefde van je gekregen en kan het redelijk goed presteren. Laten we zeggen dat u een transactie hebt met een extreem hoge doorvoer (komt vele malen per minuut voor). Als deze transactie optimaal presteert, is alles in orde, maar als de prestaties enigszins zouden verslechteren, kan dit, vanwege het verkeersvolume, een onevenredig schadelijk effect hebben op uw toepassing. Wat je wilt is zoiets als:
Dit is precies wat Key Key Transactions u bieden!
Voordat we een sleuteltransactie voor onze 'Hello World'-app opzetten, moeten we een interessantere transactie maken die meestal goed zal presteren, maar soms enigszins slecht presteert. We zullen de mogelijkheid ontwikkelen om naar auto's en modellen te kijken en een bepaald automerk te krijgen om de transactie te vertragen. Eerst de route:
Nieuwe RelicRails1 :: Application.routes.draw krijgt 'random_car', naar: 'cars # show_random' root 'hallo # index' einde
We willen een willekeurige auto kunnen krijgen, deze zal in kaart worden gebracht CarsController
:
klasse CarsController < ApplicationController def show_random @car = Car.offset(rand(Car.count)).first if @car.make == 'Ford' sleep(2) end end end
We krijgen een willekeurige auto uit de database en als de auto 'Ford' is, hebben we een trage transactie. Natuurlijk hebben we een Auto
model:
Klasse Auto < ActiveRecord::Base end
We zullen onze database moeten configureren om MySql in ontwikkeling te gebruiken (ik deed dit, maar je kunt blijven sqlite
):
basis: & BASE adapter: mysql2 codering: utf8 host: "localhost" gebruikersnaam: "root" max_connections: 10 timeout: 5000 ontwikkeling: & DEV <<: *BASE database: "New Relic_rails1_development" sql_log_level: debug
We hebben een migratie nodig om een te maken auto's
tafel:
klasse Cars < ActiveRecord::Migration def change create_table :cars, force: true do |t| t.string :make t.string :model end end end
En we hebben enkele zaadgegevens nodig die we in onze db / seeds.rb
het dossier:
Car.create (merk: 'Ford', model: 'Mondeo') Car.create (merk: 'Honda', model: 'Accord') Car.create (merk: 'Audi', model: 'A4') Auto. maken (merk: 'Lamborghini', model: 'Murcielago') Car.create (merk: 'Toyota', model: 'Prius')
Ten slotte zouden we waarschijnlijk een mening moeten hebben auto's / show_random.html.erb
:
Maken: <%= @car.make %>
Model: <%= @car.model %>
Je moet ook het mysql2
juweel voor de Gemfile
als je met MySql bent gegaan. Hierna hoeven we alleen maar de database aan te maken en te vullen, onze server opnieuw te starten en we zijn klaar om te gaan:
bundel rake db: create && rake db: migrate && rake db: seed-rails s
U moet op de URL klikken om ervoor te zorgen dat New Relic herkent dat deze transactie bestaat:
krul localhost: 3000 / random_car
We zijn nu klaar om deze transactie te volgen als een belangrijke transactie. Ga eerst naar het transactietabblad:
Klik op de knop 'Een transactie bijhouden', en kies onze nieuwe transactie:
We kunnen onze nieuwe sleuteltransactie een naam geven, de Apdex T kiezen waar we blij mee zijn en ook een aantal waarschuwingen instellen. Wanneer onze transactie langer duurt dan de Apdex die we hebben gekozen, zal New Relic een gedetailleerd spoor vastleggen dat we kunnen gebruiken om erachter te komen waar het prestatieprobleem vandaan komt. Laten we een paar keer bellen tegen onze nieuwe URL en zien welke gegevens we krijgen:
ab -n 300 -c 20 http://127.0.0.1:3000/random_car
Hmm, het lijkt erop dat sommige van onze transacties onze gebruikers frustreren:
Laten we kijken of New Relic enkele transactietracks voor ons heeft vastgelegd:
Laten we naar een van deze sporen kijken. Het duurde ongeveer 2 seconden om te antwoorden, maar slechts 10 milliseconden gebruikten de CPU:
Al onze SQL-instructies waren snel, dus database is niet het probleem:
Het lijkt erop dat het grootste deel van de tijd wordt besteed aan de actie van de controller:
Laten we een beetje in het spoor graven. Het lijkt erop dat de SQL SELECT snel was, a Car.find
was ook snel. Dan verliezen we ongeveer 2 seconden wat wordt gevolgd door een aantal zeer snelle sjabloonweergave:
New Relic heeft ons op een vriendelijke manier duidelijk gemaakt waar we die twee seconden verloren zijn. We moeten naar onze controllercode kijken na a Car.find
bellen:
klasse CarsController < ApplicationController def show_random @car = Car.offset(rand(Car.count)).first if @car.make == 'Ford' sleep(2) end end end
Hmm, de eerste SELECT moet de Car.count
bel en de Car.find
, moet het gevolg zijn van de Car.offset
noemen. Onze grote vertraging is echter meteen hierna. Ahh kijk hier eens naar, een dwaze persoon heeft een vertraging van 2 seconden in onze code aangebracht toen het merk van de auto 'Ford' was. Dat zou verklaren waarom onze vertraging van 2 seconden maar een deel van de tijd gebeurt. Ik kan beter a de schuld
in onze repository om erachter te komen wie die vreselijke code erin heeft gestopt! Bij nader inzien, kan ik beter niet, want het zou kunnen zeggen dat ik het was.
Wanneer u vanuit uw app oproepen plaatst naar andere services (bijvoorbeeld een HTTP-verzoek naar een API zoals Twitter), zal New Relic deze als externe oproepen controleren. Tegenwoordig kan een serieuze applicatie worden geïntegreerd met een aantal externe API's. Vaak kunnen deze externe services de prestaties van uw app aanzienlijk verslechteren, vooral als u deze oproepen in werking stelt. New Relic kan laten zien welke van uw externe gesprekken het langzaamst zijn, welke u het meest belt en die gemiddeld het langzaamst reageren. U kunt ook kijken naar de prestaties van elk van de externe services die u afzonderlijk gebruikt. Laten we het proberen.
We zullen een eigen externe service creëren door een kleine Sinatra-app te bouwen. Eerst installeren we de edelsteen:
gem installeer sinatra
Maak een nieuw bestand voor onze service:
raak external_service.rb aan
En plaats de volgende code daarin:
vereisen 'sinatra' krijgen '/ hallo' doen sleep_time = rand (2000) /1000.0 slaap (slaap_tijd) "Hallo externe wereld # sleep_time!" einde
Deze service slaapt gedurende een willekeurige tijd (tussen 0 en 2000 milliseconden) en retourneert vervolgens een 'Hallo'-antwoord met de tijd waarop het geslapen heeft. Nu is alles wat we moeten doen het starten:
ruby external_service.rb
Terug in onze Rails-app zullen we een nieuwe controller bouwen om onze externe service te bellen. We gebruiken deze route:
Nieuwe RelicRails1 :: Application.routes.draw do ... get 'external_call', to: 'external_calls # external_call' ... end
Onze controller zal onze Sinatra-service bellen via HTTP:
vereisen 'net / http' class 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
En we hebben een weergave nodig om de resultaten weer te geven:
<%= @result %>
Het enige dat we nu hoeven te doen, is een paar oproepen te maken naar ons nieuwe eindpunt:
ab -n 100 -c 10 http://127.0.0.1:3000/external_call
Laten we eens kijken wat New Relic voor ons heeft geproduceerd.
New Relic heeft inderdaad onze nieuwe externe oproep opgepikt. We hebben de totale oproepen per minuut die we maken naar het externe eindpunt. En het totaal dat werd uitgegeven door de externe service. Natuurlijk ziet onze grafiek er een beetje schaars uit, omdat we maar één externe dienst hebben, wat betekent dat we niets hebben om mee te vergelijken.
We kunnen ook meer gedetailleerde gegevens krijgen over de specifieke externe oproep en ook waar in onze app deze oproep vandaan komt:
We kunnen zien wanneer de oproepen werden gedaan, de doorvoer en de gemiddelde responstijd. Dit lijkt misschien eenvoudig, maar als je een app hebt met veel externe services, kan deze functie je een heel mooi overzicht geven van hoe deze externe services presteren, en ook wanneer en waar ze worden gebruikt. Dit kan u toestaan om beslissingen te nemen over het cachen van bepaalde externe servicereacties, indien mogelijk, of zelfs bepaalde externe services te laten vallen als hun prestaties niet goed zijn. En je hoeft deze dingen niet langer te betwisten op basis van gevoel van thuisgevoel en zelfgemaakte statistieken, je zult harde gegevens hebben om je punt te bewijzen.
Er is niets frustrerender voor een ontwikkelaar dan dat uw toepassing omvalt als gevolg van een verkeerspiek. Alles liep soepel tot die extra paar honderd gebruikers langs kwamen en je applicatie explodeerde. Je had het gevoel dat dit kon gebeuren, maar wist het niet zeker - de afwachtende houding leek de meest pragmatische aanpak. Met de nieuwe Relic-capaciteits- en schaalbaarheidsrapporten hoeft u niet langer af te wachten. U kunt meteen zien hoe goed uw app is geschaald, u kunt tests uitvoeren en meteen zien of uw toepassing de belasting aankan. U kunt de trends in de reactietijd van toepassingen bekijken terwijl uw gebruikersbestand groeit en voorspellen wanneer u capaciteit moet toevoegen. Dit zijn allemaal fantastische dingen.
Laten we eerst kijken naar de capaciteitsrapporten:
Hmm, deze toont een grote piek, maar verder niets. Nou, we draaien in de ontwikkelmodus, dus dit is begrijpelijk. Die piek is voor als we een hoop verzoeken tegelijkertijd kort geleden deden. Zoals je kunt zien toen we die gelijktijdige aanvragen deden, hebben we onze arme, eenzame Webrick-instantie bereikt. Als dit productie was en die belasting constant was, dan was ons exemplaar altijd 100% bezig, wat waarschijnlijk zou betekenen dat we nog een instantie nodig hebben.
Het voorbeeldanalyseverslag is iets anders:
In ons geval halen we er niet veel uit, maar laten we meestal het aantal instanties zien dat wordt uitgevoerd en het aantal exemplaren dat we eigenlijk moeten afhandelen als alle exemplaren 100% bezet zijn. Dus als we 10 exemplaren zouden draaien en de concurrente instance-belasting 2 was, zouden we het aantal actieve exemplaren gemakkelijk kunnen halveren (of zelfs meer dan halveren) en de prestaties helemaal niet verminderen. Voor een kleine app die maar een paar keer wordt uitgevoerd, is dit geen groot probleem, maar voor een grote applicatie met tientallen en honderden exemplaren kan dit zich vertalen in aanzienlijke kostenbesparingen.
En dan zijn er de schaalbaarheidsrapporten. Het antwoord op de responstijd is waarschijnlijk de meest interessante / belangrijke:
Nogmaals, onze grafiek is erg vervormd, omdat het een ontwikkelings-app is waar we willekeurig mee hebben gespeeld. Het idee met dit rapport is dat naarmate de verwerkingscapaciteit voor uw toepassing toeneemt (meer verzoeken per minuut), de responstijd dicht bij constant moet blijven (dat wil zeggen dat de prestaties niet afnemen wanneer er meer verkeer is). Dit betekent dat je hier altijd iets moet zien dat op een platte lijn lijkt. Als uw lijn aanzienlijk schuin omhoog loopt, heeft uw app waarschijnlijk moeite om het verkeer af te handelen en moet u wellicht meer capaciteit toevoegen. Waar capaciteit kan worden toegevoegd is een andere vraag (bijvoorbeeld databasecapaciteit, meer servers, etc.). De andere twee schaalbaarheidsrapporten kunnen u helpen het te beantwoorden. Er is het databaserapport:
Je kunt niet verwachten dat je database niet wordt beïnvloed door hogere belasting, dus wat je hier zou moeten zien is een lijn die langzaam omhoog gaat naarmate de doorvoer van je applicatie toeneemt. Het is aan u wanneer de responstijd van de database onaanvaardbaar wordt geacht (d.w.z. de reactie van de toepassing te veel beïnvloedt), maar als u besluit dat de antwoorden in de database te traag zijn, weet u dat het tijd is om databasecapaciteit toe te voegen. Het andere rapport is de CPU:
Nogmaals, je kunt niet echt verwachten dat een hogere doorvoer je CPU-belasting niet beïnvloedt, je zou een lijn moeten zien die langzaam stijgt met een hogere doorvoer. Dit, samen met de capaciteitsrapporten waar we eerder over gesproken hebben, kan u toestaan om te beslissen wanneer u meer Rails-processen / -servers wilt toevoegen om ervoor te zorgen dat uw prestaties fatsoenlijk blijven.
Als één of al deze kenmerken een wenkbrauw (of twee) voor je hebben opgeworpen, is het goede nieuws dat we nog maar net de oppervlakte hebben bekrast. Elk van die kenmerken verdient meer dan een diepgaand eigen artikel. Maar New Relic heeft ook een aantal andere functies die mogelijk nog krachtiger zijn, zoals Real User Monitoring, The New Relic Platform, The Thread Profiler, Alert Thresholds and Notification en vele anderen. We zullen proberen sommige of misschien zelfs allemaal in latere tutorials te bespreken.
Probeer nu New Relic uit, implementeer een agent in je favoriete taal en kijk of je een kant-en-klare manier kunt vinden om een deel van de functionaliteit te gebruiken die New Relic biedt. En als u een aantal innovatieve manieren hebt om New Relic te gebruiken, moet u iedereen hiervan op de hoogte stellen door een opmerking achter te laten.