---
title: "使用 Prometheus 監控 Nginx 請求"
description: "示範如何以 Docker Compose 部署 Prometheus 與 Grafana，透過 nginx-prometheus-exporter 監控 Nginx 請求指標，並使用 K6 進行壓力測試驗證效果。"
canonical_url: "https://blog.markkulab.net/post/prometheus-monitoring-nginx-requests"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/author/mark-ku"
site: "Mark Ku's Blog"
date_published: "2024-11-25T01:01:35+08:00"
category: "Cloud"
tags: ["prometheus", "grafana", "nginx", "docker", "monitoring", "k6"]
language: "zh-TW"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "轉載或引用請註明作者並附上原文連結"
---

# 使用 Prometheus 監控 Nginx 請求

## 前言
Prometheus 和 Grafana 是 Kubernetes 生態系統中的常見組合，這篇文章+將展示如何使用 Prometheus 監控 Nginx 請求，並利用 Grafana 進行數據可視化。

## 了解 Nginx 的 `stub_status`

在啟動 Prometheus 容器應用前，讓我們先了解 Nginx 的 `stub_status` 模組，它提供了關於 Nginx 運行狀態的基本指標，Prometheus 主要是透過，stub_status 獲取 nginx 上的資訊。

### 設定 Dockerfile

首先，創建一個 Dockerfile，基於 Nginx 映像檔進行自訂設定：

```dockerfile
FROM nginx
COPY nginx.conf /etc/nginx/conf.d/default.conf
```

### 建立 `nginx.conf`

接著，編寫 `nginx.conf` 設定文件來啟用 Nginx 的狀態頁面，這將暴露供 Prometheus 爬取：

```nginx
server {
    listen 80;  # 使用本地端口
    server_name localhost;  # 設定為 localhost

    location /nginx_status {
        stub_status on;  # 啟用狀態模組
        access_log off;
        allow all;  # 允許所有 IP 訪問
    }
}
```

### 建置並啟動容器

使用以下命令建置 Docker 映像並啟動容器：

```bash
docker build -t my-nginx:latest .
docker run -d -p 8881:80 --name nginx-prometheus-exporter my-nginx:latest
```

## 訪問 Nginx 狀態頁面

啟動容器後，訪問 `http://localhost:8881/nginx_status`，你會看到類似以下的頁面：

![Nginx Status](https://blog.markkulab.net/content/markku/posts/prometheus-monitoring-nginx-requests/images/nginx-status.png)

### Nginx 狀態資訊

**Active connections: 2**  
   目前有 2 個活動連線。  

**server accepts handled requests: 2 2 2**  
   - **2**：已接受的連線數。  
   - **2**：已成功處理的連線數。  
   - **2**：總請求數（可能大於連線數，因為每個連線可以處理多個請求）。  

**Reading: 0 Writing: 1 Waiting: 1**  
   - **Reading: 0**：正在讀取請求的連線數。  
   - **Writing: 1**：正在傳送響應的連線數。  
   - **Waiting: 1**：空閒等待新請求的連線數（使用 HTTP Keep-Alive）。  
P.S.當前伺服器負載較輕，共有 2 個連線，其中 1 個正在處理請求，1 個處於等待新請求的狀態。

## 容器應用說明
grafana ( 報表呈現 ) ＞ prometheus-exporter ( 主動爬取資料 ) > nginx/nginx-prometheus-exporter (將這些數據暴露給 Prometheus的工具 ) > nginx status  ( 網站服務器，提供網頁伺服器的狀態 )

## 建立及啟動相關容器應用

刪除先前的測試容器，接下來，我們建立 `deployment.yaml` 文件來部署包含所有服務的 Docker 容器。

### `deployment.yaml` 範例

```yaml
version: "3.8"
services:
  mynginx:
    build: ./nginx/
    container_name: mynginx
    ports:
      - 8885:80

  nginx-prometheus-exporter:
    image: nginx/nginx-prometheus-exporter
    container_name: nginx-prometheus-exporter
    command: -nginx.scrape-uri http://nginx:80/nginx_status
    ports:
      - 9113:9113
    depends_on:
      - nginx

  prometheus:
    image: prom/prometheus:v2.35.0
    container_name: prometheus
    volumes:
      - ./prometheus.yaml:/etc/prometheus/prometheus.yaml
      - ./prometheus_data:/prometheus
    command:
      - "--config.file=/etc/prometheus/prometheus.yaml"
    ports:
      - "9090:9090"

  renderer:
    image: grafana/grafana-image-renderer
    environment:
      BROWSER_TZ: Asia/Taipei
    ports:
      - "8082:8081"

  grafana:
    image: grafana/grafana
    container_name: grafana
    volumes:
      - ./grafana_data:/var/lib/grafana
    environment:
      GF_SECURITY_ADMIN_PASSWORD: pass
      GF_RENDERING_SERVER_URL: http://renderer:8082/render
      GF_RENDERING_CALLBACK_URL: http://grafana:3007/
      GF_LOG_FILTERS: rendering:debug
    depends_on:
      - prometheus
      - renderer
    ports:
      - "3007:3000"
```

### 設置 Prometheus 設定

編寫 `prometheus.yaml` 來設定 Prometheus 如何抓取數據。

```yaml
global:
  scrape_interval: 5s  # 設定抓取頻率
  external_labels:
    monitor: "my-monitor"

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]
  - job_name: "nginx_exporter"
    static_configs:
      - targets: ["nginx-prometheus-exporter:9113"]
```
使用 Docker Compose 啟動容器服務：

```bash
docker-compose -f ./deployment.yaml up -d
```

## 查看 Prometheus Targets

在瀏覽器中打開 [http://localhost:9090/targets](http://localhost:9090/targets)，你可以查看 Prometheus 採集器的目標狀態。

![Prometheus Targets](https://blog.markkulab.net/content/markku/posts/prometheus-monitoring-nginx-requests/images/prometheus-target.png)

## 使用 Prometheus 繪製 Nginx 指標圖表

切換 Prometheus 的 Graph 頁籤，搜尋`nginx`，可以根據 Nginx 的指標繪製即時圖表：

![Prometheus Graph](https://blog.markkulab.net/content/markku/posts/prometheus-monitoring-nginx-requests/images/prometheus-graph.png)

然而，Prometheus 的報表較為簡單。如果你需要更精美的圖表或更多篩選選項，可以使用 Grafana 來展示。

## 設定 Grafana 連接 Prometheus

1. 打開 Grafana 儀表板（[http://localhost:3007/](http://localhost:3007/)）。
2. 進入 "Connection" 部分，點擊 "Add new connection" 並選擇 "Prometheus"。

![Grafana Prometheus](https://blog.markkulab.net/content/markku/posts/prometheus-monitoring-nginx-requests/images/grafana-add-prometheus.png)

## 建立 Grafana Dashboard

你可以從 [Grafana Dashboard 市集下](https://grafana.com/grafana/dashboards/)載現成的模板，來展示 Nginx 的指標。

### 下載 Dashboard 範本

[下載 Dashboard JSON](https://grafana.com/grafana/dashboards/18144-nginx2/)

![Download Dashboard Settings](https://blog.markkulab.net/content/markku/posts/prometheus-monitoring-nginx-requests/images/download-dashboard-json.png)

## 匯入 Dashboard 模板
回到 Grafana 儀表板，點擊 "New Import" 並導入你下載的 JSON 模板。
![Import Dashboard Settings](https://blog.markkulab.net/content/markku/posts/prometheus-monitoring-nginx-requests/images/import-dashboard.png)

## 執行 K6 壓測

撰寫 K6 壓力測試腳本，模擬流量並驗證 Nginx 性能：

```javascript
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 3000 },  // 負載測試從 0 到 3000 個虛擬使用者，持續 30 秒
    { duration: '1m30s', target: 3000 }, // 維持 3000 個虛擬使用者，持續 1 分 30 秒
    { duration: '20s', target: 0 },      // 減少虛擬使用者數量
  ]
};

export default function () {
  const res = http.get('http://192.168.0.88:8885/nginx_status'); // your nginx ip 
  check(res, { 'status was 200': (r) => r.status == 200 });
  sleep(1);
}
```

使用 Docker 版本的 K6，無需額外安裝，直接執行壓力測試：

```
// Windows 腳本
cat script.js | docker run --rm -i grafana/k6 run -
```
## 查看 Grafana 儀表板上的即時數據

進行壓力測試後，Grafana 儀表板將即時顯示 Nginx 的連線數量等指標。

![Grafana Live Data](https://blog.markkulab.net/content/markku/posts/prometheus-monitoring-nginx-requests/images/final-dashboard.png)

## 相關程式碼
所有程式碼和設定檔都可以在 [GitHub Repo](https://github.com/markku636/Prometheus) 上找到。

## 參考資料
* [使用 Prometheus 和 Grafana 打造監控預警系統 (Docker 篇)](https://pin-yi.me/blog/docker/prometheus-grafana-docker/#prometheus)
* [prometheus-adapter结合custom metrics API 实现kubetnetes自定义HPA](https://blog.csdn.net/weixin_43391291/article/details/142212854)

---

## 關於本文與作者

本文出自 [Mark Ku's Blog](https://blog.markkulab.net/post/prometheus-monitoring-nginx-requests)

授權條款： [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — 轉載或引用請註明作者並附上原文連結

### 關於作者

**[Mark Ku](https://blog.markkulab.net/author/mark-ku)** — Software Solution Provider

- 10+ 年資深軟體工程師，現為 AI 應用 Builder
- 專注大型平台架構設計，從北美電商到AI SaaS訂閱收費系統
- 結合 AI Agent 與自動化，打造高效可演進的產品技術基礎

### 作者開發的免費工具

以下工具皆可免費使用：

- [免費 PDF 簽名工具](https://blog.markkulab.net/tools/pdf-sign): 線上 PDF 簽名工具，瀏覽器內完成手繪、打字、上傳簽名，可拖曳放置、縮放、下載。所有處理都在你的裝置完成，檔案不會上傳。
- [VS Code Refactory](https://blog.markkulab.net/tools/refactory): Refactory 是一款 VS Code 重構擴充套件：34 個重構動作、37 條 code smell 檢查、Code Health 儀表板、18 種語言、534 支測試。懂你的專案慣例：介面放哪、DI 註冊寫在哪、'use client' 該不該加；還會用 git 修改頻率 × 複雜度排出「該先修哪個檔案」，並一鍵把壞味道交給你自己電腦上的 Claude Code 修。免費使用，原始碼不離開你的機器。
- [DB-Kit 資料庫管理工具](https://blog.markkulab.net/tools/db-kit): DB-Kit 是一個用 Tauri + Rust + React 打造的輕量跨平台資料庫管理工具，用單一一致的介面同時管理 MySQL、MariaDB、PostgreSQL、SQL Server、Oracle、SQLite、MongoDB、Redis、Kafka、Elasticsearch 與 RabbitMQ 十一種資料來源：連線密碼以 OS keychain 加密、SSH Tunnel、完整 CRUD、視覺化查詢建構器、多結果集同時顯示、跨連線資料傳輸與比對同步、Excel / CSV 匯入匯出、執行計畫視覺化、ER 圖、排程備份、SQL 壓力測試（p50～p99 延遲百分位）、15 條規則的 SQL 審查、Kafka 訊息瀏覽與監控告警；繁中 / 英文雙語介面，內建 AI 助手（自然語言生成 SQL、AI 審查與調校建議）與命令列工具 dbk。免費開源（MIT），提供 Windows / macOS / Linux 安裝檔。
- [VS Code Super Mermaid](https://blog.markkulab.net/tools/super-mermaid): Super Mermaid 是一款 VS Code 擴充套件：開箱即用的漂亮 Mermaid 圖表，自動上色、即時預覽、滑鼠平移縮放、PNG / SVG 高解析匯出，內建 21 種範本與多種主題。免費開源（MIT）。
- [React Super Mermaid](https://blog.markkulab.net/tools/react-super-mermaid): react-super-mermaid 是一個開源 React 元件庫：一行 <MermaidViewer> 即可渲染漂亮的 Mermaid 圖表，內建 colorful / sketch 主題、平移縮放、圖內搜尋、SVG / PNG 高解析匯出。輕量、SSR 安全、完整 TypeScript 型別。免費開源（MIT）。
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/tools/jira-super-mermaid): Atlassian Forge app：在 Jira issue 與 Confluence 內文直接寫 Mermaid 語法，畫流程圖、時序圖、狀態機與甘特圖。11 種圖表、SVG / PNG 匯出、明暗主題、完整中日韓文字支援。取得 Runs on Atlassian 資格：圖表存在你自己的站台，app 不呼叫任何第三方服務。免費，即將上架 Atlassian Marketplace。
- [Mermaid 線上預覽](https://blog.markkulab.net/tools/mermaid-preview): 在瀏覽器裡寫 Mermaid、即時看圖，整張圖表壓進網址就能分享。免註冊、不上傳伺服器，相容 mermaid.live 的分享連結。
- [React Intl Phone Number](https://blog.markkulab.net/tools/react-intl-phone-number): react-intl-phone-number 是一個開源 React 元件：framework-agnostic、不依賴 antd，提供 E.164 進出、可搜尋國旗 / 國碼下拉、可配置驗證等級（strict / mobile-strict / loose）、可主題化 CSS 與 i18n，電話邏輯由 google-libphonenumber 驅動。輕量、完整 TypeScript 型別。免費開源（MIT）。
- [Uptime Kuma Cluster](https://blog.markkulab.net/tools/uptime-kuma-cluster): 把單機版 Uptime Kuma 改造成高可用叢集：OpenResty + Lua 智慧負載平衡、MariaDB 共享狀態、健康檢查與自動 Failover，附叢集管理 REST API，一行 Docker Compose 啟動。免費開源（MIT）。
- [特教專案](https://blog.markkulab.net/education): 為特殊教育學生製作的學習教材

### 每日 Podcast

- [科技新鮮事](https://blog.markkulab.net/category/tech-news): 每日精選 AI 與科技趨勢，透過語音摘要快速掌握最新技術動態，涵蓋 AI 應用、軟體架構、DevOps 與工程實戰。 — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/category/ai-stock-chat): 每個交易日用 AI 分析台股盤勢，以雙人對話聊當天的盤中觀察與隔日預測。 — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml

### 電子報

[訂閱電子報](https://blog.markkulab.net/subscribe) — 第一時間收到新文章通知，無垃圾信、隨時可取消訂閱。
