มาทำความรู้จักกับ Distributed Tracing ด้วย Jaeger และ Opentelemetry กันเถอะ

Samithiwat
Thinc.
Published in
3 min readMar 21, 2023

สวัสดีครับ บทความนี้จะเป็นเหมือน diary ที่พูดถึงการ setup ระบบ Distributed Tracing ด้วย Jaeger และ Opentelemetry ใน Microservice กันจากการลองผิดลองถูกในวิชา SE2 ของคณะวิศวกรรมศาสตร์ ภาค คอมพิวเตอร์

เกริ่นนำ

ในวิชา SE2 กลุ่ม project ของผมได้วาง architecture ด้วย Microservice จึงทำให้จำเป็นที่จะต้องมีระบบมา monitoring request ต่างๆที่เกิดขึ้นระหว่าง service ว่าทำงานถูกต้องหรือไม่ และเกิดความล่าช้าหรือ error ที่ส่วนไหนของ application

อะไรคือ Distributed Tracing

อย่างแรกที่จะต้องพูดถึงในบทความนี้เลย Distributed Tracing คืออะไรและมีความสำคัญอะไรบ้าง

เมื่อเราได้ออกแบบระบบให้อยู่ในรูปแบบ microservice แล้ว request จำเป็นที่จะต้องผ่านไปในหลายๆ service เพื่อทำ operation ต่างๆ และเมื่อ request มีการผ่านในหลายๆ service จะมีปัญหาหลักๆคือ

  1. การเข้าใจถึง behavior ของ application ว่าในแต่ละ request จะต้องทำอะไรบ้าง
  2. เมื่อ request มี error เกิดขึ้นในระหว่างทางจะทำให้ยากต่อการ troubleshoot

จึงทำให้เราจำเป็นที่จะต้องมีระบบมา track request ที่เกิดขึ้นใน application ของเราเพื่อนำไปแก้ปัญหาที่เกิดขึ้น นั่นคือระบบ Distributed Tracing

Idea ในการทำ Distributed Tracing

หลังจากที่เรารู้ถึงปัญหาที่เกิดขึ้นแล้วมาดู Idea ในการ track request ต่างๆที่เกิดขึ้นกัน

  1. Assign id ให้แต่ละ request
  2. ส่งต่อ request id ให้ทุก service ที่ request นี้ผ่านหรือทำ operation ใน service
  3. เพิ่ม request id นี้เข้าไปใน log message
  4. เก็บข้อมูลเช่น เวลาเริ่มต้น และ สิ้นสุดของ request และ operation ที่เกิดขึ้นในแต่ละ service เข้าสู่ centralization (ในบทความนี้คือ Jaeger)

จากขั้นตอนที่พูดถึงจะทำให้เราสามารถ track request ต่างๆได้ด้วยการเช็ค log ที่เกิดขึ้นว่าเป็นของ request ไหนผ่าน request id

รวมไปถึงสามารถเช็คเวลาที่ใช้ในการทำ operation ต่างๆในแต่ละ service ด้วย และค่อยนำข้อมูลไปเก็บที่ส่วนกลางซึ่งก็คือ Jaeger

วิธีการทำงานของ Distributed Tracing

หลังจากที่เกริ่นนำถึงหลักการไปนานได้เวลามาพูดถึงพระเอกของบทความนี้กันแล้ว

ผมต้องขอแบ่งส่วนประกอบหลักๆของระบบออกมาเป็น 2 ส่วนคือ

  1. Jaeger (Backend Server)
  2. Opentelemetry (Client)

Jaeger คืออะไร

Jaeger คือ opensource platform สำหรับการทำ end-to-end distributed tracing service พัฒนาโดย Uber Technology

หน้าที่หลักๆของ Jaeger คือการที่เก็บรวบรวม request ที่เกิดขึ้นในแต่ละ service และนำมาแสดงผลให้เราผ่านหน้า dashboard รวมไปถึงสามารถ generate graph ของ arhitecture เราคร่าวๆได้ด้วยนะ 😲

example of Jaeger dashboard

ซึ่งเจ้า Jaeger support database ที่ใช้เก็บ data อยู่ 2 ตัวคือ

  1. Elasticsearch
  2. Cassandra

ซึ่งในบทความนี้จะใช้เป็น Cassandra นะครับ

Opentelemetry คืออะไร

หลังจากที่พูดถึง Jaeger หลายๆคนน่าจะเริ่มเกิดความสงสัยแล้วว่าแล้วเราจะนำ data ที่เกิดขึ้นในแต่ละ service เข้ามาใน Jaeger ได้อย่างไร

คำตอบคือเจ้า Opentelemetry นี่แหละครับจะทำหน้าที่เป็น client ที่ส่ง data ที่เกิดขึ้นในแต่ละ service เข้าไปเก็บที่ Jaeger ด้วยการให้ service emit signal ออกมา (ใน distributed tracing คือ traces signal)

นั่นหมายความว่าเราจำเป็นที่จะต้อง implement opentelemetry ใน service ของเราด้วยนั่นเองงงง

example of distributed tracing

จากรูปตัวอย่างจะเห็นว่า opentelemetry จะต้องอยู่ในทุกๆ service ของเราเพื่อที่จะนำ data ไปให้กับ Jaeger และนำไปเก็บใน database ต่อไป

คำศัพท์ต่างๆของ Opentelemetry

ก่อนที่เราจะไปเริ่ม implement กันผมขอพูดถึงคำศัพท์ต่างๆที่จำเป็นจะต้องรู้ก่อน

Span

คือ operation ที่เกิดขึ้นใน service โดยที่ data ใน span จะเป็นรายละเอียดต่างๆที่เกิดขึ้นระหว่างที่กำลังทำ operation อยู่

เช่น ใน span จะประกอบไปด้วย

  • เวลาในการทำ operation
  • structured log message
  • attribute อื่นๆ เช่น hostname, route หรือ transport protocol เป็นต้น (ในส่วนนี้เราสามารถใส่เพิ่มเข้าไปเองได้ผ่าน opentelemetry)

Traces

คือ signal ที่เกิดขึ้นจาก opentelemetry โดย traces จะเป็นการพูดถึงภาพกว้างๆที่เกิดขึ้นใน application ของเราซึ่งใน traces จะประกอบไปด้วย span ที่เกิดขึ้น

หลังจากนี้จะเป็นส่วนประกอบที่อยู่ใน code ของเราที่จะเอาไว้สร้าง Traces Signal ขึ้นมา

Tracer Provider

คือ factory ของ tracer ซึ่งจะถูก initialize แค่เพียงครั้งเดียวใน service ของเรา

Tracer

คือ ส่วนที่สร้าง Span ขึ้นมาและใส่ข้อมูลต่างๆ (Attribute) เข้าไปใน span

Tracer Exporter

คือ ส่วนที่จะ export data ไปให้กับ consumer (Jaeger)

Tracer Context

คือ object ที่เก็บข้อมูลต่างๆของ span ที่เกิดขึ้นตามที่เคยพูดไปในหัวข้อ Idea ในการทำ Distributed Tracing เพื่อส่งต่อไปให้ service ที่ถูกเรียกหลังจาก span นี้

พูดง่ายๆก็คือเป็นตัวกลางในการส่ง request id ไปให้กับ service ที่ถูกเรียกหลัง span

ตัวอย่างการทำงานของ Tracer

service A จะมีการเรียกใช้ service B และต้องรอรับ response จาก service B ก่อนถึงจะจบการทำงาน

ใน scenario ที่พูดถึงจะเกิดเหตุการณ์ต่อไปนี้

  • service A จะสร้าง span1 ขึ้นมาเพื่อเก็บข้อมูล operation ที่เกิดขึ้นใน service A
  • มี request id ของ request นี้ในการ identify ว่า span1 เป็นของ request ไหนใน application
  • นำข้อมูลของ span1 ไปเก็บไว้ใน tracer context เพื่อส่งต่อไปให้ service B
  • เมื่อ service B ได้รับ context จาก service A แล้ว service B จะทำการ decompose context และได้รับ request id จาก span1
  • service B สร้าง span2 เพื่อเก็บข้อมูล operation ที่เกิดขึ้นโดยมี request id เป็นตัว identify request ของ span2 เหมือนกับ span1
  • เมื่อ operation เสร็จก็จะส่ง data ผ่าน tracer export ไปให้ Jaeger และส่ง response ไปให้ service A
  • service A ส่ง data ผ่าน tracer export ไปให้ Jaeger และสิ้นสุดการทำงาน

สามารถอ่านเพิ่มเติมได้ที่ official docs ของ opentelemetry

References

--

--