Bevezetés a Netflix Servo-ba

1. Áttekintés

A Netflix Servo egy metrika eszköz a Java alkalmazásokhoz. A Servo hasonlít a Dropwizard Metrics-hoz, mégis sokkal egyszerűbb. Csak a JMX-et használja fel, hogy egyszerű felületet biztosítson az alkalmazás metrikáinak feltárásához és közzétételéhez.

Ebben a cikkben bemutatjuk, hogy a Servo mit nyújt, és hogyan használhatjuk fel az alkalmazások mutatóinak gyűjtésére és közzétételére.

2. Maven-függőségek

Mielőtt belevetnénk magunkat a tényleges megvalósításba, adjuk hozzá a Servo függőséget a pom.xml fájl:

 com.netflix.servo szervo-mag 0.12.16 

Ezenkívül sokféle kiterjesztés érhető el, például Servo-Apache, Servo-AWS stb. Később szükség lehet rájuk. Ezeknek a bővítményeknek a legújabb verziói megtalálhatók a Maven Central oldalán is.

3. Gyűjtse össze a mutatókat

Először nézzük meg, hogyan gyűjthetünk mutatókat az alkalmazásunkból.

A szervo négy elsődleges mutatótípust kínál: Számláló, Nyomtáv, Időzítő, és Információs.

3.1. Metrikus típusok - Számláló

Pultok az inkrementáció rögzítésére szolgálnak. A leggyakrabban használt megvalósítások BasicCounter, StepCounter, és PeakRateCounter.

BasicCounter azt teszi, amit a számlálónak meg kell tennie, egyszerűen és egyszerűen:

Számláló számláló = new BasicCounter (MonitorConfig.builder ("teszt"). Build ()); assertEquals ("a számlálónak 0-val kell kezdődnie", 0, counter.getValue (). intValue ()); számláló.növekedés (); assertEquals ("a számlálónak 1-gyel kellett volna növekednie", 1, counter.getValue (). intValue ()); számlálónövekedés (-1); assertEquals ("a számlálónak 1-gyel csökkentenie kellett volna", 0, counter.getValue (). intValue ());

PeakRateCounter az adott másodperc maximális számát adja vissza a lekérdezési intervallum alatt:

Számlálószámláló = új PeakRateCounter (MonitorConfig.builder ("teszt"). Build ()); assertEquals ("a számlálónak 0-val kell kezdődnie", 0, counter.getValue (). intValue ()); számláló.növekedés (); MÁSODIK. Alszik (1); számláló.növekedés (); számláló.növekedés (); assertEquals ("a csúcsaránynak 2-nek kell lennie", 2, counter.getValue (). intValue ());

Más pultokkal ellentétben StepCounter rögzíti az előző szavazási intervallum másodpercenkénti sebességét:

System.setProperty ("szervo.pollers", "1000"); Számláló számláló = new StepCounter (MonitorConfig.builder ("teszt"). Build ()); assertEquals ("a számlálónak 0,0-as sebességgel kell kezdődnie, 0,0, számláló.getValue ()); számláló.növekedés (); MÁSODIK. Alszik (1); assertEquals ("az ellenértéknek 1.0-ra kellett volna növekednie", 1.0, counter.getValue ());

Figyeljük meg, hogy beállítottuk a szervo.pollerek nak nek 1000 a fenti kódban. Ez azt jelentette, hogy a lekérdezési intervallumot alapértelmezés szerint 60 másodperc és 10 másodperc helyett 1 másodpercre kell állítani. Később erről bővebben kitérünk.

3.2. Metrikus típusok - Nyomtáv

Nyomtáv egy egyszerű monitor, amely visszaadja az aktuális értéket. BasicGauge, MinGauge, MaxGauge, és Számmérők biztosítják.

BasicGauge meghívja a Hívható hogy megkapja az aktuális értéket. Megkaphatjuk a gyűjtemény méretét, a legújabb értékét BlockingQueue vagy bármilyen kis számítást igénylő érték.

Gauge gauge = new BasicGauge (MonitorConfig.builder ("teszt") .build (), () -> 2.32); assertEquals (2,32, gauge.getValue (), 0,01);

MaxGauge és MinGauge a maximális és a minimális értékek nyomon követésére szolgálnak:

MaxGauge nyomtáv = új MaxGauge (MonitorConfig.builder ("teszt"). Build ()); assertEquals (0, gauge.getValue (). intValue ()); gauge.update (4); assertEquals (4, gauge.getCurrentValue (0)); gauge.update (1); assertEquals (4, gauge.getCurrentValue (0));

NumberGauge (LongGauge, DoubleGauge) csomagol egy feltettet Szám (Hosszú, Kettős). Ahhoz, hogy a mérőszámokat ezen mérők segítségével gyűjtsük össze, biztosítanunk kell a Szám menetbiztos.

3.3. Metrikus típusok - Időzítő

Időzítők segíthet mérni egy adott esemény időtartamát. Az alapértelmezett megvalósítások BasicTimer, StatsTimer, és BucketTimer.

BasicTimer rögzíti a teljes időt, a számlálást és más egyszerű statisztikákat:

BasicTimer időzítő = új BasicTimer (MonitorConfig.builder ("teszt"). Build (), SECONDS); Stopper stopper = timer.start (); MÁSODIK. Alszik (1); időzítő.rekord (2, SECONDS); stopper.stop (); assertEquals ("az időzítőnek 1 másodpercet kell számítania", 1, timer.getValue (). intValue ()); assertEquals ("az időzítőnek összesen 3 másodpercet kell számlálnia", 3,0, timer.getTotalTime (), 0,01); assertEquals ("az időzítőnek 2 frissítést kell rögzítenie", 2, timer.getCount (). intValue ()); assertEquals ("az időzítőnek max 2-nek kell lennie", 2, timer.getMax (), 0,01);

StatsTimer sokkal gazdagabb statisztikákat nyújt a szavazási intervallumok közötti mintavétellel:

System.setProperty ("netflix.servo", "1000"); StatsTimer timer = new StatsTimer (MonitorConfig .builder ("test") .build (), new StatsConfig.Builder () .withComputeFrequencyMillis (2000) .withPercentiles (new double [] {99.0, 95.0, 90.0}) .withPublishMax (true) .withPublishMin (true) .withPublishCount (true) .withPublishMean (true) .withPublishStdDev (true) .withPublishVariance (true) .build (), SECONDS); Stopper stopper = timer.start (); MÁSODIK. Alszik (1); időzítő.rekord (3, SECONDS); stopper.stop (); stopper = timer.start (); időzítő.rekord (6, SECONDS); MÁSODIK. Alszik (2); stopper.stop (); assertEquals ("az időzítőnek összesen 12 másodpercet kell számlálnia", 12, timer.getTotalTime ()); assertEquals ("az időzítőnek összesen 12 másodpercet kell számlálnia", 12, timer.getTotalMeasurement ()); assertEquals ("az időzítőnek 4 frissítést kell rögzítenie", 4, timer.getCount ()); assertEquals ("stats timer value time-cost / update legyen 2", 3, timer.getValue (). intValue ()); végleges térkép metricMap = timer.getMonitors (). stream () .collect (toMap (monitor -> getMonitorTagValue (monitor, "statisztika"), monitor -> (Szám) monitor.getValue ())); assertThat (metricMap.keySet (), tartalmazzaInAnyOrder ("count", "totalTime", "max", "min", "variancia", "stdDev", "avg", "percentile_99", "percentile_95", "percentile_90") );

BucketTimer módot kínál a minták eloszlásának megoszlására értéktartományok szerint:

BucketTimer időzítő = új BucketTimer (MonitorConfig .builder ("teszt") .build (), új BucketConfig.Builder () .withBuckets (új hosszú [] {2L, 5L}) .withTimeUnit (SECONDS) .build (), SECONDS) ; időzítő.rekord (3); időzítő.rekord (6); assertEquals ("az időzítőnek összesen 9 másodpercet kell számlálnia", 9, timer.getTotalTime (). intValue ()); Térkép metricMap = timer.getMonitors (). Stream () .filter (monitor -> monitor.getConfig (). GetTags (). TartalmazzaKey ("szervo.bucket")) .collect (toMap (m -> getMonitorTagValue (m, ") szervo.vödör "), m -> (Hosszú) m.getValue ())); assertThat (metricMap, allOf (hasEntry ("vödör = 2s", 0L), hasEntry ("vödör = 5s", 1L), hasEntry ("vödör = túlcsordulás", 1L));

Az órákig tartó hosszú ideig tartó műveletek nyomon követéséhez használhatjuk az összetett monitort DurationTimer.

3.4. Metrikus típusok - Információs

Használhatjuk a Információs monitor leíró információk rögzítéséhez a hibakeresés és a diagnosztika elősegítése érdekében. Az egyetlen megvalósítás az BasicInformational, és használata nem lehet egyszerűbb:

BasicInformational information = new BasicInformational (MonitorConfig.builder ("teszt"). Build ()); informational.setValue ("összegyűjtött információ");

3.5. MonitorRegistry

A metrikus típusok mindegyike típus Monitor, amely az alapja Szervo. Ma már tudjuk, hogy számos eszköz gyűjti a nyers mutatókat, de az adatok jelentéséhez regisztrálnunk kell ezeket a monitorokat.

Vegye figyelembe, hogy minden egyes konfigurált monitort egyszer és egyszer kell regisztrálni a mutatók helyességének biztosítása érdekében. Így regisztrálhatjuk a monitorokat a Singleton mintával.

Legtöbbször használhatjuk DefaultMonitorRegistry monitorok regisztrálása:

Gauge gauge = new BasicGauge (MonitorConfig.builder ("teszt") .build (), () -> 2.32); DefaultMonitorRegistry.getInstance (). Register (nyomtáv);

Ha dinamikusan akarunk regisztrálni egy monitort, DynamicTimer, és DynamicCounter használható:

DynamicCounter.increment ("monitor-név", "tag-kulcs", "tag-érték");

Vegye figyelembe, hogy a dinamikus regisztráció drága keresési műveletet okoz az érték minden frissítésekor.

A Servo számos segítő módszert is kínál az objektumokban deklarált monitorok regisztrálásához:

Monitorok.registerObject ("testObject", ez); assertTrue (Monitors.isObjectRegistered ("testObject", ez));

Módszer registerObject a reflexióval hozzáadja az összes példányát Monitorok annotációval deklarálták @Monitor és adja hozzá az által kijelölt címkéket @MonitorTags:

@Monitor (név = "integerCounter", type = DataSourceType.COUNTER, description = "A frissítési műveletek teljes száma.") Privát AtomicInteger updateCount = új AtomicInteger (0); @MonitorTags private TagList tags = new BasicTagList (newArrayList (new BasicTag ("tag-key", "tag-value"))); @Test public void givenAnnotatedMonitor_whenUpdated_thenDataCollected () dobja a (z) {System.setProperty ("servo.pollers", "1000") kivételt; Monitorok.registerObject ("testObject", ez); assertTrue (Monitors.isObjectRegistered ("testObject", ez)); updateCount.incrementAndGet (); updateCount.incrementAndGet (); MÁSODIK. Alszik (1); Lista metrika = megfigyelő.getObservations (); assertThat (metrikák, hasSize (nagyobbThanOrEqualTo (1))); Iterátor metricIterator = metrics.iterator (); metricIterator.next (); // az első üres megfigyelés kihagyása, míg (metricIterator.hasNext ()) {assertThat (metricIterator.next (), hasItem (hasProperty ("config", hasProperty ("név", is ("egész számCounter"))))); }}

4. Mutatók közzététele

Az összegyűjtött mutatókkal bármilyen formátumban közzétehetjük, például idősor grafikonokat renderelhetünk különböző adatmegjelenítési platformokon. A mutatók közzétételéhez rendszeresen le kell kérdeznünk az adatokat a monitor megfigyeléseiből.

4.1. MetricPoller

MetricPoller metrikaszerzőként használják. A metrikák lekérhetők MonitorRegistries, JVM, JMX. A kiterjesztések segítségével lekérdezhetünk olyan mutatókat, mint az Apache szerver állapota és a Tomcat mutatói.

MemoryMetricObserver megfigyelő = new MemoryMetricObserver (); PollRunnable pollRunnable = új PollRunnable (új JvmMetricPoller (), új BasicMetricFilter (true), megfigyelő); PollScheduler.getInstance (). Start (); PollScheduler.getInstance (). AddPoller (pollRunnable, 1, SECONDS); MÁSODIK. Alszik (1); PollScheduler.getInstance (). Stop (); Lista metrika = megfigyelő.getObservations (); assertThat (metrikák, hasSize (nagyobbThanOrEqualTo (1))); Lista kulcsok = extractKeys (metrika); assertThat (kulcsok, hasItems ("loadedClassCount", "initUsage", "maxUsage", "threadCount");

Itt hoztuk létre a JvmMetricPoller a JVM mutatóinak felmérésére. Amikor a közvélemény-kutatót hozzáadjuk az ütemezőhöz, hagyjuk, hogy a közvélemény-kutatási feladat minden másodpercben futjon. A rendszer alapértelmezett poller konfigurációit a Pollerek, de megadhatjuk a rendszer tulajdonságaihoz használandó közvélemény-kutatókat szervo.pollerek.

4.2. MetricObserver

A mutatók lekérdezésekor a regisztráltak megfigyelései MetricObservers Frissítve lesz.

MetricObservers alapértelmezés szerint biztosítottak MemoryMetricObserver, FileMetricObserver, és AsyncMetricObserver. Már bemutattuk, hogyan kell használni MemoryMetricObserver az előző kódmintában.

Jelenleg számos hasznos kiterjesztés érhető el:

  • AtlasMetricObserver: mutatók közzététele a Netflix Atlas-on, hogy memóriában idősoros adatokat generálhasson az elemzéshez
  • CloudWatchMetricObserver: a metrikák nyomon követése és nyomon követése az Amazon CloudWatch-ra
  • GraphiteObserver: metrikák közzététele a Graphite-ban a tároláshoz és a grafikonhoz

Meg tudjuk valósítani a testreszabott MetricObserver hogy az alkalmazási mutatókat ott tegyük közzé, ahol jónak látjuk. Csak a frissített mutatók kezelése a fontos:

public class CustomObserver kiterjeszti a BaseMetricObserver {// ... @Override public void updateImpl (List metrics) {// TODO}}

4.3. Közzététel a Netflix Atlas webhelyen

Atlasz a Netflix egy másik mutatóval kapcsolatos eszköze. Ez egy eszköz a dimenziós idősor-adatok kezeléséhez, amely tökéletes hely az összegyűjtött mutatók közzétételéhez.

Most bemutatjuk, hogyan lehet közzétenni mutatóinkat a Netflix Atlas-on.

Először csatoljuk a szervo-atlasz függőség a pom.xml:

 com.netflix.servo szervo-atlas $ {netflix.servo.ver} 0.12.17 

Ez a függőség magában foglal egy AtlasMetricObserver hogy a metrikákat közzétegyük a Atlasz.

Ezután létrehozunk egy Atlas szervert:

$ 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

A tesztre fordított időnk megtakarítása érdekében állítsuk be a lépés méretét 1 másodpercre memória.conf, így idősor grafikont generálhatunk a metrikák kellő részletességével.

A AtlasMetricObserver egyszerű konfigurációt és címkék listáját igényli. A megadott címkék mutatói az Atlas-ra kerülnek:

System.setProperty ("szervo.pollers", "1000"); System.setProperty ("servo.atlas.batchSize", "1"); System.setProperty ("servo.atlas.uri", "// localhost: 7101 / api / v1 / publish"); AtlasMetricObserver megfigyelő = new AtlasMetricObserver (új BasicAtlasConfig (), BasicTagList.of ("szervo", "számláló")); PollRunnable feladat = új PollRunnable (új MonitorRegistryMetricPoller (), új BasicMetricFilter (true), megfigyelő);

Indulás után a PollScheduler a ... val PollRunnable feladat, a metrikákat automatikusan közzétehetjük az Atlas számára:

Számláló számláló = új BasicCounter (MonitorConfig .builder ("teszt") .withTag ("szervo", "számláló") .build ()); DefaultMonitorRegistry .getInstance () .register (számláló); assertThat (atlasValuesOfTag ("szervo"), nem (tartalmazzaString ("számláló"))); for (int i = 0; i <3; i ++) {számlálónövekedés (RandomUtils.nextInt (10)); MÁSODIK. Alszik (1); számláló.növekmény (-1 * RandomUtils.nextInt (10)); MÁSODIK. Alszik (1); } assertThat (atlasValuesOfTag ("szervo"), tartalmazString ("számláló"));

A mutatók alapján létrehozhatunk egy vonaldiagramot az Atlas grafikon API segítségével:

5. Összefoglalás

Ebben a cikkben bemutattuk, hogyan lehet a Netflix Servo-t felhasználni az alkalmazás mutatóinak gyűjtésére és közzétételére.

Abban az esetben, ha még nem olvasta el a Dropwizard Metrics bevezetését, nézze meg itt, és hasonlítsa össze gyorsan a Servo-val.

Mint mindig, a cikk teljes implementációs kódja megtalálható a Github oldalon.