全部產品
Search
文件中心

Managed Service for OpenTelemetry:使用OpenTelemetry對Nginx進行鏈路追蹤

更新時間:Jun 13, 2025

本文介紹如何使用 OpenTelemetry 對 Nginx 進行鏈路追蹤。 Nginx 是一個高效能、輕量級的開源 Web 服務器和反向 Proxy伺服器,支援通過模組以擴充其功能。Nginx OTel 模組支援採集 Nginx 的調用鏈並轉寄上報至Managed Service for OpenTelemetry

使用限制

  • Nginx OTel 模組目前僅支援 gRPC 方式上報,不支援 HTTP 方式上報。

  • Nginx OTel 模組版本說明:

    • ≥ 0.1.2:支援將 Nginx OTel 採集到的 Nginx 調用鏈直接轉寄上報至Managed Service for OpenTelemetry

    • ≤ 0.1.1:Nginx OTel 模組不支援設定 gRPC 鑒權 Token,因此您需要部署 OpenTelemetry Collector。將 Nginx OTel 採集到的 Nginx 調用鏈通過 OpenTelemetry Collector 轉寄上報至Managed Service for OpenTelemetry。詳細步驟,請參見三、(可選)部署 OpenTelemetry Collector

前提條件

擷取 gRPC 存取點和鑒權 Token 資訊

新版控制台

  1. 登入可觀測鏈路 OpenTelemetry 版控制台,在左側導覽列單擊接入中心

  2. 開源架構地區單擊OpenTelemetry卡片。

  3. 在彈出的OpenTelemetry面板中選擇資料需要上報的地區。

    說明

    初次接入的地區將會自動進行資源初始化。

  4. 選擇串連方式上報方式,然後複製存取點資訊。

    • 串連方式:若您的服務部署在阿里雲上,且所屬地區與選擇的接入地區一致,推薦使用阿里雲內網方式,否則選擇公網方式。

    • 上報方式:根據用戶端支援的協議類型選擇gRPC協議上報資料。

    87.jpg

舊版控制台

  1. 登入可觀測鏈路 OpenTelemetry 版控制台

  2. 在左側導覽列單擊叢集配置,然後在右側頁面單擊存取點資訊頁簽。

  3. 在頁面頂部選擇需要接入的地區,然後在叢集資訊地區開啟顯示Token開關。

  4. 用戶端採集工具地區單擊OpenTelemetry

    相關資訊列中,擷取存取點資訊。86.jpg

    說明

    如果應用部署於阿里雲生產環境,則選擇阿里雲VPC網路存取點,否則選擇公網存取點。

接入步驟

一、下載 Nginx OTel 模組

方式一:系統包管理器安裝

  • Alibaba Cloud Linux、RedHat、RHEL 及其衍生版本

    sudo yum install nginx-module-otel
  • Debian、Ubuntu 及其衍生版本

    sudo apt install nginx-module-otel

方式二:使用預構建Docker鏡像

說明

Nginx 1.27.5 版本及以上預設採用的是 0.1.2 版本的 Nginx OTel 模組。

前往Docker官網,搜尋並拉取帶有-otel尾碼的Nginx鏡像(如nginx:1.23.3-otel),通過標準容器啟動流程部署服務。

image

二、啟用 Nginx OTel 模組

若要為 Nginx 啟用鏈路追蹤,您需要在 Nginx 主設定檔/etc/nginx/nginx.conf中載入 OTel 模組並添加配置項。關於 OTel 模組的更多參數配置資訊,請參見ngx_otel_module 模組文檔

  • 全域配置:為所有 HTTP 要求開啟鏈路追蹤。

    Nginx OTel 模組版本 ≥ 0.1.2

    load_module modules/ngx_otel_module.so; # 載入 ngx_otel_module
    ...
    http {
        ...
    
        otel_exporter {
            endpoint "${GRPC_ENDPOINT}"; # 前提條件中擷取的 gRPC 存取點
            header Authentication "${GRPC_TOKEN}"; # 前提條件中擷取的鑒權 Token
        }
    
        otel_trace on;                     # 開啟鏈路追蹤
        otel_service_name ${SERVICE_NAME};  # 應用程式名稱
        otel_trace_context propagate;         # 向下遊服務注入Trace上下文
        ...
    }

    Nginx OTel 模組版本 ≤ 0.1.1

    說明

    請替換配置中的兩個變數:

    • ${OTEL_COLLECTOR_GRPC_RECEIVER_ENDPOINT}:OpenTelemetry Collector gRPC 上報點。此上報點為您部署的 OpenTelemetry Collector 的 gRPC 上報點,例如localhost:4317,而不是前提條件中擷取的Managed Service for OpenTelemetry的存取點。

    • ${SERVICE_NAME:應用程式名稱。此名稱將會作為 Nginx 的應用程式名稱在Managed Service for OpenTelemetry控制台中展示。

    load_module modules/ngx_otel_module.so; # 載入 ngx_otel_module
    ...
    http {
        ...
    
        otel_exporter {
            endpoint ${OTEL_COLLECTOR_GRPC_RECEIVER_ENDPOINT}; # OpenTelemetry Collector 的上報地址,例如 localhost:4317
        }
    
        otel_trace on;                     # 開啟鏈路追蹤
        otel_service_name ${SERVICE_NAME};  # 應用程式名稱
        otel_trace_context propagate;         # 向下遊服務注入Trace上下文
        ...
    }
  • 單個 Location 配置:為單個 Location 開啟鏈路追蹤。

    Nginx OTel 模組版本 ≥ 0.1.2

    load_module modules/ngx_otel_module.so; # 載入 ngx_otel_module
    
    ...
    
    http {
    
        otel_exporter {
            endpoint "${GRPC_ENDPOINT}"; # 前提條件中擷取的 gRPC 存取點
            header Authentication "${GRPC_TOKEN}"; # 前提條件中擷取的鑒權 Token
        }
    
        server {
            listen 127.0.0.1:80;
    
            location /hello {
                otel_trace         on;             # 只為 127.0.0.1:80/hello 開啟鏈路追蹤
                otel_service_name ${SERVICE_NAME}  # 應用程式名稱
                otel_trace_context propagate;         # 向下遊服務注入Trace上下文
    
                ...
            }
        }
    }

    Nginx OTel 模組版本 ≤ 0.1.1

    說明

    請替換配置中的兩個變數:

    • ${OTEL_COLLECTOR_GRPC_RECEIVER_ENDPOINT}:OpenTelemetry Collector gRPC 上報點。此上報點為您部署的 OpenTelemetry Collector 的 gRPC 上報點,例如localhost:4317,而不是前提條件中擷取的Managed Service for OpenTelemetry的存取點。

    • ${SERVICE_NAME:應用程式名稱。此名稱將會作為 Nginx 的應用程式名稱在Managed Service for OpenTelemetry控制台中展示。

    load_module modules/ngx_otel_module.so; # 載入 ngx_otel_module
    
    ...
    
    http {
    
        otel_exporter {
            endpoint ${OTEL_COLLECTOR_GRPC_RECEIVER_ENDPOINT}; # OpenTelemetry Collector 的上報地址,例如 localhost:4317
        }
    
        server {
            listen 127.0.0.1:80;
    
            location /hello {
                otel_trace         on;             # 只為 127.0.0.1:80/hello 開啟鏈路追蹤
                otel_service_name ${SERVICE_NAME}  # 應用程式名稱
                otel_trace_context propagate;         # 向下遊服務注入Trace上下文
    
                ...
            }
        }
    }

三、(可選)部署 OpenTelemetry Collector

說明
  • Nginx OTel 模組版本 ≥ 0.1.2時,無需部署OpenTelemetry Collector。

  • Nginx OTel 模組版本 ≤ 0.1.1時,需要部署OpenTelemetry Collector。

方式一:通過ACK控制台部署

  1. 登入Container Service管理主控台,在左側導覽列選擇市場 > 應用市場

  2. 在應用市場中搜尋並單擊opentelemetry-collector,單擊頁面右上方一鍵部署

  3. 建立頁面選擇需要部署opentelemetry-collector的叢集,然後單擊下一步

  4. 參數配置頁面,增加如下參數,然後單擊確定

    說明

    請將${GRPC_ENDPOINT}${GRPC_ENDPOINT_TOKEN}替換為前提條件中擷取的 gRPC 存取點和鑒權 Token。

    receivers:
      otlp:
        protocols:
          grpc: 
            endpoint: 0.0.0.0:4317
    
    exporters:
      otlp:
        endpoint: ${GRPC_ENDPOINT}
        tls:
          insecure: true
        headers:
          "Authentication": "${GRPC_ENDPOINT_TOKEN}"
    
    processors:
      batch:
      
    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: [batch]
          exporters: [otlp]

    以下為樣本圖:

    81

方式二:手動部署

下文以 Docker 方式為例,介紹如何部署 OpenTelemetry Collector。更多部署方式,請參見下載並部署OpenTelemetry Collector

  1. 建立opentelemetry-config.yaml檔案,並將下面的內容拷貝至檔案。

    該檔案用於定義和配置OpenTelemetry Collector的行為和功能,包括如何接收、處理和匯出資料。

    說明

    請將${GRPC_ENDPOINT}${GRPC_ENDPOINT_TOKEN}替換為前提條件中擷取的 gRPC 存取點和鑒權 Token。

    receivers:
      otlp:
        protocols:
          grpc: 
            endpoint: 0.0.0.0:4317
    
    exporters:
      otlp:
        endpoint: ${GRPC_ENDPOINT}
        tls:
          insecure: true
        headers:
          "Authentication": "${GRPC_ENDPOINT_TOKEN}"
    
    processors:
      batch:
      
    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: [batch]
          exporters: [otlp]
  2. 啟動 OpenTelemetry Collector。

    docker run -v $(pwd)/opentelemetry-config.yaml:/etc/otelcol-contrib/config.yaml otel/opentelemetry-collector-contrib:0.105.0

四、查看 Nginx 調用鏈

完成以上配置並重啟 Nginx 後,您可向 Nginx 發送請求,以產生調用鏈。然後登入可觀測鏈路 OpenTelemetry 版控制台,查看由 OpenTelemetry 產生的 Nginx 調用鏈。

  • 應用列表頁面查看 Nginx 應用。89.jpg

  • 調用鏈分析頁面開啟 Nginx 的調用鏈,查看請求耗時、用戶端 IP、 HTTP 狀態代碼等資訊。如果您的後端服務也接入了Managed Service for OpenTelemetry,您將會看到串聯在一起的 Nginx 與後端服務調用鏈。88.jpg

實踐教程

接下來將通過案例示範如何採集 Nginx 及後端應用的調用鏈,並上報至Managed Service for OpenTelemetry

一、準備工作

二、專案結構

nginx-otel-demo
│
├── docker-compose.yml          # Docker Compose 設定檔
│
├── nginx_conf/                 # nginx 設定檔
│   ├── default.conf
│   └── nginx.conf              
│
├── otel_conf/                  # OpenTelemetry Collector 設定檔
│   └── config.yaml           
│
└── backend/                    # Node.js 後端服務
    ├── Dockerfile              
    ├── main.js
    ├── package.json
    └── package-lock.json

建立檔案夾:

mkdir nginx-otel-demo && cd nginx-otel-demo

mkdir -p nginx_conf otel_conf backend

三、建立 Nginx 配置

  1. 建立 Nginx 主設定檔nginx.conf

    Nginx OTel 模組版本 ≥ 0.1.2

    cat << 'EOF' > nginx_conf/nginx.conf
    load_module modules/ngx_otel_module.so;
    
    user  nginx;
    worker_processes  auto;
    
    error_log  /var/log/nginx/error.log notice;
    pid        /var/run/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
    
        otel_exporter {
            endpoint "${GRPC_ENDPOINT}";
            header Authentication "${GRPC_TOKEN}";
        }
    
        otel_trace on;
    
        otel_trace_context propagate;
    
        otel_service_name nginx;
    
        include /etc/nginx/conf.d/*.conf;
    
    }
    EOF

    Nginx OTel 模組版本 ≤ 0.1.1

    load_module modules/ngx_otel_module.so;
    
    user  nginx;
    worker_processes  auto;
    
    error_log  /var/log/nginx/error.log notice;
    pid        /var/run/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
    
        otel_exporter {
            endpoint otel-collector:4317;
        }
    
        otel_trace on;
    
        otel_trace_context propagate;
    
        otel_service_name nginx;
    
        include /etc/nginx/conf.d/*.conf;
    
    }
    EOF
    
  2. 建立 Nginx 設定檔default.conf

    cat << 'EOF' > nginx_conf/default.conf
    server {
        listen       80;
        server_name  localhost;
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
        
        # 在這裡添加
        location /hello {
            proxy_pass http://backend-api:7001/hello;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
    }
    EOF

四、(可選)建立 OpenTelemetry Collector 配置

說明
  • Nginx OTel 模組版本 ≥ 0.1.2時,無需部署OpenTelemetry Collector。

  • Nginx OTel 模組版本 ≤ 0.1.1時,需要部署OpenTelemetry Collector。

建立 OpenTelemetry Collector 設定檔,該設定檔定義了資料如何被接收、處理和上報。

說明

請將${GRPC_ENDPOINT}${GRPC_ENDPOINT_TOKEN}替換為前提條件中擷取的 gRPC 存取點和鑒權 Token。

cat << 'EOF' > otel_conf/config.yaml
receivers:
  otlp:
    protocols:
      grpc: 
        endpoint: 0.0.0.0:4317

exporters:
  otlp:
    endpoint: ${GRPC_ENDPOINT}
    tls:
      insecure: true
    headers:
      "Authentication": "${GRPC_ENDPOINT_TOKEN}"

processors:
  batch:
  
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp]
EOF

五、建立後端服務(Node.js)

  1. 建立 package.json 檔案。檔案描述了專案的配置資訊,包括專案名稱、版本、依賴項等。

    cat << 'EOF' > backend/package.json
    {
      "name": "backend",
      "version": "1.0.0",
      "main": "index.js",
      "scripts": {},
      "keywords": [],
      "author": "",
      "license": "ISC",
      "description": "",
      "dependencies": {
        "@opentelemetry/api": "^1.9.0",
        "@opentelemetry/auto-instrumentations-node": "^0.52.0",
        "axios": "^1.7.7",
        "express": "^4.21.1"
      }
    }
    EOF
  2. 建立 main.js 檔案,包含一個基本的 Express 架構 Web 應用程式。

    cat << 'EOF' > backend/main.js
    "use strict";
    const axios = require("axios").default;
    const express = require("express");
    const app = express();
    app.get("/", async (req, res) => {
      const result = await axios.get("http://localhost:7001/hello");
      return res.status(201).send(result.data);
    });
    app.get("/hello", async (req, res) => {
      console.log("hello world!")
      res.json({ code: 200, msg: "success" });
    });
    app.use(express.json());
    app.listen(7001, () => {
      console.log("Listening on http://localhost:7001");
    });
    EOF
  3. 建立 Dockerfile 檔案。

    Nginx OTel 模組版本 ≥ 0.1.2

    cat << 'EOF' > backend/Dockerfile
    FROM node:20.16.0
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    ENV OTEL_TRACES_EXPORTER="otlp"
    ENV OTEL_LOGS_EXPORTER=none
    ENV OTEL_METRICS_EXPORTER=none
    ENV OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=grpc
    ENV OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="${GRPC_ENDPOINT}"
      export OTEL_EXPORTER_OTLP_HEADERS=Authentication=${GRPC_TOKEN}
    ENV OTEL_NODE_RESOURCE_DETECTORS="env,host,os"
    ENV OTEL_SERVICE_NAME="ot-nodejs-demo"
    ENV NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
    EXPOSE 7001
    CMD ["node", "main.js"]
    EOF

    Nginx OTel 模組版本 ≤ 0.1.1

    cat << 'EOF' > backend/Dockerfile
    FROM node:20.16.0
    WORKDIR /app
    COPY package*.json ./
    RUN npm install
    COPY . .
    ENV OTEL_TRACES_EXPORTER="otlp"
    ENV OTEL_LOGS_EXPORTER=none
    ENV OTEL_METRICS_EXPORTER=none
    ENV OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=grpc
    ENV OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://otel-collector:4317"
    ENV OTEL_NODE_RESOURCE_DETECTORS="env,host,os"
    ENV OTEL_SERVICE_NAME="ot-nodejs-demo"
    ENV NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
    EXPOSE 7001
    CMD ["node", "main.js"]
    EOF

六、建立 Docker Compose 檔案

該檔案定義了一個多容器應用程式的配置,包括 Nginx 反向 Proxy、OpenTelemetry Collector 和 Node.js 後端服務,以及它們之間的網路連接和連接埠映射。

Nginx OTel 模組版本 ≥ 0.1.2

cat << 'EOF' > docker-compose.yml
version: "3"

services:
  nginx:
    image: nginx:1.27.5-alpine-otel # 預設包含 0.1.2 版本 nginx-moduel-otel 模組的 nginx 鏡像
    volumes:
      - ./nginx_conf/nginx.conf:/etc/nginx/nginx.conf:ro 
      - ./nginx_conf/default.conf:/etc/nginx/conf.d/default.conf:ro 
    ports:
      - "80:80"
    networks:
      - nginx-otel-demo

  backend-api:
    build:
      context: ./backend
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=production
    ports:
      - "7001:7001"
    networks:
      - nginx-otel-demo

networks:
  nginx-otel-demo:
    driver: bridge
EOF

Nginx OTel 模組版本 ≤ 0.1.1

cat << 'EOF' > docker-compose.yml
version: "3"

services:
  nginx:
    image: nginx:1.27.2-alpine-otel # 預設包含 opentelemetry 模組的 nginx 鏡像
    volumes:
      - ./nginx_conf/nginx.conf:/etc/nginx/nginx.conf:ro 
      - ./nginx_conf/default.conf:/etc/nginx/conf.d/default.conf:ro 
    ports:
      - "80:80"
    networks:
      - nginx-otel-demo

  otel-collector:
    image: otel/opentelemetry-collector-contrib:latest
    volumes:
      - ./otel_conf/config.yaml:/etc/otelcol-contrib/config.yaml # 掛載 OpenTelemetry Collector 設定檔
    ports:
      - "4317:4317" # OTLP gRPC receiver
    networks:
      - nginx-otel-demo

  backend-api:
    build:
      context: ./backend
      dockerfile: Dockerfile
    environment:
      - NODE_ENV=production
    ports:
      - "7001:7001"
    networks:
      - nginx-otel-demo

networks:
  nginx-otel-demo:
    driver: bridge
EOF

七、啟動服務

  1. 在 nginx-otel-demo 目錄中執行以下命令。

    docker compose up -d

    預期輸出:

    Nginx OTel 模組版本 ≥ 0.1.2

    image

    Nginx OTel 模組版本 ≤ 0.1.1

    image (14).png

  2. 訪問應用。

    curl http://localhost:80/hello

    預期輸出:

    {"code":200,"msg":"success"}
  3. 登入可觀測鏈路 OpenTelemetry 版控制查看 Nginx 及後端服務的調用鏈。

    在本例中,Nginx 在應用列表頁面的名稱為 nginx,後端應用程式名稱為 ot-nodejs-demo。

常見問題

  1. 無法下載 nginx-module-otel,提示Unable to find a match: nginx-module-otel

    下載 nginx-module-otel 需要已配置  nginx packages repository,請檢查是否配置過 nginx packages repository。如未配置,配置操作請參見nginx-otel

  2. 在 Nginx 設定檔中添加 Nginx OTel 模組配置後,Nginx 啟動失敗。

    請使用nginx -t命令檢查 Nginx 配置是否正確,或查看 Nginx 日誌中的錯誤資訊。

    sudo tail -n 50 /var/log/nginx/error.log
  3. 啟用 Nginx OTel 模組後,在Managed Service for OpenTelemetry控制台沒有看到 Nginx 的調用鏈。

    請檢查 Nginx 配置中 otel_exporter.endpoint 是否配置正確。該地址由 OpenTelemetry Collector 地址以及 gRPC 接收器連接埠組成,例如localhost:4317。可通過查看 Nginx 日誌確認是否配置正確,當出現如下報錯時,說明 otel_exporter.endpoint 未配置正確。

    image (15).png

  4. Nginx 的調用鏈無法與其他應用串聯。

    請確保 Nginx 配置中添加了otel_trace_context propagate;,並確認其他應用使用的鏈路透傳協議與 Nginx 的透傳協議是否相同。Nginx OTel 模組使用 OpenTelemetry W3C 作為透傳協議,這需要其他應用也要使用 OpenTelemetry W3C 透傳協議才能串聯。

  5. Nginx OTel 外掛程式模組是否會對 Nginx 的效能產生影響?

    Nginx OTel 外掛程式模組為 Nginx 原生模組,官方提示該模組對 Nginx 效能的影響限制在10-15%。詳細資料,請參見NGINX Native OpenTelemetry (OTel) Module

相關連結