שירותי מעקב מבוזרים באמצעות Spring Cloud Sleuth ו-Cloud Trace

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

מעקב מבוזר חשוב כדי לקבל תובנות וניראות (observability) בארכיטקטורת מיקרו-שירותים (microservices) רב-שכבתית. כשמקשרים בין שירות מסוים לקריאות שירות, משירות א' לשירות ב' ועד שירות ג', חשוב להבין שהשיחות היו מוצלחות וגם את זמן האחזור בכל שלב.

ב-Spring גבוהים, אפשר להשתמש ב-Spring Cloud Sleuth כדי להוסיף בצורה חלקה את האינסטרומנטציה של המעקב המבוזר לאפליקציה. כברירת מחדל, היא יכולה להעביר את נתוני המעקב אל Zipkin.

ב-Google Cloud Platform יש את Cloud Trace, שירות מנוהל שמאפשר לאחסן נתוני מעקב בלי לנהל מכונה או אחסון משלכם ב-Zipkin. Cloud Trace יכול גם להפיק דוחות התפלגות של זמן אחזור ולזהות באופן אוטומטי רגרסיות של ביצועים.

יש שתי אפשרויות להשתמש ב-Cloud Trace מאפליקציית Spring Boot:

  1. משתמשים ב-Stackdriver Trace Zipkin Proxy ופשוט מגדירים את Spring Cloud Sleuth להשתמש בשרת ה-Proxy הזה כנקודת הקצה של Zipkin
  2. אפשרות אחרת היא להשתמש ב-Spring Cloud GCP Trace, שמשתלב בצורה חלקה עם Spring Cloud Sleuth ומעביר את נתוני המעקב ישירות ל-Cloud Trace.

ב-Codelab הזה תלמדו איך לפתח אפליקציית Spring Boot חדשה ולהשתמש ב-Spring Cloud GCP Trace למעקב מבוזר.

מה תלמדו

  • איך ליצור אפליקציית Spring Boot Java ולהגדיר את Cloud Trace.

מה צריך להכין

  • פרויקט ב-Google Cloud Platform
  • דפדפן, למשל Chrome או Firefox
  • היכרות עם עורכי טקסט סטנדרטיים של Linux, כגון Vim, EMAC או Nano

איך תשתמשו במדריך הזה?

לקריאה בלבד לקרוא אותו ולבצע את התרגילים

איזה דירוג מגיע לחוויה שלך עם בניית אפליקציות אינטרנט מסוג HTML/CSS?

מתחילים בינונית בקיאים

איזה דירוג מגיע לדעתך לחוויית השימוש בשירותי Google Cloud Platform?

מתחילים בינונית בקיאים

2. הגדרה ודרישות

הגדרת סביבה בקצב עצמאי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Project name הוא השם המוצג של המשתתפים בפרויקט. זו מחרוזת תווים שלא משמשת את Google APIs. תמיד אפשר לעדכן.
  • Project ID הוא ייחודי בכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר מחרוזת ייחודית באופן אוטומטי; בדרך כלל לא מעניין אותך מה זה. ברוב ה-codelabs תצטרכו להפנות למזהה הפרויקט שלכם (בדרך כלל מזוהה כ-PROJECT_ID). אם המזהה שנוצר לא מוצא חן בעיניכם, אתם יכולים ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות שם משלך ולראות אם הוא זמין. לא ניתן לשנות אותו אחרי השלב הזה, והוא נשאר למשך הפרויקט.
  • לידיעתך, יש ערך שלישי, Project Number, שבו משתמשים בחלק מממשקי ה-API. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי התיעוד.
  1. בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או בממשקי API של Cloud. מעבר ב-Codelab הזה לא יעלה הרבה כסף, אם בכלל. כדי להשבית משאבים ולא לצבור חיובים מעבר למדריך הזה, אתם יכולים למחוק את המשאבים שיצרתם או למחוק את הפרויקט. משתמשים חדשים ב-Google Cloud זכאים להשתתף בתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.

Google Cloud Shell

אומנם אפשר להפעיל את Google Cloud ואת Kubernetes מרחוק מהמחשב הנייד, אבל ב-Codelab הזה נשתמש ב-Google Cloud Shell, סביבת שורת הפקודה שפועלת ב-Cloud.

הפעלת Cloud Shell

  1. במסוף Cloud, לוחצים על Activate Cloud Shell 853e55310c205094.png.

55efc1aaa7a4d3ad.png

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

9c92662c6a846a5c.png

ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.

9f0e51b578fecce5.png

במכונה הווירטואלית הזו נמצאים כל כלי הפיתוח הדרושים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר משמעותית את ביצועי הרשת והאימות. אם לא את כולן, ניתן לבצע חלק גדול מהעבודה ב-Codelab הזה באמצעות דפדפן.

אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שהפרויקט מאומת ושהפרויקט מוגדר לפי מזהה הפרויקט שלכם.

  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list

פלט הפקודה

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה ב-gcloud יודעת על הפרויקט שלכם:
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

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

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

3. יצירה של שירות Spring Boot REST חדש

אחרי ההשקה של Cloud Shell, תוכלו להשתמש בשורת הפקודה כדי ליצור אפליקציית Springboot חדשה עם Spring Initializr:

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d bootVersion=2.7.6 \
  -d dependencies=web,lombok,cloud-gcp,distributed-tracing \
  -d jvmVersion=17 \
  -d type=maven-project \
  -d baseDir=trace-service-one | tar -xzvf - \
  && cd trace-service-one

כדי ליצור בקר REST חדש, מוסיפים מחלקה חדשה:

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class WorkController {
  Random r = new Random();

  public void meeting() {
    try {
      log.info("meeting...");
      // Delay for random number of milliseconds.
      Thread.sleep(r.nextInt(500));
    } catch (InterruptedException e) {
    }
  }

  @GetMapping("/")
  public String work() {
    // What is work? Meetings!
    // When you hit this URL, it'll call meetings() 5 times.
    // Each time will have a random delay.
    log.info("starting to work");
    for (int i = 0; i < 5; i++) {
      this.meeting();
    }
    log.info("finished!");
    return "finished work!";
  }
}

צריך לוודא שברשותכם גרסת ה-JVM המתאימה לאפליקציה:

$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64

אפשר להפעיל את האפליקציה Spring Boot כרגיל באמצעות הפלאגין Spring Boot. נדלג על בדיקות בשיעור ה-Lab הזה:

$ ./mvnw -DskipTests spring-boot:run

אחרי שהאפליקציה מתחילה, לוחצים על הסמל של Web Preview 3a9b40fa650b2b.pngבסרגל הכלים של Cloud Shell ובוחרים באפשרות תצוגה מקדימה ביציאה 8080.

3aca52f76c6c22a3.png

לאחר המתנה קצרה אמורה להופיע התוצאה:

6793a3339447cbb5.png

ב-Cloud Shell, אתם אמורים לראות גם את הודעות היומן עם המזהה לצורכי מעקב ומזהה ה-span:

18d597c388de1ba.png

4. שימוש ב-Cloud Trace

הפעלת Cloud Trace API

לפני השימוש ב-Cloud Trace כדי לאחסן את נתוני המעקב, צריך להפעיל את Cloud Trace API. כדי להפעיל את ה-API, מפעילים:

$ gcloud services enable cloudtrace.googleapis.com

הגדרת Application Default Credentials

בשיעור ה-Lab הזה צריך להגדיר לאפליקציה (פרטי כניסה) כברירת מחדל. פרטי הכניסה האלה ייאספו באופן אוטומטי על ידי Spring Cloud GCP Trace Starter.

ראשית, מתחברים:

$ gcloud auth application-default login
You are running on a Google Compute Engine virtual machine.
The service credentials associated with this virtual machine
will automatically be used by Application Default
Credentials, so it is not necessary to use this command.
If you decide to proceed anyway, your user credentials may be visible
to others with access to this virtual machine. Are you sure you want
to authenticate with your personal account?
Do you want to continue (Y/n)? Y

Go to the following link in your browser:
    https://accounts.google.com/o/oauth2/auth...
Enter verification code: ...

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

85f500de6f5dc0a8.png

לאחר מכן, מעתיקים את קוד האימות ומדביקים אותו בחזרה ב-Cloud Shell ומקישים על Enter. אתם אמורים לראות:

Credentials saved to file: [/tmp/tmp.jm9bnQ4R9Q/application_default_credentials.json]
These credentials will be used by any library that requests
Application Default Credentials.

הוספת נתוני GCP Trace של Spring Cloud

בשירות הזה כבר השתמשנו ב-Spring Cloud Sleuth לצורך מעקב. עכשיו נוסיף את הסימן לתחילת פעולה ב-Spring Cloud GCP Trace כדי להעביר את הנתונים ל-Cloud Trace.

מוסיפים את התלות של Spring Cloud GCP Trace:

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Cloud Trace Starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

כברירת מחדל, Spring Cloud Sleuth לא דוגם כל בקשה. כדי להפוך את הבדיקה לקלה יותר, צריך להגדיל את תדירות הדגימה ל-100% ב-application.properties כדי להבטיח שנוכל לראות את נתוני המעקב, וכן להתעלם מחלק מכתובות ה-URL שלא חשובות לנו:

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
" > src/main/resources/application.properties

מריצים שוב את האפליקציה ומשתמשים ב-Cloud Shell Web Preview כדי לצפות בה:

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run

כברירת מחדל, מערכת Spring Cloud GCP Trace עוקבת אחר נתוני מעקב ושולחת אותם פעם אחת בכל 10 שניות, או כשמתקבל מספר מינימלי של נתוני מעקב. אפשר להגדיר זאת ולעיין במאמרי העזרה של Spring Cloud GCP Trace למידע נוסף.

שליחת בקשה לשירות:

$ curl localhost:8080

במסוף Cloud, עוברים אל פעולותTraceרשימת מעקב

be48cb0f99b5f7c2.png

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

3522eef823df39d8.png

נתוני המעקב אמורים להופיע תוך כ-30 שניות.

9628f6e1d2e75b05.png

לוחצים על הנקודה הכחולה כדי לראות את פרטי המעקב:

ba9051a8d4f3e725.png

זה היה די פשוט!

5. יצירת אפליקציית אינטרנט שנייה מסוג Spring Boot

לוחצים על הסמל + כדי לפתוח סשן חדש ב-Cloud Shell:

9799bee5fea95aa6.png

בסשן החדש, יוצרים את האפליקציה השנייה של Springboo:

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
  -d bootVersion=2.7.6 \
  -d dependencies=web,lombok,cloud-gcp,distributed-tracing \
  -d jvmVersion=17 \
  -d type=maven-project \
  -d baseDir=trace-service-two | tar -xzvf - \
  && cd trace-service-two

כדי ליצור בקר REST חדש, מוסיפים מחלקה חדשה:

src/main/java/com/example/demo/MeetingController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class MeetingController {
  Random r = new Random();

  @GetMapping("/meet")
  public String meeting() {
    try {
      log.info("meeting...");
      Thread.sleep(r.nextInt(500 - 20 + 1) + 20);
    } catch (InterruptedException e) {
    }
    return "finished meeting";
  }
}

הוספת Spring Cloud GCP Trace ל-pom.xml

pom.xml

<project>
  ...
  <dependencies>
    ...
    <!-- Add Cloud Trace starter -->
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>spring-cloud-gcp-starter-trace</artifactId>
    </dependency>
  </dependencies>
  ...
</project>

מגדירים את הבלש כדי לדגום 100% מהבקשות:

src/main/resources/application.properties

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
" > src/main/resources/application.properties

לבסוף, אפשר להפעיל את האפליקציה Spring Boot ביציאה 8081 באמצעות הפלאגין Spring Boot:

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw -DskipTests spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"

6. עדכון השירות הראשון כדי לצרוך שירות שני

בזמן ש-trace-service-two פועל, חוזרים לחלון הסשן הראשון של Cloud Shell ומבצעים את השינויים ב-trace-service-one.

קודם כול מאתחלים וריאנט חדש של RestTemplate:

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

...

import org.springframework.web.client.RestTemplate;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {
        @Bean
        public RestTemplate restTemplate() {
                return new RestTemplate();
        }
        
        public static void main(String[] args) {
                SpringApplication.run(DemoApplication.class, args);
        }
}

בעוד WorkController.meeting(), יש לך אפשרות להתקשר לשירות הפגישות.

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

...
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;

@RestController
@Slf4j
public class WorkController {
  @Autowired
  RestTemplate restTemplate;

  public void meeting() {
    String result = restTemplate.getForObject("http://localhost:8081/meet", String.class);
    log.info(result);
  }

  ...
}

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

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`

# The '&' places the process in the background. Bring it back to the foreground with 'fg'.
$ ./mvnw -DskipTests spring-boot:run &

$ curl localhost:8080

בשני החלונות של הסשנים, אתם אמורים לראות את ההודעות ביומן, ומזהה המעקב יופץ משירות אחד לאחר.

ברשימת המעקב של Cloud Trace, אתם אמורים לראות את נתוני המעקב השני:

13490977f1638702.png

אפשר ללחוץ על הנקודה הכחולה החדשה כדי לראות את פרטי המעקב:

ca69ef9cdd13d4aa.png

אפשר גם ללחוץ על כל טווח בתרשים כדי לראות את הפרטים של הטווח.

7. הפצת זמן אחזור דוח ביצועים

כשמשתמשים ב-Cloud Trace בתור אחסון הנתונים למעקב, Cloud Trace יכול להשתמש בנתונים כדי ליצור דוח הפצת זמן אחזור. נדרשים יותר מ-100 נתוני מעקב כדי ליצור את הדוח כך:

c8713f3d9e51dc25.png

תוכלו להריץ את יותר מ-100 הבקשות הראשונות באמצעות הפקודה hey, שמותקן מראש ב-Cloud Shell.

$ hey localhost:8080 -n 150

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

8. סיכום

בשיעור ה-Lab הזה יצרתם 2 שירותים פשוטים, הוספתם מעקב מבוזר באמצעות Spring Cloud Sleuth, והשתמשתם ב-Spring Cloud GCP כדי להעביר את פרטי המעקב אל Cloud Trace.

9. מעולה!

למדת איך לכתוב את אפליקציית האינטרנט הראשונה שלך ב-App Engine!

מידע נוסף

רישיון

היצירה הזו בשימוש ברישיון Creative Commons Attribution 2.0 גנרי.