黃金信號(Golden Signals)最初是谷歌在站點可靠性工程(SRE)實踐的背景下引入的,由谷歌軟件工程師Dave Rensin和Kevin Smathers在2016年O 'Reilly Velocity Conference上的一次演講中提出,其背后的想法是提供一組關鍵性能指標(KPI),用于測量和監控復雜分布式系統的運行狀況。
引入黃金信號是為了幫助SRE團隊關注系統可靠性和性能方面真正重要的東西。黃金信號不依賴于難以解釋的大量指標和告警,而是提供一組簡單且易于理解的指標,用于快速評估系統健康狀況。
自從這一概念提出以來,黃金信號已在SRE社區中得到廣泛采用,并被認為是監控和管理分布式系統運行狀況的最佳實踐。雖然最初黃金信號專注于延遲、流量、錯誤和飽和指標,但一些組織已經調整了這個概念,引入了特定于其系統和用例的附加指標。不過,通過一組KPI來度量和監控系統健康的核心思想仍然是黃金信號概念的核心。
黃金信號是SRE用來衡量其系統健康狀況的一組四個關鍵指標,包括:
延遲
Prometheus查詢histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket{job="fastapi-app"}[5m])) by (le, method, endpoint))通過直方圖指標(histogram metric)度量來檢測FastAPI應用程序HTTP請求的P95延遲。
該查詢計算過去5分鐘內http_request_duration_seconds_bucket度量值(表示落入特定延遲桶的請求數量)的速率總和,并按延遲(le)、HTTP方法和端點分組。然后,histogram_quantile函數使用這些值計算每個HTTP方法和端點組合的P95延遲。
流量
Prometheus查詢rate(http_requests_total{job="fastapi-app"}[$__rate_interval])通過計數器指標(counter metric)度量FastAPI應用程序每秒HTTP請求的速率。
該查詢使用rate函數來計算http_requests_total計數器指標的每秒增長率,計算向FastAPI應用程序發出的HTTP請求總數。job="fastapi-app"標簽選擇器過濾度量數據,使其只包含來自FastAPI的數據。
$__rate_interval變量是模板變量,表示計算速率的持續時間,該變量值由用戶在Prometheus查詢界面中設置,用于確定計算速率的時間范圍。
例如,如果用戶將$__rate_interval設置為5m,查詢將計算過去5分鐘內HTTP請求的每秒速率。此查詢可用于監控FastAPI應用程序的流量,并識別請求量隨時間變化的模式或異常情況。
錯誤數
Prometheus查詢http_requests_total {endpoint="/generate_error", http_status="500"}檢索web應用程序的"/generate_error"端點的HTTP請求并且HTTP狀態碼為500(內部服務器錯誤)的數量。
該查詢使用http_requests_total計數器指標,計算向web應用程序發出的HTTP請求總數。查詢通過指定endpoint="/generate_error"標簽選擇器過濾度量數據,使其只包括對"/generate_error"端點的請求。此外,查詢通過指定http_status="500"標簽選擇器過濾數據,只包括HTTP狀態碼為500的請求。
通過運行這個查詢,可以深入了解web應用中錯誤發生率,以及哪些端點容易出錯。這些信息可以幫助識別和修復應用中的問題,提高可靠性,并確保為用戶提供更好的體驗。
飽和度
Prometheus查詢clamp_max(active_requests{job="fastapi-app"} / 10, 1)用于計算活動請求與最大并發請求數的比率,并將該比率的值限制為不超過1。
該查詢使用active_requests度量(gauge)指標檢索FastAPI應用程序中的當前活動請求數。job="fastapi-app"標簽選擇器過濾度量數據,使其只包含來自FastAPI的數據。
然后,查詢將活動請求數除以10,表示系統可以處理的最大并發請求數。然后使用clamp_max函數將該比率的值限制為不超過1。這意味著,如果活動請求與最大并發請求數之比大于1,則查詢將返回值1。
通過這個查詢,可以監控系統飽和情況,并確定系統何時因請求而過載。如果活動請求與最大并發請求數之比接近1,可能需要擴容系統以處理增加的請求。此查詢可以幫助我們確保系統在高負載下仍可保持可靠和高性能。
因為黃金信號使SRE們可以清楚了解系統的運行情況,因此非常重要。通過測量和監控這些關鍵指標,SRE可以快速識別問題,并在問題變得嚴重之前采取糾正措施,即使這么做增加了系統復雜性,也可以有助于確保系統的可靠性、可伸縮性和高性能。
黃金信號可以通過幾種方式來提高系統可靠性:
了解如何在實踐中實現這些指標也很重要。實現黃金信號的一種方法是使用內置對其支持的監控工具和庫,比如Prometheus。在下面代碼示例中,Python FastAPI應用程序通過Prometheus來實現黃金信號。
from fastapi import FastAPI, Request, HTTPException, Responsefrom prometheus_client import Counter, Gauge, Histogram, generate_latest, CONTENT_TYPE_LATESTfrom starlette.responses import StreamingResponseimport timeapp = FastAPI()# Define Prometheus metricshttp_requests_total = Counter( "http_requests_total", "Total number of HTTP requests", ["method", "endpoint", "http_status"])http_request_duration_seconds = Histogram( "http_request_duration_seconds", "HTTP request duration in seconds", ["method", "endpoint"])http_request_size_bytes = Histogram( "http_request_size_bytes", "HTTP request size in bytes", ["method", "endpoint"])http_response_size_bytes = Histogram( "http_response_size_bytes", "HTTP response size in bytes", ["method", "endpoint"])active_requests = Gauge( "active_requests", "Number of active requests")error_counter = Counter( "error_counter", "Total number of HTTP errors", ["method", "endpoint", "http_status"])@app.middleware("http")async def record_request_start_time(request: Request, call_next): request.state.start_time = time.time() response = await call_next(request) return response@app.middleware("http")async def record_request_end_time(request: Request, call_next): response = await call_next(request) latency = time.time() - request.state.start_time http_request_duration_seconds.labels( request.method, request.url.path ).observe(latency) http_request_size_bytes.labels( request.method, request.url.path ).observe(request.headers.get("Content-Length", 0)) if isinstance(response, StreamingResponse): response_size = 0 else: response_size = len(response.content) http_response_size_bytes.labels( request.method, request.url.path ).observe(response_size) http_requests_total.labels( request.method, request.url.path, response.status_code ).inc() return response@app.middleware("http")async def increment_counter(request: Request, call_next): active_requests.inc() response = await call_next(request) active_requests.dec() return response@app.middleware("http")async def log_saturation(request: Request, call_next): max_concurrent_requests = 10 # set the maximum number of concurrent requests saturation_ratio = active_requests._value._value / max_concurrent_requests print(f"Saturation: {saturation_ratio}") return await call_next(request)@app.middleware("http")async def increment_error_counter(request: Request, call_next): try: response = await call_next(request) return response except HTTPException as e: error_counter.labels( request.method, request.url.path, e.status_code ).inc() print(f"Incremented error counter for {request.method} {request.url.path} {e.status_code}") raise e@app.get("/")async def root(): return {"message": "Hello, World!"}@app.get("/generate_traffic")async def generate_traffic(): for i in range(100): response = await root() print(response) return {"message": "Generated traffic successfully."}@app.get("/generate_error")async def generate_error(): raise HTTPException(status_code=500, detail="Generated an error.")@app.get("/metrics")async def metrics(): return Response(cnotallow=generate_latest(), media_type=CONTENT_TYPE_LATEST)
requirements.txt:
anyio==3.6.2click==8.1.3fastapi==0.92.0h11==0.14.0idna==3.4prometheus-client==0.16.0pydantic==1.10.5sniffio==1.3.0starlette==0.25.0typing_extensinotallow==4.5.0uvicorn==0.20.0
使用Prometheus在FastAPI應用程序中實現了黃金信號后,可能希望將其部署到Kubernetes集群中,以確保可伸縮性和高可用性。下面的Kubernetes清單文件可以用來部署FastAPI應用程序和Grafana儀表板:
fastapi-app.yaml
# @formatapiVersion: apps/v1kind: Deploymentmetadata: name: fastapi-appspec: selector: matchLabels: app: fastapi-app replicas: 2 template: metadata: labels: app: fastapi-app annotations: prometheus.io/scrape: "true" prometheus.io/path: "/" prometheus.io/port: "80" spec: containers: - name: fastapi-app image: rtiwariops/fastapi-app:v1 ports: - containerPort: 80---apiVersion: v1kind: Servicemetadata: name: fastapi-appspec: selector: app: fastapi-app ports: - name: http protocol: TCP port: 80 targetPort: 80
grafana.yaml
# @formatapiVersion: apps/v1kind: Deploymentmetadata: name: grafanaspec: selector: matchLabels: app: grafana replicas: 1 template: metadata: labels: app: grafana spec: containers: - name: grafana image: grafana/grafana:latest ports: - containerPort: 3000---apiVersion: v1kind: Servicemetadata: name: grafanaspec: selector: app: grafana ports: - name: http protocol: TCP port: 3000 targetPort: 3000
prometheus.yaml
apiVersion: v1kind: Servicemetadata: name: prometheusspec: selector: app: prometheus ports: - name: web port: 9090 targetPort: 9090---apiVersion: apps/v1kind: Deploymentmetadata: name: prometheusspec: selector: matchLabels: app: prometheus replicas: 1 template: metadata: labels: app: prometheus spec: containers: - name: prometheus image: prom/prometheus:v2.28.1 ports: - name: web containerPort: 9090 command: - "/bin/prometheus" args: - "--config.file=/etc/prometheus/prometheus.yml" volumeMounts: - name: config-volume mountPath: /etc/prometheus volumes: - name: config-volume configMap: name: prometheus-config
總之,黃金信號是SRE工具箱中的關鍵工具。通過測量和監控延遲、流量、錯誤和飽和度指標,即使面對日益增加的復雜性和需求,SRE也可以確保其系統保持可靠、可擴展和高性能。
完整代碼示例: https://github.com/PolyCloudNative/Golden-Rule-Demo
[1]Four Golden Signals Of Monitoring: Site Reliability Engineering (SRE) Metrics: https://umeey.medium.com/four-golden-signals-of-monitoring-site-reliability-engineering-sre-metrics-64031dbe268
本文鏈接:http://www.www897cc.com/showinfo-26-34674-0.html站點可靠性工程SRE最佳實踐 -- 黃金監控信號
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 淺析VR視頻傳輸方案