返回文章列表

NGINX Plus OpenTelemetry 整合與效能調校

本文介紹如何整合 NGINX Plus API 與 OpenTelemetry,實作全鏈路可觀測性,並探討 NGINX 的日誌組態、請求追蹤及效能調校技巧。涵蓋 NGINX Plus API 的使用、OpenTelemetry 模組的安裝與組態、抽樣追蹤策略、Prometheus Exporter

Web 開發 系統設計

NGINX Plus 提供豐富的 API 可收集伺服器狀態、連線和 HTTP 請求等統計資料,結合 OpenTelemetry 則能實作更全面的系統監控。OpenTelemetry 提供了標準化的遙測資料收集方案,能將 NGINX 的請求處理過程與後端服務的追蹤資料關聯,實作全鏈路可觀測性。整合後,開發者可以利用請求追蹤、上下文傳播和動態取樣等功能,深入分析系統效能瓶頸。此外,文章也說明瞭如何透過 NGINX Prometheus Exporter 將 NGINX 的指標資料匯入 Prometheus 監控系統,以及如何設定 NGINX 的存取日誌和錯誤日誌,包含自定義日誌格式和 Syslog 轉發設定。最後,文章也提供了一些 NGINX 除錯和效能調校的最佳實務,例如使用 debug_connection 指令針對特定連線除錯、使用 $request_id 進行請求追蹤,以及利用瀏覽器快取控制提升效能等技巧。

NGINX Plus API 與 OpenTelemetry 整合

NGINX Plus 提供了一個強大的 API,用於收集伺服器、連線、HTTP 請求等多方面的統計資料。同時,透過 OpenTelemetry(OTel)模組,NGINX 可以與現代化的可觀測性工具整合,提供深入的追蹤和分析能力。

使用 NGINX Plus API 收集統計資料

NGINX Plus API 提供了一系列的端點,用於取得伺服器的詳細統計資訊。以下是一些範例:

取得 NGINX 伺服器基本資訊

$ curl "https://demo.nginx.com/api/9/nginx" | json_jq

輸出結果包含伺服器的版本、構建資訊、PID 等關鍵資料:

{
  "address": "10.3.0.7",
  "build": "nginx-plus-r30",
  "generation": 1,
  "load_timestamp": "2023-08-15T11:38:35.603Z",
  "pid": 622,
  "ppid": 621,
  "timestamp": "2023-08-22T20:49:21.717Z",
  "version": "1.25.1"
}

取得連線統計資訊

$ curl "https://demo.nginx.com/api/9/connections" | json_jq

輸出結果顯示目前的連線狀態:

{
  "accepted": 9884385,
  "active": 4,
  "dropped": 0,
  "idle": 127
}

取得 HTTP 請求統計

$ curl "https://demo.nginx.com/api/9/http/requests" | json_jq

輸出結果包含總請求數和當前請求數:

{
  "total": 52107833,
  "current": 2
}

詳細伺服器區域統計資訊

$ curl "https://demo.nginx.com/api/9/http/server_zones/hg.nginx.org" | json_jq

輸出結果包含請求處理、回應狀態碼等詳細統計:

{
  "discarded": 0,
  "processing": 0,
  "received": 308357,
  "requests": 10633,
  "responses": {
    "1xx": 0,
    "2xx": 10633,
    "3xx": 0,
    "4xx": 0,
    "5xx": 0,
    "codes": {
      "200": 10633
    },
    "total": 10633
  },
  "sent": 1327232700,
  "ssl": {
    "handshake_timeout": 0,
    "handshakes": 10633,
    "handshakes_failed": 0,
    // ... 其他 SSL 相關統計
  }
}

與 OpenTelemetry(OTel)整合

安裝 OTel 模組

首先需要安裝 NGINX OTel 模組,以 YUM 為例:

$ sudo yum install -y nginx-plus-module-otel

對於 APT 系統:

$ sudo apt install -y nginx-plus-module-otel

組態 OTel

nginx.conf 中載入 OTel 模組並組態匯出器:

load_module modules/ngx_otel_module.so;

http {
    otel_exporter {
        endpoint localhost:4317;
    }
    
    server {
        listen 127.0.0.1:8080;
        location / {
            otel_trace on;
            otel_trace_context inject;
            proxy_pass http://backend;
        }
    }
}

追蹤控制

可以透過 split_clients 控制追蹤比例:

split_clients "$otel_trace_id" $ratio_sampler {
    10% on;
    * off;
}

server {
    location / {
        otel_trace $ratio_sampler;
        otel_trace_context propagate;
        proxy_pass http://backend;
    }
}

也可以結合 HTTP 頭部實作動態追蹤控制:

map "$http_enable_otel_trace" $has_trace_header {
    default on;
    '' off;
}

map "$ratio_sampler:$has_trace_header" $request_otel {
    off:off off;
    on:on on;
    on:off on;
    off:on on;
}

server {
    location / {
        otel_trace $request_otel;
        // ... 其他組態
    }
}

OpenTelemetry 的作用

OpenTelemetry 提供了一套完整的遙測資料收集方案,能夠將 NGINX 的請求處理過程與後端服務的追蹤資料進行關聯,從而實作全鏈路的可觀測性。

主要功能特點

  1. 請求追蹤: 自動收集請求的追蹤資訊
  2. 上下文傳播: 能夠在 NGINX 與後端服務之間傳遞追蹤上下文
  3. 動態取樣: 可以根據不同條件控制追蹤的比例

在繁忙的系統中進行請求追蹤的最佳實踐

在繁忙的系統中,記錄所有請求的追蹤資料可能會過於龐大。本章節將介紹如何使用 NGINX 的相關模組來最佳化請求追蹤的實施。

使用 split_clients 模組進行抽樣追蹤

NGINX 的 split_clients 模組可以用於僅對部分請求進行追蹤,例如將追蹤比率設為 10%。進一步地,可以透過設定特定的請求頭來確保開發者的請求被追蹤。這兩種條件可以透過 map 模組結合,實作一個 OR 邏輯閘,只有當兩個條件都傳回「關閉」時,才會關閉追蹤。

設定範例

http {
    split_clients "${remote_addr} ${request_uri}" $tracing {
        10%     on;
        *       off;
    }

    map $http_x_trace_header $tracing_override {
        "on"    on;
        default off;
    }

    map "$tracing $tracing_override" $final_tracing {
        "on off"    on;
        "off on"    on;
        default     off;
    }

    # 使用 $final_tracing 變數來控制是否進行追蹤
}

內容解密:

  1. split_clients 設定:根據客戶端 IP 和請求 URI 將 10% 的請求標記為追蹤物件。
  2. map 設定:檢查特定的請求頭 X-Trace-Header 是否開啟追蹤。
  3. 最終追蹤控制:結合上述兩個條件,只要有一個條件開啟追蹤,則最終開啟追蹤。

利用 NGINX Prometheus Exporter 蒐集統計資料

為了與 Prometheus 監控系統整合,NGINX 提供了 Prometheus Exporter 模組來蒐集 NGINX 的統計資料並傳送至 Prometheus。

使用 Docker 啟動 NGINX Prometheus Exporter

$ docker run -p 9113:9113 nginx/nginx-prometheus-exporter:0.8.0 \
-nginx.scrape-uri http://{nginxEndpoint}:8080/stub_status

對於 NGINX Plus,則需要額外指定 -nginx.plus 旗標:

$ docker run -p 9113:9113 nginx/nginx-prometheus-exporter:0.8.0 \
-nginx.plus -nginx.scrape-uri http://{nginxPlusEndpoint}:8080/api

內容解密:

  1. 啟動 Exporter:使用 Docker 啟動 NGINX Prometheus Exporter,並對映埠號。
  2. 指定 NGINX 端點:根據 NGINX 或 NGINX Plus 的不同,分別指定正確的端點 URL。
  3. Prometheus 整合:Exporter 蒐集的統計資料可供 Prometheus 蒐集,實作監控功能。

組態存取日誌格式

NGINX 允許自定義存取日誌的格式,以包含有用的變數資訊。

自定義日誌格式範例

http {
    log_format geoproxy
        '[$time_local] $remote_addr '
        '$realip_remote_addr $remote_user '
        '$proxy_protocol_server_addr $proxy_protocol_server_port '
        '$request_method $server_protocol '
        '$scheme $server_name $uri $status '
        '$request_time $body_bytes_sent '
        '$geoip_city_country_code3 $geoip_region '
        '"$geoip_city" $http_x_forwarded_for '
        '$upstream_status $upstream_response_time '
        '"$http_referer" "$http_user_agent"';

    # ...
}

內容解密:

  1. 日誌格式定義:使用 log_format 定義名為 geoproxy 的自定義日誌格式。
  2. 變數資訊:包含多個內嵌變數,如客戶端 IP、請求方法、伺服器名稱、處理時間等。
  3. GeoIP 資訊:記錄客戶端的地理位置資訊,如國家程式碼、地區和城市。

NGINX 日誌組態與管理

NGINX 提供了強大的日誌組態功能,可以根據不同的需求自定義日誌格式和日誌記錄方式。本文將介紹如何組態 NGINX 的存取日誌和錯誤日誌,以及如何將日誌轉發到 Syslog 監聽器。

組態存取日誌

存取日誌(Access Log)用於記錄客戶端的請求資訊,包括客戶端的 IP 地址、請求方法、請求 URI、HTTP 版本、狀態碼等。NGINX 允許自定義存取日誌的格式和記錄內容。

自定義存取日誌格式

使用 log_format 指令可以自定義存取日誌的格式。例如:

log_format geoproxy '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent" '
                   '$geoip_country_code $geoip_region ';

在這個例子中,我們定義了一個名為 geoproxy 的日誌格式,該格式包含了客戶端的 IP 地址、請求時間、請求方法、請求 URI、HTTP 版本、狀態碼、傳送的位元組數、Referer 和 User Agent 等資訊。

使用存取日誌格式

使用 access_log 指令可以指定使用哪個日誌格式和日誌檔案路徑。例如:

server {
    access_log /var/log/nginx/access.log geoproxy;
    # ...
}

在這個例子中,我們指定了使用 geoproxy 日誌格式,並將日誌記錄到 /var/log/nginx/access.log 檔案中。

組態錯誤日誌

錯誤日誌(Error Log)用於記錄 NGINX 伺服器的錯誤資訊,包括組態錯誤、連線錯誤等。NGINX 允許組態錯誤日誌的記錄級別和日誌檔案路徑。

組態錯誤日誌

使用 error_log 指令可以組態錯誤日誌的記錄級別和日誌檔案路徑。例如:

error_log /var/log/nginx/error.log warn;

在這個例子中,我們指定了錯誤日誌的記錄級別為 warn,並將日誌記錄到 /var/log/nginx/error.log 檔案中。

將日誌轉發到 Syslog 監聽器

Syslog 是一種標準的日誌記錄協定,可以將日誌記錄到中央伺服器上。NGINX 允許將日誌轉發到 Syslog 監聽器。

組態 Syslog 轉發

使用 error_logaccess_log 指令可以將日誌轉發到 Syslog 監聽器。例如:

error_log syslog:server=10.0.1.42 info;
access_log syslog:server=10.0.1.42,tag=nginx,severity=info geoproxy;

在這個例子中,我們將錯誤日誌和存取日誌轉發到 IP 地址為 10.0.1.42 的 Syslog 監聽器上。

除錯 NGINX 組態

除錯 NGINX 組態可以幫助您找出組態錯誤和效能問題。NGINX 提供了多種除錯工具和技巧,包括檢視錯誤日誌、使用 nginx -T 命令檢查組態等。

除錯技巧

  • 檢視錯誤日誌:錯誤日誌是除錯 NGINX 組態的第一步。
  • 使用 nginx -T 命令:該命令可以檢查 NGINX 組態檔案的語法和正確性。
  • 使用除錯日誌:NGINX 允許組態除錯日誌,可以提供更詳細的日誌資訊。

透過以上介紹,您應該能夠更好地理解和管理 NGINX 的日誌組態。

NGINX 除錯與效能調校

NGINX 是一個強大的工具,能夠完成許多令人驚嘆的事情。然而,在除錯和效能調校方面,需要了解如何追蹤請求並使用相關的指令來幫助除錯。

除錯 NGINX

要除錯 NGINX,首先需要確保 NGINX 的套件是使用 --with-debug 旗標建置的。大多數常見的套件都包含此旗標,但如果您自行建置或執行的是最小化的套件,則可能需要檢查是否已啟用除錯功能。檢查方式是執行 nginx -V 命令。

啟用除錯記錄

啟用除錯記錄的方法是將 error_log 指令的記錄層級設定為 debug

error_log /var/log/nginx/error.log debug;

針對特定連線進行除錯

可以使用 debug_connection 指令來針對特定的連線進行除錯。此指令在 events 上下文中有效,並接受 IP 或 CIDR 範圍作為引數。可以宣告多次以新增多個 IP 位址或 CIDR 範圍進行除錯。

events {
    debug_connection 192.168.1.100;
}

針對特定虛擬伺服器進行除錯

由於 error_log 指令在 mainhttpmailstreamserverlocation 上下文中都有效,因此可以只在需要的上下文中設定除錯記錄層級。

請求追蹤

要對請求進行端對端的瞭解,需要將 NGINX 日誌與應用程式日誌相互關聯。可以使用 $request_id 變數來實作此目的。

設定請求 ID

可以使用 log_format 指令來定義一個名為 trace 的日誌格式,並使用 $request_id 變數來記錄請求 ID。

log_format trace '$remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent" '
                 '"$http_x_forwarded_for" $request_id';

upstream backend {
    server 10.0.0.42;
}

server {
    listen 80;
    add_header Request-ID $request_id;
    location / {
        proxy_pass http://backend;
        proxy_set_header X-Request-ID $request_id;
        access_log /var/log/nginx/access_trace.log trace;
    }
}

在這個範例組態中,$request_id 變數被用於日誌記錄,並透過 proxy_set_header 指令將請求 ID 傳遞給上游應用程式。同時,也透過 add_header 指令將請求 ID 設定在回應標頭中。

效能調校

效能調校是使 NGINX 成為高效伺服器的關鍵。效能調校取決於多個變數,例如環境、使用案例、需求和物理元件等。

使用負載測試工具

可以使用 HTTP 負載測試工具(例如 Apache JMeter、Locust 或 Gatling)來自動化測試。建立一個全面測試您的 Web 應用程式的組態,然後執行測試並檢視收集到的指標以建立基準。

瀏覽器快取控制

可以使用客戶端快取控制標頭來增加效能。

location ~* \.(css|js)$ {
    expires 1y;
    add_header Cache-Control "public";
}

這個 location 區塊指定客戶端可以快取 CSS 和 JavaScript 檔案的內容。expires 指令指示客戶端其快取資源在一年後將不再有效。add_header 指令新增 HTTP 回應標頭 Cache-Control,其值為 public,允許沿途的任何快取伺服器快取回應。

詳細解說:

  1. 啟用除錯記錄:將 error_log 的記錄層級設定為 debug 以取得詳細的除錯資訊。
  2. 針對特定連線進行除錯:使用 debug_connection 指令針對特定的 IP 或 CIDR 範圍進行除錯。
  3. 請求追蹤:使用 $request_id 變數將 NGINX 日誌與應用程式日誌相互關聯,以便進行端對端的請求追蹤。
  4. 效能調校:使用負載測試工具自動化測試,並根據測試結果進行效能調校。
  5. 瀏覽器快取控制:使用客戶端快取控制標頭來增加效能,減少伺服器負載。