• 如何在 Docker 环境下自动给 .NET 程序生成 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 
    
    procdump -M 200 -w dotnet & 
    
    dotnet $1 
    
    " > ./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

  • 相关阅读:
    百度之星初赛 A
    百度之星 初赛 BC
    2016 百度之星资格赛
    codeforces 749
    codeforces 785
    HDU 4617
    网络流 poj 2195
    网络流 poj 3436 poj 3281
    codeforces 780 C
    idea激活
  • 原文地址:https://www.cnblogs.com/Rwing/p/docker-net-auto-dump.html
Copyright © 2020-2023  润新知