如何在 Docker 環境下自動給 .NET 程式生成 Dump
2021-06-02 08:31
Rwing
閱讀(8)
評論(0)
編輯
收藏
之前“一線碼農”大佬有寫文章介紹了如何在windows下自動dump,正好手裡有個在 docker 環境下 dump 的需求,是以在參考大佬文章的基礎上,有了本篇。
前言
之前“一線碼農”大佬有寫文章介紹了如何在 windows 下自動 dump,正好手裡有個在 docker 環境下 dump 的需求,是以在參考大佬文章的基礎上,有了本篇。
工具
dotnet-dump (https://docs.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-dump)
ProcDump for linux (https://github.com/Sysinternals/ProcDump-for-Linux)
dotnet-dump
dotnet-dump是微軟官方推出的一個.NET全局工具,安裝和使用都非常簡單。
安裝:
dotnet tool install --global dotnet-dump
使用:
dotnet-dump collect --process-id 1902 # pid
但是它不能夠自動dump(也可能是我不知道),是以本文主要讨論下面這個工具
ProcDump for linux
本工具是 ProcDump 的社群 linux 移植版,不過主要開發人員也是微軟的員工。
它可以實作根據 CPU 占用 、記憶體占用、線程數等情況進行自動 dump,我們以此來應對程式出現異常時需要dump檔案進行分析的場景。
安裝
在 Dockerfile中添加以下指令:
注意我們要在運作時的鏡像中添加,并且最好是自行建構一個基礎鏡像,而不是每次都進行安裝。
# final stage/image
FROM mcr.microsoft.com/dotnet/aspnet:5.0
# 安裝所需依賴
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
wget \
gdb \
lldb
# 安裝 procdump
RUN wget https://packages.microsoft.com/repos/microsoft-debian-buster-prod/pool/main/p/procdump/procdump_1.1.1-220_amd64.deb -O procdump.deb \
&& dpkg -i procdump.deb \
&& rm procdump.deb
本文基于 aspnet:5.0 鏡像,即 debian 10,如果基于其他鏡像,可去下面目錄中尋找對應的包
https://packages.microsoft.com/repos/
也可參考作者提供的安裝說明
運作
因為 docker 容器并不能很友善的在啟動時同時執行多個程序,是以我們需要一個sh檔案以便在啟動時同時執行dotnet和procdump。
因為我個人不喜歡在 Dockerfile 之外還要依賴其他檔案,是以我直接在 Dockerfile 裡進行了sh檔案的建立
RUN echo "#!/bin/bash \n\
procdump -M 200 -w dotnet & \n\
dotnet \$1 \n\
" > ./start.sh
RUN chmod +x ./start.sh
ENTRYPOINT ["./start.sh", "<YourApp>.dll"]
如果有需要的話,也可以自行建立一個start.sh,内容為
#!/bin/bash
procdump -M 200 -w dotnet &
dotnet $1
Dockerfile 改為
COPY start.sh ./start.sh
RUN chmod +x ./start.sh
ENTRYPOINT ["./start.sh", "<YourApp>.dll"]
這樣就可以了,在docker run的時候會同時啟動dotnet和procdump,并且當記憶體大于200M的時候會自動dump。
還有一點要注意,docker run的時候需要添加--privileged 以提高權限。例如docker run --privileged -it xx
其中 procdump 的各個參數為
Usage: procdump [OPTIONS...] TARGET
OPTIONS
-h Prints this help screen
-C 當CPU超過或等于指定值(0到100 * nCPU)時,觸發核心轉儲生成。
-c 當CPU小于指定值(0到100 * nCPU)時觸發核心轉儲生成。
-M 當記憶體送出超過或等于指定值(MB)時,觸發核心轉儲生成
-m 當記憶體送出小于指定值(MB)時,觸發核心轉儲生成。
-T 當線程數超過或等于指定值時觸發。
-F 當檔案描述符計數超過或等于指定值時觸發。
-I Polling frequency in milliseconds (default is 1000)
-n Number of core dumps to write before exiting (default is 1)
-s Consecutive seconds before dump is written (default is 10)
-d Writes diagnostic logs to syslog
TARGET 以下二選一:
-p 程序的 pid
-w 程序的名字
舉例來說,以下指令表示當 CPU 使用率為>= 65%或記憶體為>= 100 MB 時建立一個 dump 檔案
procdump -C 65 -M 100 -p 1234
其他
dump 檔案的持久化
大家都知道 docker 容器消失的話,那麼其中的 dump 檔案也會消失。
是以需要輸出 dump 檔案到一個指定的、進行過持久化挂載的卷中,不過可惜的是,目前procdump for linux還沒有一個輸出參數來控制輸出目錄,隻會在應用程式的同級目錄生成,是以現在需要手動移動一下。
我看已經有人提了 PR,未來會增加一個 -o 參數以控制輸出。
參考
https://www.cnblogs.com/huangxincheng/p/14661031.html
https://docs.docker.com/config/containers/multi-service_container/
https://github.com/msbrz/procdump-docker
- 分類 01.文章
-
标簽 Dump
, Docker
, .net