前情概要随着容器和云技术的发展, 大量的应用运行在云上的容器中, 它们的好处是毋庸置疑的, 例如极大的提高了我们的研发部署速度, 快速的扩缩容等等, 但是也存在一些小小的问题, 例如难以调试.基于VM的部署我们可以通过安全的方式登录到主机上做一些你想做的事情, 但是云上的容器那就是不太方便了(目前AWS的ECS已经有类似docker exec的方式直接进入容器中了, 其他的云未作了解).但是就算能进入容器也不意味着调试就好做了, 通常来说使用的镜像都是经过优化和精简的(如果要调式可能需要安装大量的组件).
所以, 接下来介绍一下使用dotnet-monitor 来内存转储(memory dump)运行在容器中的 dotnet 程序.
需要提前知晓的一些知识点什么是 dotnet-monitor?Announcing dotnet monitor in .NET 6 官方博客的原文:
Running a .NET application in diverse environments can make collecting diagnostics artifacts (e.g., logs, traces, process dumps) challenging. dotnet monitor is a tool that provides an unified way to collect these diagnostic artifacts regardless of whether running you’re running on your desktop machine or in a kubernetes cluster.There are two different mechanisms for collection of these diagnostic artifacts:An HTTP API for on demand collection of artifacts. You can call these API endpoints when you already know your application is experiencing an issue and you are interested in gathering more information.Triggers for rule-based configuration for always-on collection of artifacts. You may configure rules to collect diagnostic artifacts when a desired condition is met, for example, collect a process dump when you have sustained high CPU.
google翻译:
在不同的环境中运行 .NET 应用程序会使收集诊断工件(例如,日志、跟踪、进程转储)具有挑战性 。dotnet monitor是一个工具 , 它提供了一种统一的方式来收集这些诊断工件,无论您是在台式机上运行还是在 kubernetes 集群中运行 。
收集这些诊断工件有两种不同的机制:
用于按需收集工件的HTTP API。当您已经知道您的应用程序遇到问题并且您有兴趣收集更多信息时,您可以调用这些 API 端点 。基于规则的配置触发器,用于始终在线收集工件 。您可以配置规则以在满足所需条件时收集诊断工件,例如,当您持续使用高 CPU 时收集进程转储 。
dotnet-monitor工作在什么位置?借用官方博客中的一张图说明一下dotnet-monitor工作在什么地方
![使用dotnet-monitor sidecar模式 dump docker运行的dotnet程序.](http://img.zhejianglong.com/231018/2343124506-0.png)
文章插图
dotnet-monitor是如何能对我们的目标程序进行操作的?dotnet-monitor 可以连接到dotnet运行时公开的一个诊断端口(diagnostic port)(3.0新提供的新功能), 并通过自定义协议(ipc protocol)与运行时交互,
![使用dotnet-monitor sidecar模式 dump docker运行的dotnet程序.](http://img.zhejianglong.com/231018/2343122523-1.png)
文章插图
更多调试知识和工具例如ETW, eventpipe, lldb, dotnet-trace, dotent-counters 等可以查看 dotnet diagnostics.
目标应用程序容器准备首先, 我们得让我们被调试的目标程序公开这个诊断端口, 因为默认情况下这个诊断端口只能由运行这个程序的用户或者root用户来访问, 显然sidecar 模式启动的dotnet-monitor是不可能和目标程序用的是同一个用户的.
未作特别声明的话, 后文给出的实验都是基于AWS Fargate
和Linux
配置.
#添加环境变量DOTNET_DiagnosticPorts=/my_diagnostic_volume/diag.sock,suspend,connect
/my_diagnostic_volume/diag.sock
指 Unix Domain Socket
文件路径, my_diagnostic_volume
是挂载的一个volume.suspend
意思是让运行时等待dotnet-monitor 连接进来之后在执行托管代码.connect
接受dotnet-monitor连接, 详细解释看这里diagnostic ports上述配置的完整语法结构是 address[,(listen|connect)][,(suspend|nosuspend)]
详情请查看文档configure additional diagnostic ports如果我们的需要dump内存文件, 可能会遇到
WriteDumpAsync failed - HRESULT: 0x00000000
issues 1783这样的错误, 是因为权限问题.比如我在AWS Fargate
中遇到的就是 /dump
API 返回400错误 Write dump failed - HRESULT: 0x00000000
, 目标程序输出日志 ptrace(ATTACH, 1) FAILED Operation not permitted
.解决这个需要吧SYS_PTRACE权限给到目标程序. AWS Fargate
是编辑任务定义的json文件增加这一部分, docker 启动是通过增加--cap-add=SYS_PTRACE
参数.{"linuxParameters": {"capabilities": {"add": ["SYS_PTRACE"]}}}
最后, 配置目标程序容器依赖dotnet-monitor容器, 这样可以先让dotnet-monitor容器启动后, 在启动目标程序容器.到此, 目标程序容器的配置就完成了, 接下来配置dotnet-monitor
推荐阅读
- 如何使用支付宝付款(支付宝付款怎么追回)
- 支付宝使用详细教程(支付宝怎么扫码付款)
- 支付宝怎么规范使用(支付宝本人已故还可以使用吗)
- 怎样使用支付宝(支付宝不绑卡怎样付款)
- 支付宝怎么使用教程(支付宝怎么玩可以挣钱)
- 支付宝使用方法(支付宝怎么绑银行卡)
- 一次 Redis 事务使用不当引发的生产事故
- 还在使用@Autowrired注入?不妨试试@RequiredArgsConstructor
- Java并发编程 | Synchronized原理与使用
- python3使用mutagen进行音频元数据处理