พูดถึงวิธีตรวจเช็คสถานะของระบบบน Production


แอปพลิเคชันที่ deploy ขึ้นไปบน server นั้นควรจะมีระบบที่สามารถตรวจสอบการทำงานของระบบได้ด้วย เพื่อที่จะทำให้หาสาเหตุในเวลาที่มีปัญหาเกิดขึ้นมาได้

เกี่ยวกับเรื่อง Monitoring

Monitoring นั้นมีหลายแบบ และทั้งหมดใช้เพื่อเช็คความเป็นตายของแอปพลิเคชัน ลองดูว่ามีอะไรให้ใช้บ้าง

  • Check ใช้สำหรับเช็คว่าทำงานอยู่มั้ย ข้อมูลจาก check นั้นจะบอกแค่ว่าโอเคหรือไม่โอเค
  • Metrics ใช้สำหรับบอกค่าสถานะแบบ time series ซึ่งจะคอยบอกค่าต่าง ๆ ที่ระบบกำลังเป็นอยู่ เช่น ปริมาณการใช้งานของ ram, cpu, memory หรืออาจจะเป็นจำนวนการตอบกลับแต่ละประเภทของ request (2XX, 4XX, 5XX) เป็นต้น
  • Logs ใช้สำหรับเก็บข้อมูลเป็นข้อความหรือ json ที่ metrics ไม่สามารถเก็บได้ แต่ละ document อาจจะบอกเวลา ไอพีผู้ใช้ urlที่ร้องขอ event และ errorที่เกิดขึ้น อื่น ๆ ส่วนมากจะเจอในรูปแบบ text files ซึ่งจะใช้โปรแกรมมาดึงข้อมูลไปอ่านอีกที
  • Traces ขั้นกว่าของ Logs ที่สามารถ monitor หลาย ๆ services ได้ สามารถตรวจสอบได้ว่า service ไหนติดต่อไปยัง service ไหน ใช้เวลาเท่าไหร่ เกิด error อะไรขึ้นมั้ย ค่าเป็นอย่างไร การทำ monitoring ประเภทนี้จะสามารถเช็คได้เลยว่าปัญหานั้นเกิดขึ้นที่จุดไหน ตอนนี้จะขอพูดถึง traces กับ metrics ว่ามีเครื่องมืออะไรที่ช่วยทำงานตรงส่วนนี้ได้

Jaeger

Jaeger เป็นเครื่องมือยอดนิยมที่ใช้ในการทำ tracing; Jaeger นั้นจะ webserver เป็น UI ที่สามารถทำให้อ่านข้อมูลที่เกิดขึ้นได้ง่าย ๆ Jaeger ใช้ในการสร้าง trace ที่จะบอกว่า transaction นึงที่เกิดขึ้นได้ไปหา service ใด ๆ บ้าง ในแต่ละ trace นั้นจะประกอบไปด้วย span และ context

Span ก็คือเส้น timeline ที่สามารถใส่รายละเอียดได้ว่า ณ เวลาใด ๆ เกิด event อะไรขึ้นบ้าง และเราสามารถสร้าง span ย่อย ๆ (timeline ย่อย) โดยที่มี span นึงเป็นตัวหลัก ว่า span แต่ละตัวนั้นถูกเรียกโดย span หลักขณะที่มันยังทำงานอยู่; ยกตัวอย่าง ลูกค้าสร้างบัญชีใหม่ในระบบ ก็จะมี trace เกิดขึ้น ใน trace นั้นก็จะมี root span ว่า CreateAccount และมี span ย่อย ๆ หลายตัว เช่นนำพาสเวิร์ดไป hash บ้าง ส่งข้อมูลลูกค้าไปบันทึกที่ customer service บ้าง และใน customer service ก็อาจจะมี span ย่อยซ้อนเข้าไปอีกที โดย span พวกนี้จะบอกเวลาที่ตัวมันเองแต่ละตัวใช้ในการทำงาน ซึ่งตรงนี้เราจะสามารถใช้ตรงนี้ในการหาได้เลยว่ามี service ตัวไหนที่ทำงานนานเกินปรกติ หรือมี error แดงขึ้นมาตอน span ไหน ก็จะทำให้ไม่เสียเวลาในการมัวแต่หาว่าปัญหาเกิดจากจุดไหน

Context นั้นจะถูกสร้างมาคู่กันกับ span ซึ่งจะเก็บ metadata เกี่ยวกับ trace id, span id, ชื่อ, เวลา และ attributes ต่าง ๆ โดน context จะถูกใช้ในการสร้าง span ย่อย หรือ child span

Prometheus

Prometheus เป็นเครื่องมือการทำ metrics วิธีการเก็บค่าข้อมูลจากแอปพลิเคชันนั้นจะต่างจาก Jaeger ตรงที่ Prometheus เป็นฝ่ายเข้าไปเก็บข้อมูลจาก services เอง แทนที่ services จะเป็นตัวยิงข้อมูลไปหา เนื่องจาก Prometheus นั้นเก็บข้อมูลเป็นรูปแบบ time series ซึ่งประเภท metrics จะมีอยู่สามแบบ

  • Counter ใช้กับข้อมูลที่มีการนับจำนวนเพิ่มขึ้นเรื่อย ๆ โดย metrics นี้จะสามารถตรวจสอบอัตราการเพิ่มในแต่ละทุก ๆ ช่วงเวลาที่กำหนดได้ เช่นแต่ละนาทีมีการเพิ่มขึ้นกี่เปอร์เซ็นต์เป็นต้น
  • Guage ใช้ในการเก็บข้อมูลที่มีการเพิ่มลดโดยจะบอกค่าสถานะ ณ เวลานั้นเช่นเปอร์เซ็นต์การใช้ทรัพยากรของเซิฟเวอร์
  • Histogram ใช้สำหรับการเก็บข้อมูลแบบแจกแจงที่มีการแบ่งนับเป็นช่วงค่าต่าง ๆ เช่น [0, 1), [1, 3), [3, 5), [5, inf) เป็นต้น; มีการสรุปสถิติเบื้องต้นเช่น sum, count และก็สามารถใช้ฟังก์ชันหาเปอร์เซ็นต์ไทล์ต่าง ๆ ได้

Prometheus นอกจากจะเอาไว้ใช้เก็บ metrics data แล้วก็ยังสามารถเขียน alert rules ที่เอาไว้ติดต่อกับ Alertmanager ได้ด้วย; โดยจะเขียน rules ต่าง ๆ ไว้ว่า ถ้าหากสถานะของระบบ (ข้อมูลที่ได้มาจาก metrics) เป็นไปตามเงื่อนไข เช่นใช้ cpu เกิน 75% ก็จะส่งข้อมูลไปยัง Alertmanager; โดยตัว Alertmanager นี้ก็ตั้งค่าได้ว่าจะให้ส่งแจ้งไปทางไหน mail, sms, slack หรือยิง webhook ก็ได้ แล้วเมื่อได้รับแจ้งปัญหาเราก็จะมาใช้ Jaeger เพื่อ trace services ดูว่ามีปัญหาที่ตรงไหนเป็นต้น

Alerts ที่ส่งมาจาก Alertmanager จะมีอยู่สองสถานะคือ Firing ที่จะส่งมาเมื่อระบบตกอยู่ภายในเงื่อนไขของ alert rules; และสถานะ Resolved ที่จะถูกส่งมาอีกครั้งเมื่อระบบหลุดจากเงื่อนไขของ alert rules แล้ว (ในกรณีตัวอย่างนี้ก็คือ cpu กลับมาต่ำกว่า 75%)