Úvod do servera Netflix Servo

1. Prehľad

Netflix Servo je metrický nástroj pre Java aplikácie. Servo je podobné ako Dropwizard Metrics, ale oveľa jednoduchšie. Využíva JMX iba na poskytnutie jednoduchého rozhrania na zverejnenie a zverejnenie metrík aplikácie.

V tomto článku si predstavíme, čo Servo poskytuje a ako ich môžeme použiť na zhromažďovanie a zverejňovanie metrík aplikácií.

2. Maven závislosti

Predtým, ako sa ponoríme do skutočnej implementácie, pridajme závislosť Servo do pom.xml spis:

 com.netflix.servo servo-jadro 0.12.16 

Okrem toho je k dispozícii veľa rozšírení, napríklad Servo-Apache, Servo-AWS atď. Neskôr ich možno budeme potrebovať. Najnovšie verzie týchto rozšírení nájdete aj na serveri Maven Central.

3. Zhromažďujte metriky

Najprv sa pozrime, ako zhromaždiť metriky z našej aplikácie.

Servo poskytuje štyri primárne metrické typy: Počítadlo, Ukazovateľ, Časovač, a Informačné.

3.1. Metrické typy - Počítadlo

Počítadlá sa používajú na zaznamenávanie prírastkov. Bežne používané implementácie sú BasicCounter, StepCountera PeakRateCounter.

BasicCounter robí to, čo má počítadlo robiť, jednoduché a priame:

Počítadlo počítadla = nový BasicCounter (MonitorConfig.builder ("test"). Build ()); assertEquals ("počítadlo by malo začínať číslom 0", 0, counter.getValue (). intValue ()); counter.increment (); assertEquals ("počítadlo sa malo zvýšiť o 1", 1, counter.getValue (). intValue ()); prírastok počítadla (-1); assertEquals ("počítadlo sa malo znížiť o 1", 0, counter.getValue (). intValue ());

PeakRateCounter vráti maximálny počet pre danú sekundu počas intervalu výziev:

Počítadlo počítadla = nový PeakRateCounter (MonitorConfig.builder ("test"). Build ()); assertEquals ("počítadlo by malo začínať číslom 0", 0, counter.getValue (). intValue ()); counter.increment (); SECONDS.sleep (1); counter.increment (); counter.increment (); assertEquals ("maximálna rýchlosť by mala byť 2", 2, counter.getValue (). intValue ());

Na rozdiel od iných počítadiel, StepCounter rýchlosť záznamu za sekundu predchádzajúceho intervalu výziev:

System.setProperty ("servo.pollers", "1000"); Počítadlo počítadla = nový StepCounter (MonitorConfig.builder ("test"). Build ()); assertEquals ("počítadlo by malo začínať rýchlosťou 0,0", 0,0, counter.getValue ()); counter.increment (); SECONDS.sleep (1); assertEquals ("počítadlo by sa malo zvýšiť na 1,0", 1,0, counter.getValue ());

Všimnite si, že sme nastavili servo.pollers do 1000 v kóde vyššie. To bolo predvolene nastaviť interval dopytovania na 1 sekundu namiesto intervalov 60 sekúnd a 10 sekúnd. O tom sa budeme zaoberať neskôr.

3.2. Metrické typy - Ukazovateľ

Ukazovateľ je jednoduchý monitor, ktorý vracia aktuálnu hodnotu. BasicGauge, MinGauge, MaxGaugea NumberGauges sú k dispozícii.

BasicGauge vyvolá a Vyvolávateľná získať aktuálnu hodnotu. Môžeme získať veľkosť zbierky, najnovšiu hodnotu a BlockingQueue alebo akákoľvek hodnota, ktorá vyžaduje malé výpočty.

Ukazovateľ rozchodu = nový BasicGauge (MonitorConfig.builder ("test") .build (), () -> 2,32); assertEquals (2,32, gauge.getValue (), 0,01);

MaxGauge a MinGauge sa používajú na sledovanie maximálnej a minimálnej hodnoty:

Ukazovateľ MaxGauge = nový MaxGauge (MonitorConfig.builder ("test"). Build ()); assertEquals (0, gauge.getValue (). intValue ()); rozchod.aktualizácia (4); assertEquals (4, gauge.getCurrentValue (0)); rozchod.aktualizácia (1); assertEquals (4, gauge.getCurrentValue (0));

NumberGauge (LongGauge, DoubleGauge) zabalí poskytnuté Číslo (Dlhé, Dvojitý). Ak chcete pomocou týchto meradiel zhromažďovať metriky, musíme zabezpečiť: Číslo je bezpečný pre vlákna.

3.3. Metrické typy - Časovač

Časovače pomôžte zmerať trvanie konkrétnej udalosti. Predvolené implementácie sú BasicTimer, StatsTimera BucketTimer.

BasicTimer zaznamenáva celkový čas, počet a ďalšie jednoduché štatistiky:

Časovač BasicTimer = nový BasicTimer (MonitorConfig.builder ("test"). Build (), SECONDS); Stopky stopky = timer.start (); SECONDS.sleep (1); timer.record (2, SEKUNDY); stopky.stop (); assertEquals ("časovač by mal počítať 1 sekundu", 1, timer.getValue (). intValue ()); assertEquals ("časovač by mal počítať celkovo 3 sekundy", 3.0, timer.getTotalTime (), 0,01); assertEquals ("časovač by mal zaznamenávať 2 aktualizácie", 2, timer.getCount (). intValue ()); assertEquals ("časovač by mal mať max. 2", 2, timer.getMax (), 0,01);

StatsTimer poskytuje oveľa bohatšiu štatistiku vzorkovaním medzi intervalmi výziev:

System.setProperty ("netflix.servo", "1000"); Časovač StatsTimer = nový StatsTimer (MonitorConfig .builder ("test") .build (), nový StatsConfig.Builder () .withComputeFrequencyMillis (2000) .withPercentiles (nový double [] {99.0, 95.0, 90.0}) .withPublishMax (true) .withPublishMin (true) .withPublishCount (true) .withPublishMean (true) .withPublishStdDev (true) .withPublishVariance (true) .build (), SECONDS); Stopky stopky = timer.start (); SECONDS.sleep (1); timer.record (3, SEKUNDY); stopky.stop (); stopky = timer.start (); timer.record (6, SEKUND); SEKUNDY.spánok (2); stopky.stop (); assertEquals ("časovač by mal celkovo počítať 12 sekúnd", 12, timer.getTotalTime ()); assertEquals ("časovač by mal celkovo počítať 12 sekúnd", 12, timer.getTotalMeasurement ()); assertEquals ("časovač by mal zaznamenať 4 aktualizácie", 4, timer.getCount ()); assertEquals ("hodnota štatistického časovača čas-cena / aktualizácia by mala byť 2", 3, timer.getValue (). intValue ()); konečná mapa metricMap = timer.getMonitors (). stream () .collect (toMap (monitor -> getMonitorTagValue (monitor, "štatistika"), monitor -> (číslo) monitor.getValue ())); assertThat (metricMap.keySet (), containsInAnyOrder ("count", "totalTime", "max", "min", "variance", "stdDev", "avg", "percentile_99", "percentile_95", "percentile_90") );

BucketTimer poskytuje spôsob, ako získať distribúciu vzoriek podľa rozsahu hodnôt bucketingu:

Časovač BucketTimer = nový BucketTimer (MonitorConfig .builder ("test") .build (), nový BucketConfig.Builder () .withBuckets (nový dlhý [] {2L, 5L}) .withTimeUnit (SECONDS) .build (), SECONDS) ; záznam časovača (3); záznam časovača (6); assertEquals ("časovač by mal počítať spolu 9 sekúnd", 9, timer.getTotalTime (). intValue ()); Mapa metricMap = timer.getMonitors (). Stream () .filter (monitor -> monitor.getConfig (). GetTags (). ContainsKey ("servo.bucket")) .collect (toMap (m -> getMonitorTagValue (m, ") servo.bucket "), m -> (Long) m.getValue ())); assertThat (metricMap, allOf (hasEntry ("bucket = 2s", 0L), hasEntry ("bucket = 5s", 1L), hasEntry ("bucket = overflow", 1L)));

Na sledovanie dlhodobých operácií, ktoré môžu trvať hodiny, môžeme použiť kompozitný monitor Časovač.

3.4. Metrické typy - Informačné

Môžeme tiež využiť Informačné monitor na zaznamenanie popisných informácií na pomoc pri ladení a diagnostike. Jedinou implementáciou je ZákladnéInformačnéa jeho použitie nemôže byť jednoduchšie:

BasicInformational informational = nový BasicInformational (MonitorConfig.builder ("test"). Build ()); informational.setValue ("zhromaždené informácie");

3.5. MonitorRegistry

Metrické typy sú všetky typu Monitor, ktorý je samotnou základňou Servo. Teraz poznáme druhy nástrojov, ktoré zhromažďujú nespracované metriky, ale na vykazovanie údajov je potrebné tieto monitory zaregistrovať.

Upozorňujeme, že každý jeden nakonfigurovaný monitor by mal byť zaregistrovaný raz a iba raz, aby sa zabezpečila správnosť metrík. Môžeme teda zaregistrovať monitory pomocou Singletonovho vzoru.

Väčšinu času môžeme použiť DefaultMonitorRegistry registrácia monitorov:

Ukazovateľ rozchodu = nový BasicGauge (MonitorConfig.builder ("test") .build (), () -> 2,32); DefaultMonitorRegistry.getInstance (). Register (rozchod);

Ak chceme monitor zaregistrovať dynamicky, DynamicTimera DynamicCounter môže byť použité:

DynamicCounter.increment ("monitor-name", "tag-key", "tag-value");

Upozorňujeme, že dynamická registrácia by pri každej aktualizácii hodnoty spôsobila nákladnú operáciu vyhľadávania.

Servo tiež poskytuje niekoľko pomocných metód na registráciu monitorov deklarovaných v objektoch:

Monitors.registerObject ("testObject", toto); assertTrue (Monitors.isObjectRegistered ("testObject", toto));

Metóda registerObject použije reflexiu na pridanie všetkých inštancií súboru Monitory deklarované anotáciou @Monitor a pridať značky deklarované @MonitorTags:

@Monitor (name = "integerCounter", type = DataSourceType.COUNTER, description = "Celkový počet operácií aktualizácie.") Private AtomicInteger updateCount = nový AtomicInteger (0); @MonitorTags súkromné ​​tagy tagList = nový BasicTagList (newArrayList (nový BasicTag ("tag-key", "tag-value")))); @ Test public void givenAnnotatedMonitor_whenUpdated_thenDataCollected () vyvolá výnimku {System.setProperty ("servo.pollers", "1000"); Monitors.registerObject ("testObject", toto); assertTrue (Monitors.isObjectRegistered ("testObject", toto)); updateCount.incrementAndGet (); updateCount.incrementAndGet (); SECONDS.sleep (1); Zoznam metrics = observer.getObservations (); assertThat (metriky, hasSize (greaterThanOrEqualTo (1))); Iterátor metricIterator = metrics.iterator (); metricIterator.next (); // preskočiť prvé prázdne pozorovanie while (metricIterator.hasNext ()) {assertThat (metricIterator.next (), hasItem (hasProperty ("config", hasProperty ("name", is ("integerCounter"))))); }}

4. Zverejnite metriky

Po zhromaždení metrík ich môžeme publikovať v akomkoľvek formáte, napríklad pri vykresľovaní grafov časových radov na rôznych platformách vizualizácie údajov. Na zverejnenie metrík musíme pravidelne zisťovať údaje z pozorovaní monitora.

4.1. MetricPoller

MetricPoller sa používa ako nástroj na načítanie metrík. Môžeme načítať metriky MonitorRegistries, JVM, JMX. Pomocou rozšírení môžeme dopytovať metriky, ako napríklad stav servera Apache a metriky Tomcat.

Pamäťový pozorovateľ MemoryMetricObserver = nový MemoryMetricObserver (); PollRunnable pollRunnable = nový PollRunnable (nový JvmMetricPoller (), nový BasicMetricFilter (true), pozorovateľ); PollScheduler.getInstance (). Start (); PollScheduler.getInstance (). AddPoller (pollRunnable, 1, SECONDS); SECONDS.sleep (1); PollScheduler.getInstance (). Stop (); Zoznam metrics = observer.getObservations (); assertThat (metriky, hasSize (greaterThanOrEqualTo (1))); Zoznam kľúčov = extractKeys (metriky); assertThat (kľúče, hasItems ("loadedClassCount", "initUsage", "maxUsage", "threadCount"));

Tu sme vytvorili a JvmMetricPoller zisťovať metriky JVM. Pri pridávaní prieskumu do plánovača sme nechali úlohu prieskumu bežať každú sekundu. Predvolené konfigurácie systému poller sú definované v Polleri, ale môžeme určiť pollery, ktoré sa majú použiť s vlastnosťou systému servo.pollers.

4.2. MetricObserver

Pri dopytovaní metrík pozorovania zaregistrovaných MetricObservers bude aktualizovaný.

MetricObservers poskytované v predvolenom nastavení sú MemoryMetricObserver, FileMetricObservera AsyncMetricObserver. Ako sa používa, sme si už ukázali MemoryMetricObserver v predchádzajúcej ukážke kódu.

V súčasnosti je k dispozícii niekoľko užitočných rozšírení:

  • AtlasMetricObserver: zverejnenie metrík na serveri Netflix Atlas s cieľom generovať v pamäti údaje o časových radoch pre analýzu
  • CloudWatchMetricObserver: push metrics to Amazon CloudWatch for metrics monitoring and tracking
  • GraphiteObserver: zverejnenie metrík v Graphite na ukladanie a grafovanie

Môžeme implementovať na mieru MetricObserver zverejňovať metriky aplikácií tam, kde to považujeme za vhodné. Jediná vec, na ktorej vám záleží, je zvládnuť aktualizované metriky:

verejná trieda CustomObserver rozširuje BaseMetricObserver {// ... @Override public void updateImpl (zoznam metrík) {// TODO}}

4.3. Zverejnite na serveri Netflix Atlas

Atlas je ďalší nástroj súvisiaci s metrikami od spoločnosti Netflix. Je to nástroj na správu dimenzionálnych údajov časových radov, čo je ideálne miesto na zverejnenie metrík, ktoré sme zhromaždili.

Teraz si ukážeme, ako zverejniť naše metriky v Netflix Atlas.

Najskôr pripojme servoatlas závislosť od pom.xml:

 com.netflix.servo servoatlas $ {netflix.servo.ver} 0.12.17 

Táto závislosť zahŕňa AtlasMetricObserver aby nám pomohol zverejniť metriky na Atlas.

Potom nastavíme server Atlas:

$ curl -LO '//github.com/Netflix/atlas/releases/download/v1.4.4/atlas-1.4.4-standalone.jar' $ curl -LO '//raw.githubusercontent.com/Netflix/atlas/ v1.4.x / conf / memory.conf '$ java -jar atlas-1.4.4-standalone.jar memory.conf

Aby sme ušetrili čas na test, nastavíme veľkosť kroku na 1 sekundu pamäť.konf, aby sme mohli vygenerovať graf časových radov s dostatkom podrobností o metrikách.

The AtlasMetricObserver vyžaduje jednoduchú konfiguráciu a zoznam značiek. Metriky daných značiek sa presunú do Atlasu:

System.setProperty ("servo.pollers", "1000"); System.setProperty ("servo.atlas.batchSize", "1"); System.setProperty ("servo.atlas.uri", "// localhost: 7101 / api / v1 / publish"); Pozorovateľ AtlasMetricObserver = nový AtlasMetricObserver (nový BasicAtlasConfig (), BasicTagList.of ("servo", "počítadlo")); PollRunnable task = nový PollRunnable (nový MonitorRegistryMetricPoller (), nový BasicMetricFilter (true), pozorovateľ);

Po naštartovaní a PollScheduler s PollRunnable úlohu, môžeme publikovať metriky na Atlas automaticky:

Počítadlo počítadla = nový BasicCounter (MonitorConfig .builder ("test") .withTag ("servo", "counter") .build ()); DefaultMonitorRegistry .getInstance () .register (počítadlo); assertThat (atlasValuesOfTag ("servo"), nie (containsString ("counter"))); pre (int i = 0; i <3; i ++) {counter.increment (RandomUtils.nextInt (10)); SECONDS.sleep (1); counter.increment (-1 * RandomUtils.nextInt (10)); SECONDS.sleep (1); } assertThat (atlasValuesOfTag ("servo"), containsString ("counter"));

Na základe metrík môžeme vygenerovať spojnicový graf pomocou grafického rozhrania API spoločnosti Atlas:

5. Zhrnutie

V tomto článku sme si predstavili, ako používať server Netflix Servo na zhromažďovanie a zverejňovanie metrík aplikácií.

Ak ste si ešte nečítali náš úvod do Metriky Dropwizard, tu si pozrite rýchle porovnanie so serverom Servo.

Celý implementačný kód tohto článku nájdete ako vždy na serveri Github.


$config[zx-auto] not found$config[zx-overlay] not found