مراقبة الخدمات المصغرة باستخدام Prometheus و Grafana
June 8, 2023
المراقبة المستمرة أمر بالغ الأهمية لجعل أنظمة الخدمات المصغرة قوية. بدون مراقبة مناسبة، يمكن أن تتعرض الخدمات المصغرة للإرهاق بسرعة، مما يؤدي إلى حدوث أخطاء وفقدان في الأداء.
من خلال المراقبة المستمرة، يمكن للمطورين اكتشاف المشكلات في خدماتهم بمجرد ظهورها واتخاذ إجراءات لمنع حدوث أضرار كبيرة. كما توفر رؤى حول كيفية أداء خدماتك، مما يسمح لك باتخاذ قرارات مستنيرة.
ستقدم هذه المقالة كيفية إعداد المراقبة على تطبيق الخدمات المصغرة الخاص بك باستخدام أداتين شائعتين في هذا المجال، وهما Prometheus وGrafana.
يتوفر الكود المصدري وملف Docker Compose لهذا البرنامج التعليمي في pottekkat/monitoring-101.
أساسيات Prometheus
Prometheus هو أداة مراقبة وإنذار مفتوحة المصدر. يقوم "بسحب" المقاييس (القياسات) من الخدمات المصغرة عن طريق إرسال طلبات HTTP ويخزن النتائج في قاعدة بيانات تسلسل زمني.
يمكنك توجيه خدماتك باستخدام مكتبات العميل التي توفرها Prometheus. سيسمح لك ذلك بإنشاء وجمع مقاييس مخصصة من خدماتك.
كما أن Prometheus يحتوي على مصدّرات تتيح لك سحب المقاييس التي ليست بتنسيق Prometheus. يعمل المصدّر كوسيط ويحول البيانات المصدرة إلى تنسيق يمكن لـ Prometheus قراءته.
توفر Prometheus لغة استعلام قوية، PromQL، للعمل مع هذه البيانات المجمعة. يمكنك استخدام PromQL لإنشاء استعلامات معقدة لتصفية البيانات وتجميعها وتحويلها إلى التنسيق المطلوب.
بالإضافة إلى سحب المقاييس، يمكن لـ Prometheus أيضًا تشغيل إنذارات عند تجاوز الحدود المحددة. آلية الإنذار قابلة للتخصيص بشكل كبير ويمكنها إرسال إشعارات إلى أماكن مثل Slack أو البريد الإلكتروني.
يحتوي Prometheus على واجهة مستخدم رسومية تتيح لك تصور المقاييس المجمعة بسهولة. كما يتكامل مع أدوات التصور المتقدمة الأخرى مثل Grafana.
أنواع المقاييس
توفر Prometheus أربعة أنواع أساسية من المقاييس:
- العداد (Counter): يمثل عدادًا واحدًا يتزايد بشكل رتيب. يمكن أن تزيد قيمته أو تعود إلى الصفر عند إعادة التشغيل. يمكنك استخدامه لتمثيل مقاييس مثل عدد الطلبات التي تمت خدمتها.
- المقياس (Gauge): يمثل قيمة رقمية يمكن أن تزيد أو تنخفض. يمكنك استخدامه لتمثيل قيم مثل استخدام الذاكرة أو عدد الطلبات في الثانية.
- الهيستوجرام (Histogram): يقوم بأخذ عينات من البيانات وتوزيعها في سلال قابلة للتكوين. استخدمه لتمثيل قيم مثل مدة الطلبات أو أحجام الاستجابات.
- الملخص (Summary): يشبه الهيستوجرام، حيث يقوم أيضًا بحساب قيم قابلة للتكوين على نافذة زمنية منزلقة.
يمكنك معرفة المزيد عن هذه الأنواع من المقاييس وكيفية استخدامها من الوثائق الرسمية.
تطبيق العينة
يتكون تطبيق العينة الخاص بنا من بوابة API، تطبيق Go، وتطبيق Python.
سيقوم التطبيق بإرجاع "مرحبًا <اسم>!" باللغة التي تختارها مع الاسم الذي تقدمه. سيكون Apache APISIX هو بوابة API التي توجه حركة المرور إلى خدماتك.
يظهر الرسم البياني التالي كيفية عمل النظام.
- يرسل المستخدم طلب GET إلى APISIX، وهي نقطة الدخول للتطبيق.
- يقوم APISIX بتوجيه الطلب إلى خدمة Go.
- تقوم خدمة Go بإرسال طلب GET إلى خدمة Python للحصول على "مرحبًا" باللغة المحددة.
- تقوم خدمة Python بالرد بالترجمة المطلوبة لـ "مرحبًا".
- تقوم خدمة Go بإنشاء الاستجابة المطلوبة باستخدام الاسم المقدم في الاستعلام وترسلها إلى APISIX.
- يقوم APISIX بتوجيه الاستجابة مرة أخرى إلى المستخدم.
تكوين Prometheus لجمع المقاييس
سنقوم بتوجيه وتصدير المقاييس من جميع الخدمات في تطبيقنا وجمعها في Prometheus. سنبدأ ببوابة API الخاصة بنا، Apache APISIX.
تصدير المقاييس من APISIX
Apache APISIX هو بوابة API مفتوحة المصدر ومصممة للعمل في البيئات السحابية.
لا تحتاج إلى معرفة APISIX لمتابعة هذا البرنامج التعليمي، ويمكنك استخدام ملف Docker Compose المقدم لإعداد كل شيء. لمعرفة المزيد عن APISIX، قم بزيارة api7.ai/apisix.
يوفر APISIX إضافة prometheus التي تصدر المقاييس بسهولة بتنسيق Prometheus. يمكنك تكوين الإضافة في ملف تكوين APISIX الخاص بك:
apisix:
enable_admin: false # تشغيل APISIX في الوضع المستقل
config_center: yaml # استخدام ملف YAML للتكوين بدلاً من تخزينه في etcd
plugin_attr:
prometheus:
export_uri: /prometheus/metrics # تمكين إضافة prometheus وتصدير المقاييس إلى هذا الرابط
enable_export_server: false # تصدير المقاييس في منفذ data-plane الافتراضي
يمكننا الآن تمكين الإضافة على كل Route عن طريق جعلها قاعدة عامة:
routes:
# توجيه الطلبات إلى /hello/* إلى go-app
- uri: /hello/*
upstream:
type: roundrobin
nodes:
"go-app:8080": 1
plugins:
# إزالة البادئة "/hello" قبل توجيه الطلب إلى go-app
proxy-rewrite:
regex_uri:
- "/hello/(.*)"
- "/$1"
# تصدير مقاييس Prometheus إلى الرابط المحدد
- uri: /prometheus/metrics
plugins:
public-api:
# تمكين إضافة Prometheus بشكل عام على جميع Routes
global_rules:
- id: 1
plugins:
prometheus:
prefer_name: true
#END
سيؤدي هذا إلى تصدير المقاييس إلى نقطة النهاية /prometheus/metrics
في Apache APISIX.
يمكنك معرفة المزيد عن المقاييس المتاحة من الوثائق.
توجيه وتصدير المقاييس من خدمة Go
يحتوي Prometheus على مكتبة عميل رسمية لـ Go لتوجيه تطبيقات Go.
بشكل افتراضي، سيقوم Prometheus بعرض المقاييس الافتراضية لـ Go. يمكنك أيضًا إنشاء مقاييس خاصة بتطبيقك.
في خدمتنا، سنعرض المقاييس الافتراضية وننشئ مقياس عداد خاص بنا لتتبع عدد الطلبات:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
// حزم Prometheus
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Response يخزن الرسالة التي تم الحصول عليها من python-app
type Response struct {
Message string `json:"message"`
}
// اللغة والاسم الافتراضيين
var (
lang = "en"
name = "John"
)
// إنشاء مقياس عداد مخصص جديد لـ Prometheus
var pingCounter = promauto.NewCounter(
prometheus.CounterOpts{
Name: "go_app_request_count",
Help: "عدد الطلبات التي تمت معالجتها بواسطة go-app",
},
)
// HelloHandler يعالج الطلبات إلى go-app
func HelloHandler(w http.ResponseWriter, r *http.Request) {
lang = r.URL.String()
name = r.URL.Query()["name"][0]
fmt.Println("طلب لـ", lang, "مع الاسم", name)
pingCounter.Inc()
pUrl := os.Getenv("PYTHON_APP_URL")
if len(pUrl) == 0 {
pUrl = "localhost"
}
// استدعاء python-app للحصول على الترجمة
resp, err := http.Get("http://" + pUrl + ":8000" + lang)
if err != nil {
log.Fatalln(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
resp.Body.Close()
var m Response
json.Unmarshal(body, &m)
// إرسال الرد مع "مرحبًا اسم!" باللغة المحددة
fmt.Fprintf(w, "%s %s!", m.Message, name)
}
func main() {
// عرض مقاييس Prometheus
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/", HelloHandler)
http.ListenAndServe(":8080", nil)
}
سيؤدي هذا إلى عرض المقاييس إلى نقطة النهاية /metrics
. يمكنك معرفة المزيد عن مكتبة عميل Go من مستودع GitHub الخاص بها.
توجيه وتصدير المقاييس من خدمة Python
يحتوي Prometheus أيضًا على مكتبة عميل رسمية لـ Python. هناك أيضًا مكتبات تابعة لجهات خارجية مصممة لتلائم حالات استخدام محددة.
تستخدم خدمتنا FastAPI، وسنستخدم مكتبة prometheus_fastapi_instrumentator لتوجيهها:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from prometheus_fastapi_instrumentator import Instrumentator
app = FastAPI()
hello = {"en": "Hello", "fr": "Bonjour", "es": "Hola", "ml": "ഹലോ"}
# عرض المقاييس الافتراضية لـ Python إلى نقطة النهاية /metrics
Instrumentator().instrument(app).expose(app)
@app.get("/{lang}")
async def get_hello(lang):
return {"message": hello[lang]}
يمكنك معرفة المزيد عن إنشاء مقاييس مخصصة من الوثائق.
تكوين Prometheus
يمكننا الآن سحب وجمع هذه المقاييس في Prometheus.
يمكنك تكوين Prometheus لجمع المقاييس من كل خدمة. بشكل افتراضي، يتحقق Prometheus من المقاييس في المسار /metrics
:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "go-app"
static_configs:
- targets: ["go-app:8080"]
- job_name: "python-app"
static_configs:
- targets: ["python-app:8000"]
- job_name: "apisix"
static_configs:
- targets: ["apisix:9080"]
metrics_path: "/prometheus/metrics"
هذا كل شيء! الآن، إذا قمت بفتح لوحة تحكم Prometheus (الافتراضي على المنفذ 9090
) والنقر على "Status" من شريط التنقل و"Targets"، ستتمكن من رؤية حالة المقاييس التي يتم سحبها من خدماتك.
استعلام وتصور المقاييس في Prometheus
الآن، يمكنك استخدام لوحة تحكم Prometheus لتشغيل الاستعلامات والتعابير المعقدة.
يمكنك معرفة المزيد عن استعلام Prometheus في الوثائق الرسمية.
استخدام Grafana لاستعلام Prometheus
Grafana هي منصة تصور بيانات مفتوحة المصدر تعمل مع Prometheus لتوفير أداة شاملة لجمع المقاييس واستعلامها وتصورها.
Prometheus جيد في جمع المقاييس والاستعلام ولكن يفتقر إلى توفير أدوات لإنشاء تصورات ذات معنى. يتغلب Grafana على هذا القصور عن طريق تحويل المقاييس المجمعة إلى تصورات.
Grafana متوافق أيضًا مع العديد من مصادر البيانات الأخرى غير Prometheus.
بمجرد نشر Grafana، يمكنك فتح واجهة المستخدم عبر الويب (الافتراضي على المنفذ 3000
).
أولاً، يجب عليك إضافة Prometheus كمصدر بيانات. للقيام بذلك، انتقل إلى `/datasources أو "Configuration" و"Data sources." انقر على "Add data source" واختر Prometheus. حدد مكان نشر Prometheus، واحفظ واختبر الاتصال.
استخدام لوحات تحكم Grafana المبنية مسبقًا
يستضيف Grafana مستودع لوحات تحكم عامة يحتوي على لوحات تحكم Grafana مبنية مسبقًا. يمكنك استخدامها في نسختك من Grafana لتصور المقاييس ذات الصلة بسرعة.
سنستخدم لوحة تحكم Go Processes التي ستقوم بمعالجة وتصور حالة العملية التي تنشرها مكتبة عميل Prometheus لـ Go.
لاستيراد هذا القالب، أولاً، انسخ معرفه (6671
) من مستودع لوحات التحكم. في واجهة مستخدم Grafana الخاصة بك، انتقل إلى "Dashboards" واختر "Import." الصق المعرف الذي نسخته وانقر على "Load."
يمكنك أيضًا استكشاف لوحات تحكم أخرى مبنية مسبقًا أو إنشاء لوحات تحكم خاصة بك. راجع الوثائق لمعرفة المزيد عن هذا.
ما التالي؟
هذا كل شيء لهذا البرنامج التعليمي!
كانت هذه المقالة مجرد مقدمة عن كيفية إعداد المراقبة على خدماتك، وأشجعك على معرفة المزيد عن Prometheus وGrafana من المصادر المذكورة أدناه:
يتوفر الكود الكامل وملف Docker Compose لهذا البرنامج التعليمي في pottekkat/monitoring-101.