การติดตามแบบกระจายด้วย Spring Cloud Sleuth และ Cloud Trace

1. ภาพรวม

การติดตามแบบกระจายมีความสำคัญในการรับข้อมูลเชิงลึกและความสามารถในการสังเกตของสถาปัตยกรรม Microservice แบบหลายระดับ เมื่อคุณเชื่อมโยงบริการเป็นการเรียกใช้บริการ ตั้งแต่บริการ A ไปยังบริการ B ไปจนถึงบริการ C คุณต้องเข้าใจว่าการโทรนั้นประสบความสำเร็จ รวมถึงเวลาในการตอบสนองในทุกขั้นตอนด้วย

ใน Spring Boot คุณสามารถใช้ Spring Cloud Sleuth เพื่อเพิ่มการใช้เครื่องมือการติดตามแบบกระจายไปยังแอปพลิเคชันได้อย่างราบรื่น โดยค่าเริ่มต้น อุปกรณ์จะส่งต่อข้อมูลการติดตามไปยัง Zipkin

Google Cloud Platform มี Cloud Trace ซึ่งเป็นบริการที่มีการจัดการซึ่งช่วยให้คุณจัดเก็บข้อมูลการติดตามได้โดยไม่ต้องจัดการอินสแตนซ์หรือพื้นที่เก็บข้อมูลของ Zipkin ของคุณเอง Cloud Trace ยังสามารถสร้างรายงานการกระจายเวลาในการตอบสนองและตรวจหาการถดถอยของประสิทธิภาพโดยอัตโนมัติ

คุณมี 2 ตัวเลือกในการใช้ Cloud Trace จากแอปพลิเคชัน Spring Boot ดังนี้

  1. ใช้พร็อกซี Zipkin Trace ของสแต็ก และเพียงกำหนดค่า Spring Cloud Sleuth ให้ใช้พร็อกซีนี้เป็นปลายทางของ 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, EMACs หรือ Nano

คุณจะใช้บทแนะนำนี้อย่างไร

อ่านเท่านั้น อ่านและทำแบบฝึกหัด

คุณจะให้คะแนนประสบการณ์ในการสร้างเว็บแอป HTML/CSS อย่างไร

มือใหม่ ระดับกลาง ผู้ชำนาญ

คุณจะให้คะแนนความพึงพอใจสำหรับประสบการณ์การใช้บริการ Google Cloud Platform อย่างไร

มือใหม่ ระดับกลาง ผู้ชำนาญ

2. การตั้งค่าและข้อกำหนด

การตั้งค่าสภาพแวดล้อมตามเวลาที่สะดวก

  1. ลงชื่อเข้าใช้ Google Cloud Console และสร้างโปรเจ็กต์ใหม่หรือใช้โปรเจ็กต์ที่มีอยู่ซ้ำ หากยังไม่มีบัญชี Gmail หรือ Google Workspace คุณต้องสร้างบัญชี

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • ชื่อโครงการคือชื่อที่แสดงของผู้เข้าร่วมโปรเจ็กต์นี้ เป็นสตริงอักขระที่ Google APIs ไม่ได้ใช้ โดยคุณจะอัปเดตวิธีการชำระเงินได้ทุกเมื่อ
  • รหัสโปรเจ็กต์จะไม่ซ้ำกันในทุกโปรเจ็กต์ของ Google Cloud และจะเปลี่ยนแปลงไม่ได้ (เปลี่ยนแปลงไม่ได้หลังจากตั้งค่าแล้ว) Cloud Console จะสร้างสตริงที่ไม่ซ้ำกันโดยอัตโนมัติ คือคุณไม่สนว่าอะไรเป็นอะไร ใน Codelab ส่วนใหญ่ คุณจะต้องอ้างอิงรหัสโปรเจ็กต์ (โดยปกติจะระบุเป็น PROJECT_ID) หากคุณไม่ชอบรหัสที่สร้างขึ้น คุณสามารถสร้างรหัสแบบสุ่มอื่นได้ หรือคุณจะลองดำเนินการเองแล้วดูว่าพร้อมให้ใช้งานหรือไม่ คุณจะเปลี่ยนแปลงหลังจากขั้นตอนนี้ไม่ได้และจะยังคงอยู่ตลอดระยะเวลาของโปรเจ็กต์
  • สำหรับข้อมูลของคุณ ค่าที่ 3 คือหมายเลขโปรเจ็กต์ ซึ่ง API บางตัวใช้ ดูข้อมูลเพิ่มเติมเกี่ยวกับค่าทั้ง 3 ค่าเหล่านี้ในเอกสารประกอบ
  1. ถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Cloud Console เพื่อใช้ทรัพยากร/API ของระบบคลาวด์ การใช้งาน Codelab นี้จะไม่มีค่าใช้จ่ายใดๆ หากมี หากต้องการปิดทรัพยากรเพื่อหลีกเลี่ยงการเรียกเก็บเงินที่นอกเหนือจากบทแนะนำนี้ คุณสามารถลบทรัพยากรที่คุณสร้างหรือลบโปรเจ็กต์ได้ ผู้ใช้ Google Cloud ใหม่มีสิทธิ์เข้าร่วมโปรแกรมช่วงทดลองใช้ฟรี$300 USD

Google Cloud Shell

แม้ว่า Google Cloud และ Kubernetes จะทำงานจากระยะไกลได้จากแล็ปท็อป แต่ใน Codelab นี้ เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์

เปิดใช้งาน Cloud Shell

  1. คลิกเปิดใช้งาน Cloud Shell 853e55310c205094.png จาก Cloud Console

55efc1aaa7a4d3ad.png

หากเริ่มต้นใช้งาน Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอตรงกลางที่อธิบายว่านี่คืออะไร หากระบบแสดงหน้าจอตรงกลาง ให้คลิกต่อไป

9c92662c6a846a5c.png

การจัดสรรและเชื่อมต่อกับ Cloud Shell ใช้เวลาเพียงไม่กี่นาที

9f0e51b578fecce5.png

เครื่องเสมือนนี้โหลดด้วยเครื่องมือการพัฒนาทั้งหมดที่จำเป็น โดยมีไดเรกทอรีหลักขนาด 5 GB ถาวรและทำงานใน 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. สร้างบริการ REST สำหรับ Spring Boot ใหม่

หลังจากเปิดตัว Cloud Shell แล้ว คุณจะใช้บรรทัดคำสั่งเพื่อสร้างแอปพลิเคชัน Spring Boot ใหม่ด้วย 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 มาข้ามการทดสอบสำหรับห้องทดลองนี้กัน

$ ./mvnw -DskipTests spring-boot:run

เมื่อเริ่มแอปพลิเคชันแล้ว ให้คลิกไอคอน "แสดงตัวอย่างเว็บ" 3a9b40fafa650b2b.png ในแถบเครื่องมือ Cloud Shell แล้วเลือกแสดงตัวอย่างบนพอร์ต 8080

3aca52f76c6c22a3.png

หลังจากนั้นไม่นาน คุณจะเห็นผลลัพธ์:

6793a3339447cbb5.png

ใน Cloud Shell คุณควรเห็นข้อความบันทึกที่มีรหัสการติดตามและรหัสช่วงเวลาด้วย:

18d597c388de1ba.png

4. การใช้ Cloud Trace

เปิดใช้ Cloud Trace API

คุณต้องเปิดใช้ Cloud Trace API ก่อนจึงจะใช้ Cloud Trace เพื่อจัดเก็บข้อมูลการติดตามได้ หากต้องการเปิดใช้ API ให้ดำเนินการต่อไปนี้

$ gcloud services enable cloudtrace.googleapis.com

ตั้งค่าข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน

สำหรับห้องทดลองนี้ คุณจะต้องกำหนดค่าข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน เงื่อนไขเริ่มต้นการติดตาม GCP สำหรับ Cloud ของ Spring Cloud จะเลือกข้อมูลเข้าสู่ระบบนี้โดยอัตโนมัติ

ขั้นแรก เข้าสู่ระบบ:

$ 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 สำหรับระบบคลาวด์ช่วงฤดูใบไม้ผลิ

ในบริการนี้ เราได้ใช้ Spring Cloud Sleuth สำหรับการติดตามแล้ว เพิ่มเงื่อนไขเริ่มต้นการติดตาม GCP สำหรับระบบคลาวด์ Spring เพื่อส่งต่อข้อมูลไปยัง Cloud Trace กัน

เพิ่มทรัพยากร Dependency ของ GCP Trace ใน Spring Cloud ดังนี้

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 วินาที หรือเมื่อได้รับข้อมูลการติดตามตามจำนวนขั้นต่ำแล้ว การตั้งค่านี้กำหนดค่าได้และดูข้อมูลเพิ่มเติมได้ที่เอกสารอ้างอิงเกี่ยวกับการติดตาม GCP สำหรับ Cloud ในฤดูใบไม้ผลิ

ส่งคำขอไปยังบริการ:

$ curl localhost:8080

ใน Cloud Console ให้ไปที่การดำเนินการติดตามรายการการติดตาม

be48cb0f99b5f7c2.png

ที่ด้านบน ให้จำกัดช่วงเวลาให้แคบลงเป็น 1 ชั่วโมง การโหลดซ้ำอัตโนมัติจะเปิดอยู่โดยค่าเริ่มต้น ข้อมูลการติดตามควรปรากฏในคอนโซลแล้วเมื่อมีข้อมูลการติดตาม

3522eef823df39d8.png

ข้อมูลการติดตามควรปรากฏขึ้นภายในเวลาประมาณ 30 วินาที

9628f6e1d2e75b05.png

คลิกที่จุดสีน้ำเงินเพื่อดูรายละเอียดการติดตาม

ba9051a8d4f3e725.png

ง่ายมากเลย

5. สร้างเว็บแอปพลิเคชัน Spring Boot โปรแกรมที่ 2

เปิดเซสชัน Cloud Shell ใหม่โดยคลิกไอคอน + ดังนี้

9799bee5fea95aa6.png

ในเซสชันใหม่ ให้สร้างแอปพลิเคชัน Spring Boot โปรแกรมที่ 2 ดังนี้

$ 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 Trace ของ GCP ไปยัง 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>

กำหนดค่า Sleuth เพื่อสุ่มตัวอย่างคำขอ 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. อัปเดตบริการแรกเพื่อใช้บริการที่ 2

ขณะที่ 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

ในทั้ง 2 หน้าต่างเซสชัน คุณควรเห็นข้อความบันทึกพร้อมรหัสการติดตามที่ถ่ายทอดจากบริการหนึ่งไปยังอีกบริการหนึ่ง

ในรายการการติดตามของ Cloud Trace คุณจะเห็นการติดตามรายการที่ 2 ดังนี้

13490977f1638702.png

คุณสามารถคลิกจุดสีน้ำเงินใหม่และดูรายละเอียดการติดตามได้ ดังนี้

ca69ef9cdd13d4aa.png

นอกจากนี้ คุณยังสามารถคลิกที่ระยะเวลาในแผนภาพนี้เพื่อดูรายละเอียดระยะเวลา

7. การกระจายเวลาในการตอบสนองและ รายงานประสิทธิภาพ

เมื่อใช้ Cloud Trace เป็นพื้นที่เก็บข้อมูลการติดตาม Cloud Trace จะใช้ข้อมูลดังกล่าวเพื่อสร้างรายงานการกระจายเวลาในการตอบสนองได้ คุณต้องใช้การติดตามมากกว่า 100 รายการเพื่อสร้างรายงานดังนี้

c8713f3d9e51dc25.png

คุณเรียกใช้คำขอมากกว่า 100 รายการแรกได้โดยใช้นี่ ซึ่งติดตั้งมาล่วงหน้าใน Cloud Shell แล้ว

$ hey localhost:8080 -n 150

นอกจากนี้ Cloud Trace ยังตรวจหาการถดถอยของประสิทธิภาพของบริการเดียวกันในช่วงเวลาที่แตกต่างกัน 2 ช่วงโดยอัตโนมัติได้ในรายงานการวิเคราะห์

8. สรุป

ในห้องทดลองนี้ คุณสร้างบริการแบบง่าย 2 บริการและเพิ่มการติดตามแบบกระจายด้วย Spring Cloud Sleuth และใช้ Spring Cloud GCP เพื่อส่งต่อข้อมูลการติดตามไปยัง Cloud Trace

9. ยินดีด้วย

คุณได้เรียนรู้วิธีเขียนเว็บแอปพลิเคชันแรกของ App Engine แล้ว

ดูข้อมูลเพิ่มเติม

ใบอนุญาต

ผลงานนี้ได้รับอนุญาตภายใต้ใบอนุญาตทั่วไปครีเอทีฟคอมมอนส์แบบระบุแหล่งที่มา 2.0