מבוא לסרוו נטפליקס

1. סקירה כללית

סרוו Netflix הוא כלי מדדים ליישומי Java. סרוו דומה למדדי Dropwizard, אך הרבה יותר פשוטים. היא ממנפת את JMX רק כדי לספק ממשק פשוט לחשיפה ופרסום של מדדי יישומים.

במאמר זה נציג את מה ש- Servo מספק וכיצד נוכל להשתמש בו כדי לאסוף ולפרסם מדדי יישומים.

2. תלות Maven

לפני שנצלול ליישום בפועל, בואו נוסיף את תלות סרוו ל- pom.xml קוֹבֶץ:

 com.netflix.servo ליבת סרוו 0.12.16 

חוץ מזה, יש הרבה הרחבות זמינות, כגון Servo-Apache, Servo-AWS וכו '. ייתכן שנצטרך אותם מאוחר יותר. הגרסאות העדכניות ביותר של הרחבות אלה נמצאות גם ב- Maven Central.

3. אסוף מדדים

ראשית, בואו נראה איך אוספים מדדים מהיישום שלנו.

סרוו מספק ארבעה סוגי מדדים עיקריים: דֶלְפֵּק, מַד, שָׁעוֹן עֶצֶר, ו הסברה.

3.1. סוגי מדדים - דֶלְפֵּק

מונים משמשים להקלטת תוספת. יישומים נפוצים הם BasicCounter, מד צעדים, ו PeakRateCounter.

BasicCounter עושה מה שדלפק צריך לעשות, פשוט וישר:

מונה מונה = BasicCounter חדש (MonitorConfig.builder ("מבחן"). Build ()); assertEquals ("המונה צריך להתחיל עם 0", 0, counter.getValue (). intValue ()); counter.increment (); assertEquals ("המונה היה צריך להגדיל ב -1", 1, counter.getValue (). intValue ()); counter.increment (-1); assertEquals ("המונה היה צריך לרדת ב -1", 0, counter.getValue (). intValue ());

PeakRateCounter מחזירה את הספירה המרבית לשנייה נתונה במהלך מרווח הסקרים:

מונה נגד = PeakRateCounter חדש (MonitorConfig.builder ("מבחן"). Build ()); assertEquals ("המונה צריך להתחיל עם 0", 0, counter.getValue (). intValue ()); counter.increment (); SECONDS.sleep (1); counter.increment (); counter.increment (); assertEquals ("שיעור השיא צריך להיות 2", 2, counter.getValue (). intValue ());

בניגוד לדלפקים אחרים, מד צעדים שיעור רשומות לשנייה מרווח הסקרים הקודם:

System.setProperty ("servo.pollers", "1000"); מונה מונה = StepCounter חדש (MonitorConfig.builder ("מבחן"). Build ()); assertEquals ("המונה צריך להתחיל בקצב 0.0", 0.0, counter.getValue ()); counter.increment (); SECONDS.sleep (1); assertEquals ("שיעור הנגד היה צריך לעלות ל 1.0", 1.0, counter.getValue ());

שימו לב שקבענו את סרוו.פולרים ל 1000 בקוד לעיל. זה היה להגדיר את מרווח הקלפי לשנייה במקום מרווחים של 60 שניות ו -10 שניות כברירת מחדל. עוד נדבר על כך בהמשך.

3.2. סוגי מדדים - מַד

מַד הוא צג פשוט המחזיר את הערך הנוכחי. בסיסי מד, MinGauge, MaxGauge, ו מספר מדדים מסופקים.

BasicGauge קורא א ניתן להתקשר כדי לקבל את הערך הנוכחי. אנו יכולים לקבל את גודל האוסף, הערך העדכני ביותר של a BlockingQueue או כל ערך הדורש חישובים קטנים.

מד מד = חדש BasicGauge (MonitorConfig.builder ("מבחן") .build (), () -> 2.32); assertEquals (2.32, gauge.getValue (), 0.01);

MaxGauge ו MinGauge משמשים למעקב אחר הערכים המקסימליים והמינימליים בהתאמה:

מד MaxGauge = MaxGauge חדש (MonitorConfig.builder ("מבחן"). Build ()); assertEquals (0, gauge.getValue (). intValue ()); מד.עדכון (4); assertEquals (4, gauge.getCurrentValue (0)); gauge.update (1); assertEquals (4, gauge.getCurrentValue (0));

NumberGauge (LongGauge, DoubleGauge) עוטף אספקה מספר (ארוך, לְהַכפִּיל). כדי לאסוף מדדים באמצעות מדדים אלה, עלינו לוודא את מספר הוא בטוח בחוטים.

3.3. סוגי מדדים - שָׁעוֹן עֶצֶר

טיימרים לעזור במדידת משך האירוע המסוים. יישומי ברירת מחדל הם BasicTimer, סטטימר, ו BucketTimer.

BasicTimer מתעד זמן כולל, ספירה וסטטיסטיקה פשוטה אחרת:

טיימר BasicTimer = BasicTimer חדש (MonitorConfig.builder ("מבחן"). Build (), SECONDS); שעון עצר שעון עצר = timer.start (); SECONDS.sleep (1); timer.record (2, SECONDS); stopwatch.stop (); assertEquals ("הטיימר צריך לספור שנייה אחת", 1, timer.getValue (). intValue ()); assertEquals ("הטיימר צריך לספור 3 שניות בסך הכל", 3.0, timer.getTotalTime (), 0.01); assertEquals ("הטיימר צריך להקליט 2 עדכונים", 2, timer.getCount (). intValue ()); assertEquals ("הטיימר אמור להכיל מקסימום 2", 2, טיימר. getMax (), 0.01);

סטטימר מספק נתונים סטטיסטיים עשירים בהרבה על ידי דגימה בין מרווחי הסקרים:

System.setProperty ("netflix.servo", "1000"); טיימר StatsTimer = StatsTimer חדש (MonitorConfig. Builder ("test") .build (), StatsConfig.Builder חדש () .withComputeFrequencyMillis (2000) .withPercentiles (כפול חדש [] {99.0, 95.0, 90.0}) .withPublishMax (נכון) .withPublishMin (true) .withPublishCount (true) .withPublishMean (true) .withPublishStdDev (true) .withPublishVariance (true) .build (), SECONDS); שעון עצר שעון עצר = timer.start (); SECONDS.sleep (1); timer.record (3, SECONDS); stopwatch.stop (); סטופר = טיימר.תחיל (); timer.record (6, SECONDS); SECONDS.sleep (2); stopwatch.stop (); assertEquals ("הטיימר צריך לספור 12 שניות בסך הכל", 12, timer.getTotalTime ()); assertEquals ("הטיימר צריך לספור 12 שניות בסך הכל", 12, timer.getTotalMeasurement ()); assertEquals ("טיימר צריך להקליט 4 עדכונים", 4, timer.getCount ()); assertEquals ("ערך הטיימר הסטטיסטי בעלות הזמן / העדכון צריך להיות 2", 3, timer.getValue (). intValue ()); סופי מפה metricMap = timer.getMonitors (). stream () .collect (toMap (monitor -> getMonitorTagValue (monitor, "statistic"), monitor -> (Number) monitor.getValue ())); assertThat (metricMap.keySet (), containInAnyOrder ("count", "totalTime", "max", "min", "variance", "stdDev", "avg", "percentile_99", "percentile_95", "percentile_90") );

BucketTimer מספק דרך להפיץ את הדגימות לפי טווחי ערכים:

טיימר BucketTimer = BucketTimer חדש (MonitorConfig. Builder ("test") .build (), BucketConfig.Builder חדש () .withBuckets (חדש ארוך [] {2L, 5L}) .withTimeUnit (SECONDS) .build (), SECONDS) ; timer.record (3); timer.record (6); assertEquals ("הטיימר צריך לספור 9 שניות בסך הכל", 9, timer.getTotalTime (). intValue ()); מפה metricMap = timer.getMonitors (). Stream () .filter (monitor -> monitor.getConfig (). GetTags (). ContainKey ("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));

כדי לעקוב אחר פעולות ארוכות שעשויות להימשך שעות, אנו יכולים להשתמש בצג המרוכב DurationTimer.

3.4. סוגי מדדים - הסברה

כמו כן, אנו יכולים לעשות שימוש ב- הסברה לפקח על מנת להקליט מידע תיאורי כדי לעזור באגים ואבחון. היישום היחיד הוא בסיסי מידעוהשימוש בו לא יכול להיות פשוט יותר:

מידע בסיסי על מידע = בסיסי חדש של מידע (MonitorConfig.builder ("מבחן"). Build ()); informational.setValue ("מידע שנאסף");

3.5. MonitorRegistry

סוגי המדדים כולם מסוגים צג, שהוא הבסיס של סרוו. כעת אנו יודעים כי סוגים של כלים אוספים מדדים גולמיים, אך כדי לדווח על הנתונים, עלינו לרשום את המסכים הללו.

שים לב כי כל צג מוגדר יחיד צריך להיות רשום פעם אחת ופעם אחת בלבד כדי להבטיח את נכונות המדדים. כדי שנוכל לרשום את המסכים באמצעות תבנית סינגלטון.

לרוב אנו יכולים להשתמש DefaultMonitorRegistry לרישום צגים:

מד מד = BasicGauge חדש (MonitorConfig.builder ("מבחן") .build (), () -> 2.32); DefaultMonitorRegistry.getInstance (). Register (מד);

אם אנו רוצים לרשום דינמי צג, DynamicTimer, ו DynamicCounter יכול לשמש:

DynamicCounter.increment ("שם צג", "תג מפתח", "תג תג");

שימו לב כי רישום דינמי יגרום לפעולה של בדיקת מחיר יקרה בכל פעם שהערך מעודכן.

סרוו מספק גם מספר שיטות עוזרות לרישום צגים שהוכרזו באובייקטים:

Monitors.registerObject ("testObject", זה); assertTrue (Monitors.isObjectRegistered ("testObject", זה));

שיטה registerObject ישתמש בבבואה כדי להוסיף את כל המקרים של צגים הוכרז בהערה @Monitor ולהוסיף תגים שהוכרזו על ידי @MonitorTags:

@Monitor (name = "integerCounter", type = DataSourceType.COUNTER, תיאור = "המספר הכולל של פעולות העדכון.") פרטי AtomicInteger updateCount = AtomicInteger חדש (0); @MonitorTags תגיות תגיות פרטיות = BasicTagList חדש (newArrayList (BasicTag חדש ("תג-מפתח", "תג-ערך"))); @Test הציבור בטל givenAnnotatedMonitor_whenUpdated_thenDataCollected () זורק חריג {System.setProperty ("servo.pollers", "1000"); Monitors.registerObject ("testObject", זה); assertTrue (Monitors.isObjectRegistered ("testObject", זה)); updateCount.incrementAndGet (); updateCount.incrementAndGet (); SECONDS.sleep (1); רשימה מדדים = observer.getObservations (); assertThat (מדדים, hasSize (largeThanOrEqualTo (1))); איטרטור metricIterator = metrics.iterator (); metricIterator.next (); // דלג על תצפית ריקה ראשונה תוך כדי (metricIterator.hasNext ()) {assertThat (metricIterator.next (), hasItem (hasProperty ("config", hasProperty ("name", is ("integerCounter")))); }}

4. פרסם מדדים

בעזרת המדדים שנאספו, נוכל לפרסם אותה בכל פורמט, כגון הצגת גרפים של סדרות זמן בפלטפורמות שונות להדמיית נתונים. כדי לפרסם את המדדים, עלינו לסקור את הנתונים מעת לעת מתצפיות המוניטור.

4.1. MetricPoller

MetricPoller משמש כעובר מדדים. אנחנו יכולים להביא מדדים של צג רישומים, JVM, JMX. בעזרת הרחבות אנו יכולים לסקור מדדים כמו סטטוס שרת אפאצ'י ומדדי Tomcat.

תצפית MemoryMetricObserver = MemoryMetricObserver חדש (); PollRunnable pollRunnable = PollRunnable חדש (JvmMetricPoller חדש (), BasicMetricFilter חדש (נכון), צופה); PollScheduler.getInstance (). התחל (); PollScheduler.getInstance (). AddPoller (pollRunnable, 1, SECONDS); SECONDS.sleep (1); PollScheduler.getInstance (). Stop (); רשימה מדדים = observer.getObservations (); assertThat (מדדים, hasSize (largeThanOrEqualTo (1))); מקשי רשימה = לחצן מפתחות (מדדים); assertThat (מפתחות, hasItems ("loadedClassCount", "initUsage", "maxUsage", "threadCount"));

כאן יצרנו א JvmMetricPoller למדדי סקרים של JVM. בעת הוספת הקלפן למתזמן, אנו נותנים למשימת הסקר לפעול בכל שנייה. תצורות של קלרי ברירת מחדל של המערכת מוגדרות ב בוחרים, אך אנו יכולים לציין סקרים לשימוש עם מאפיין המערכת סרוו.פולרים.

4.2. MetricObserver

בעת סקרי מדדים, תצפיות של רשומים MetricObservers יעודכן.

MetricObservers מסופקים כברירת מחדל הם MemoryMetricObserver, FileMetricObserver, ו AsyncMetricObserver. כבר הראינו כיצד להשתמש MemoryMetricObserver במדגם הקוד הקודם.

נכון לעכשיו, ישנם מספר הרחבות שימושיות:

  • AtlasMetricObserver: פרסם מדדים לאטלס של נטפליקס כדי ליצור בזיכרון נתוני סדרות זמן לניתוח
  • CloudWatchMetricObserver: דחף מדדים לאמזון CloudWatch לצורך ניטור ומעקב אחר מדדים
  • גרפיט שרת: פרסם מדדים ל- Graphite לאחסון וגרף

אנחנו יכולים ליישם מותאם אישית MetricObserver לפרסם מדדי יישומים למקום שנראה לנו מתאים. הדבר היחיד שיש לדאוג לו הוא לטפל בערכים המעודכנים:

מחלקה ציבורית CustomObserver מרחיב את BaseMetricObserver {// ... @Override public void updateImpl (מדדי רשימה) {// TODO}}

4.3. פרסם באטלס נטפליקס

אַטְלָס הוא כלי נוסף שקשור למדדים מ- Netflix. זהו כלי לניהול נתונים ממדי סדרות זמן, המהווה מקום מושלם לפרסום המדדים שאספנו.

כעת נדגים כיצד לפרסם את המדדים שלנו לאטלס נטפליקס.

ראשית, בואו נספח את אטווס סרוו תלות ב- pom.xml:

 com.netflix.servo אטלס סרוו $ {netflix.servo.ver} 0.12.17 

תלות זו כוללת AtlasMetricObserver כדי לעזור לנו לפרסם מדדים ל- אַטְלָס.

לאחר מכן, נקים שרת אטלס:

$ 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

כדי לחסוך את הזמן שלנו למבחן, בואו נגדיר את גודל הצעד לשנייה אחת memory.confכדי שנוכל ליצור גרף של סדרות זמן עם מספיק פרטים על המדדים.

ה AtlasMetricObserver דורש תצורה פשוטה ורשימת תגים. מדדי התגים הנתונים יועברו לאטלס:

System.setProperty ("servo.pollers", "1000"); System.setProperty ("servo.atlas.batchSize", "1"); System.setProperty ("servo.atlas.uri", "// localhost: 7101 / api / v1 / publish"); צופה AtlasMetricObserver = חדש AtlasMetricObserver (חדש BasicAtlasConfig (), BasicTagList.of ("סרוו", "מונה")); משימה PollRunnable = PollRunnable חדש (MonitorRegistryMetricPoller חדש (), BasicMetricFilter חדש (נכון), צופה);

לאחר הפעלת א PollScheduler עם ה PollRunnable נוכל לפרסם מדדים לאטלס באופן אוטומטי:

מונה דלפק = BasicCounter חדש (MonitorConfig. Builder ("test") .withTag ("servo", "counter") .build ()); DefaultMonitorRegistry .getInstance () .register (counter); assertThat (atlasValuesOfTag ("servo"), not (containString ("counter"))); עבור (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 ("סרוו"), containString ("מונה"));

בהתבסס על המדדים, אנו יכולים ליצור גרף קווים באמצעות גרף API של אטלס:

5. סיכום

במאמר זה הצגנו כיצד להשתמש ב- Netflix Servo כדי לאסוף ולפרסם מדדי יישומים.

אם לא קראת את המבוא שלנו למדדי Dropwizard, בדוק אותו כאן להשוואה מהירה עם סרוו.

כמו תמיד, ניתן למצוא את קוד ההטמעה המלא של מאמר זה ב- Github.


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