Nginx R31 doc-17-debugging 調試

来源:https://www.cnblogs.com/houbbBlogs/p/18221286
-Advertisement-
Play Games

前言 大家好,我是老馬。很高興遇到你。 我們為 java 開發者實現了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何處理的,可以參考我的另一個項目: 手寫從零實現簡易版 tomcat minicat 手寫 ngin ...


前言

大家好,我是老馬。很高興遇到你。

我們為 java 開發者實現了 java 版本的 nginx

https://github.com/houbb/nginx4j

如果你想知道 servlet 如何處理的,可以參考我的另一個項目:

手寫從零實現簡易版 tomcat minicat

手寫 nginx 系列

如果你對 nginx 原理感興趣,可以閱讀:

從零手寫實現 nginx-01-為什麼不能有 java 版本的 nginx?

從零手寫實現 nginx-02-nginx 的核心能力

從零手寫實現 nginx-03-nginx 基於 Netty 實現

從零手寫實現 nginx-04-基於 netty http 出入參優化處理

從零手寫實現 nginx-05-MIME類型(Multipurpose Internet Mail Extensions,多用途互聯網郵件擴展類型)

從零手寫實現 nginx-06-文件夾自動索引

從零手寫實現 nginx-07-大文件下載

從零手寫實現 nginx-08-範圍查詢

從零手寫實現 nginx-09-文件壓縮

從零手寫實現 nginx-10-sendfile 零拷貝

從零手寫實現 nginx-11-file+range 合併

從零手寫實現 nginx-12-keep-alive 連接復用

NGINX 調試

通過調試二進位文件、調試日誌和核心轉儲來排除 NGINX 或 NGINX Plus 部署中的問題並追蹤錯誤。

介紹

調試幫助您在程式代碼出現問題時識別錯誤。它通常用於開發或測試第三方或實驗性模塊。

NGINX 調試功能包括調試日誌和創建核心轉儲文件以及進一步的回溯。

配置 NGINX 二進位文件進行調試

首先,您需要在 NGINX 二進位文件中啟用調試。NGINX Plus 已經為您提供了 nginx-debug 二進位文件,而 NGINX Open Source 需要重新編譯。

配置 NGINX Plus 二進位文件

從版本 8 開始,NGINX Plus 與標準二進位文件一起提供 nginx-debug 二進位文件。要在 NGINX Plus 中啟用調試,您需要從 nginx 切換到 nginx-debug 二進位文件。打開終端並運行以下命令:

service nginx stop && service nginx-debug start

完成後,在配置文件中啟用調試日誌。

編譯 NGINX Open Source 二進位文件

要在 NGINX Open Source 中啟用調試,您需要使用 configure 腳本中指定的 --with-debug 標誌重新編譯它。

要編譯支持調試的 NGINX Open Source:

  1. 下載並解壓 NGINX 源文件,轉到源文件所在的目錄。參見下載源代碼
  2. 獲取 NGINX 配置參數列表。運行命令:
nginx -V 2>&1 | grep arguments
  1. 將 --with-debug 選項添加到 configure 命令列表中並運行 configure 腳本:
./configure --with-debug <其他 configure 參數>
  1. 編譯和安裝 NGINX:
sudo make
sudo make install
  1. 重新啟動 NGINX。

NGINX 和調試符號

調試符號有助於獲取用於調試的附加信息,例如函數、變數、數據結構、源文件和行號信息。

NGINX 預設使用“-g”標誌編譯,其中包含調試符號。

但是,如果在運行回溯時出現“沒有可用的符號表信息”錯誤,則表示缺少調試符號,您需要重新編譯 NGINX 並支持調試符號。

確切的編譯器標誌取決於編譯器。例如,對於 GCC 編譯器系統:

  • 使用“-g”標誌包含調試符號
  • 使用“-O0”標誌禁用編譯器優化,使調試器輸出更易於理解:
./configure --with-debug --with-cc-opt='-O0 -g' ...

在 NGINX 配置中啟用調試日誌

調試日誌記錄錯誤和與調試相關的任何信息,預設情況下是禁用的。要啟用它,請確保 NGINX 已編譯支持調試(參見“為調試配置 NGINX 二進位文件”),然後在 NGINX 配置文件中使用 error_log 指令的 debug 參數啟用它。調試日誌可以寫入文件、記憶體中的分配緩衝區、標準錯誤輸出或 syslog。

建議在 NGINX 配置的“main”級別上啟用調試日誌,以獲得正在進行的完整情況。

將調試日誌寫入文件

將調試日誌寫入文件可能會在高負載下降低性能。還要註意,文件可能會變得非常大,快速消耗磁碟空間。為減少負面影響,您可以配置調試日誌寫入記憶體緩衝區,或為特定 IP 地址設置調試日誌。有關詳細信息,請參閱“將調試日誌寫入記憶體”和“選定 IP 的調試日誌”。

要啟用將調試日誌寫入文件:

  1. 確保您的 NGINX 配置了 --with-debug 配置選項。運行命令並檢查輸出是否包含 --with-debug 行:

    nginx -V 2>&1 | grep -- '--with-debug'
    
  2. 打開 NGINX 配置文件:

    sudo vi /etc/nginx/nginx.conf
    
  3. 查找 error_log 指令,預設情況下位於 main 上下文中,並將日誌級別更改為 debug。如果需要,更改日誌文件的路徑:

    error_log  /var/log/nginx/error.log debug;
    
  4. 保存配置並退出配置文件。

將調試日誌寫入記憶體

調試日誌可以使用迴圈緩衝區寫入記憶體。優點是,在高負載下,調試級別的日誌記錄對性能影響不大。

要啟用將調試日誌寫入記憶體:

  1. 確保您的 NGINX 配置了 --with-debug 配置選項。運行命令並檢查輸出是否包含 --with-debug 行:

    nginx -V 2>&1 | grep -- '--with-debug'
    
  2. 在 NGINX 配置文件中,使用在 main 上下文中指定的 error_log 指令啟用調試日誌的記憶體緩衝區:

    error_log memory:32m debug;
    ...
    http {
        ...
    }
    

從記憶體中提取調試日誌

可以使用在 GDB 調試器中執行的腳本從記憶體緩衝區中提取日誌。

要從記憶體中提取調試日誌:

  1. 獲取 NGINX 工作進程的 PID:

    ps axu |grep nginx
    
  2. 啟動 GDB 調試器:

    sudo gdb -p <在上一步中獲得的 nginx PID>
    
  3. 複製腳本,將其粘貼到 GDB 中並按“Enter”。該腳本將在當前目錄中的 debug_log.txt 文件中保存日誌:

    set $log = ngx_cycle->log
    while $log->writer != ngx_log_memory_writer
        set $log = $log->next
    end
    set $buf = (ngx_log_memory_buf_t *) $log->wdata
    dump binary memory debug_log.txt $buf->start $buf->end
    
  4. 通過按下 CTRL+D 退出 GDB。

  5. 打開位於當前目錄中的“debug_log.txt”文件:

    sudo less debug_log.txt
    

選定 IP 的調試日誌

可以為特定 IP 地址或 IP 地址範圍啟用調試日誌。在生產環境中,記錄特定 IP 可能很有用,因為它不會對性能產生負面影響。IP 地址在事件塊中的 debug_connection 指令中指定;該指令可以定義多次:

error_log /path/to/log;
...
events {
    debug_connection 192.168.1.1;
    debug_connection 192.168.10.0/24;
}

每個虛擬主機的調試日誌

通常,error_log 指令在主上下文中指定,因此適用於所有其他上下文,包括伺服器和位置。

但是,如果在特定伺服器或位置塊內指定了另一個 error_log 指令,則會覆蓋全局設置,並且這樣的 error_log 指令將設置自己的日誌文件路徑和調試日誌級別。

要為特定虛擬主機設置調試日誌,請在特定伺服器塊內添加 error_log 指令,並設置新的日誌文件路徑和調試日誌級別:

error_log /path1/to/log debug;
...
http {
    ...
    server {
    error_log /path2/to/log debug;
    ...
    }
}

要禁用特定虛擬主機的調試日誌,請在特定伺服器塊內指定 error_log 指令,並僅指定日誌文件路徑:

error_log /path/to/log debug;
...
http {
    ...
    server {
    error_log /path/to/log;
    ...
    }
}

啟用核心轉儲

核心轉儲文件可以幫助識別和修複導致 NGINX 崩潰的問題。核心轉儲文件可能包含諸如密碼和私鑰之類的敏感信息,因此請確保對它們進行安全處理。

為了創建核心轉儲文件,必須在操作系統和 NGINX 配置文件中都啟用它們。

在操作系統中啟用核心轉儲

在操作系統中執行以下步驟:

  1. 指定一個工作目錄,用於保存核心轉儲文件,例如“/tmp/cores”:

    mkdir /tmp/cores
    
  2. 確保該目錄可由 NGINX 工作進程寫入:

    sudo chown root:root /tmp/cores
    sudo chmod 1777 /tmp/cores
    
  3. 禁用核心轉儲文件的最大大小限制:

    ulimit -c unlimited
    

    如果操作以“Cannot modify limit: operation not permitted”結束,請運行以下命令:

    sudo sh -c "ulimit -c unlimited && exec su $LOGNAME"
    
  4. 為 setuid 和 setgid 進程啟用核心轉儲。

    • 對於 CentOS 7.0、Debian 8.2、Ubuntu 14.04,請運行以下命令:
    echo "/tmp/cores/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern
    sudo sysctl -w fs.suid_dumpable=2
    sysctl -p
    
    • 對於 FreeBSD,請運行以下命令:
    sudo sysctl kern.sugid_coredump=1
    sudo sysctl kern.corefile=/tmp/cores/%N.core.%P
    

在 NGINX 配置中啟用核心轉儲

要在 NGINX 配置文件中啟用核心轉儲:

  1. 打開 NGINX 配置文件:

    sudo vi /usr/local/etc/nginx/nginx.conf
    
  2. 使用 working_directory 指令定義一個目錄,該目錄將保存核心轉儲文件。該指令在主配置級別上指定:

    working_directory /tmp/cores/;
    
  3. 確保該目錄存在,並由 NGINX 工作進程寫入。在終端中運行以下命令:

    sudo chown root:root /tmp/cores
    sudo chmod 1777 /tmp/cores
    
  4. 使用 worker_rlimit_core 指令指定核心轉儲文件的最大可能大小。該指令也在主配置級別上指定。如果核心轉儲文件大小超過該值,將不會創建核心轉儲文件。

    worker_rlimit_core 500M;
    

    示例:

    worker_processes   auto;
    error_log          /var/log/nginx/error.log debug;
    working_directory  /tmp/cores/;
    worker_rlimit_core 500M;
    
    events {
        ...
    }
    
    http {
        ...
    }
    

通過這些設置,核心轉儲文件將在“/tmp/cores/”目錄中創建,只有當其大小不超過 500 兆位元組時才會創建。

從核心轉儲文件中獲取回溯信息

回溯提供了關於程式崩潰時出錯的信息。

要從核心轉儲文件中獲取回溯信息:

  1. 使用 GDB 調試器打開核心轉儲文件,命令格式為:

    sudo gdb <nginx_executable_path> <coredump_file_path>
    
  2. 輸入“backtrace”命令以從崩潰時的堆棧中獲取堆棧跟蹤信息:

    (gdb) backtrace
    

如果“backtrace”命令返回“沒有可用的符號表信息”消息,則需要重新編譯 NGINX 二進位文件以包含調試符號。請參閱NGINX和調試符號。

從運行中的進程中轉儲NGINX配置

您可以從主進程記憶體中提取當前的NGINX配置。當您需要:

  • 驗證已載入的配置
  • 如果磁碟上的版本被意外刪除或覆蓋,恢復以前的配置

配置轉儲可以通過提供一個GDB腳本來獲得,只要您的NGINX具有調試支持。

確保您的NGINX已經構建了調試支持(在configure參數列表中使用--with-debug選項)。運行命令並檢查輸出是否包含--with-debug行:

nginx -V 2>&1 | grep -- '--with-debug'

獲取NGINX工作進程的PID:

ps axu | grep nginx

啟動GDB調試器:

sudo gdb -p <在上一步中獲取的NGINX PID>

複製並粘貼腳本到GDB中,然後按“Enter”鍵。該腳本將配置保存在當前目錄中的nginx_conf.txt文件中:

set $cd = ngx_cycle->config_dump
set $nelts = $cd.nelts
set $elts = (ngx_conf_dump_t*)($cd.elts)
while ($nelts-- > 0)
set $name = $elts[$nelts]->name.data
printf "Dumping %s to nginx_conf.txt\n", $name
append memory nginx_conf.txt \
      $elts[$nelts]->buffer.start $elts[$nelts]->buffer.end
end

按下CTRL+D退出GDB。

打開位於當前目錄中的nginx_conf.txt文件:

sudo vi nginx_conf.txt

在請求幫助時
在請求調試幫助時,請提供以下信息:

  • NGINX版本、編譯器版本和配置參數。運行命令:
nginx -V
  • 當前完整的NGINX配置。請參閱從運行進程中轉儲NGINX配置

  • 調試日誌。請參閱在NGINX配置中啟用調試日誌

  • 獲取的回溯。請參閱啟用核心轉儲,獲取回溯信息。

參考資料

https://docs.nginx.com/nginx/admin-guide/monitoring/debugging/


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1️⃣ 原因 由於是一個比較老的項目,所以在做功能時,用到了老項目的一個控制項,這一個控制項是以前封裝好的,依賴的是jquery-1.6.min.js。但是在做下拉框多選功能時,在網上找了一個下拉框多選的框架,但是這個框架依賴是jquery.js(3.7.1),所以才出現了這個問題。 簡單來說就是新老控 ...
  • 1、是什麼 pointer-events 直譯為指針事件,該屬性指定在什麼情況下某個DOM可以成為滑鼠事件的 target。 簡而言之,就是允許/禁止DOM的滑鼠事件(click事件、hover事件、mouse事件等滑鼠事件) 2、具體屬性分析 用法分析:pointer-events: auto | ...
  • 前言 眾所周知,當子組件使用setup後,父組件就不能像vue2那樣直接就可以訪問子組件內的屬性和方法。這個時候就需要在子組件內使用defineExpose巨集函數來指定想要暴露出去的屬性和方法。這篇文章來講講defineExpose巨集函數是如何暴露出去這些屬性和方法給父組件使用。註:本文中使用的vu ...
  • 最近在做滑鼠框選的需求,滑鼠框選就需要用到 Range 和 Selection 對象。 Range 表示選擇的區間範圍,Selection 表示選擇的文檔內容。 Range 介面表示一個包含節點與文本節點的一部分的文檔片段。 不僅僅可以用於滑鼠框選,頁面上任何元素、文本都可以創建 Range。 Se... ...
  • 一、遞歸 遞歸(英語:Recursion) 在數學與電腦科學中,是指在函數的定義中使用函數自身的方法 在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數 其核心思想是把一個大型複雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解 一般來說,遞歸需要有邊界條件、 ...
  • title: 理解Vue 3響應式系統原理 date: 2024/5/28 15:44:47 updated: 2024/5/28 15:44:47 categories: 前端開發 tags: Vue3.x TypeScript SFC優化 Composition-API Ref&Reactive ...
  • 我們知道,lua通過package模塊來管理模塊的搜索和載入,當使用require首次成功載入一個模塊後,模塊(Table)會被存儲在package.loaded中,之後的require行為會直接獲取到已載入的模塊緩存。 如何在程式執行時,將對模塊文件的修改熱更新到程式中,同時確保運行時狀態的正常。 ...
  • 1. 枚舉的由來 當我們知道所有變數的可能性時,儘量使用枚舉類型來定義,比如季節,春夏秋冬,一周(一二三四五六七),只讀不需要修改 有限的一個一個列舉出來的類叫做枚舉類,枚舉是一組常量的集合,枚舉也是一個特殊的類,裡面包含了一組有限的特定對象 2. 自定義實現枚舉 不需要提供set方法,因為枚舉對象 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...