.NET Core dump 分析

服务 CPU 或 内存偶尔飙高是部署环境中经常遇到的问题,一般会采用记录日志的方式来诊断,不过有些情况靠日志可能并不能分析出个所以然,面对实在无头绪的问题也只能暂时使用重启大法先恢复。

为了尽可能精准的定位问题,掌握通过 dump 分析服务运行堆栈信息也是非常必要的,本文将分别介绍如何对 .NET Core 2.2 和 .NET Core 3.1 项目进行 dump 分析(这里只针对 Linux 下使用容器部署的方式)。

创建 dump 文件

在创建 dump 文件之前,最好先查看具体是服务中哪些线程引发的异常,然后针对特定线程进行分析,不然全扫一遍将是一件非常耗时的工作。

进入容器后,安装 htop:

apt-get update
apt-get install htop

通过 htop 查看资源使用情况:

以上是测试程序模拟的状况,可知 PID 12 是需要关注的线程

执行以下命令即可创建 dump 文件(这里以 2.2.8 为例,另外可通过 createdump --help 查看更多参数设置,容器内默认 dotnet 进程对应 pid 均为 1):

/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.8/createdump 1

命令执行完成后,将生成 dump 文件 /tmp/coredump.1,我们需要通过 docker cpkubectl cpcoredump.1  文件复制到主机目录下,然后下载到用于 dump 分析的机器上。

**注意:**在 Docker 部署模式下,createdump 命令执行需要有容器特权,所以在容器启动时需要加 --privileged = true 参数。另外 dump 文件生成需要使用较大内存,需适当调整容器内存限制参数。

.NET Core 2.2

目前大多使用 lldb 进行分析,但从零开始搭建环境实在有些折腾,不推荐。网上已有封装好的镜像可直接使用,如:6opuc/lldb-netcore[1]6opuc/lldb-netcore 默认是基于 .NET Core SDK 2.2.8 构建的镜像,如果当前要 dump 的服务 .NET Core 版本非 2.2.8,则需要修改 lldb-netcore 源码[2] 重新构建镜像。

执行以下命令进入 lldb:

docker run --rm -it -v /root/coredump.1:/tmp/coredump 6opuc/lldb-netcore

查看当时运行的线程:

clrthreads -live

指定需要分析的线程编号(PID 12 的线程对应的 16 进制为 c,所以找到 OSID 为 c 的记录,对应编号为 7【第一列】

thread select 7

查看当前线程在托管代码中的堆栈信息

clrstack

更多命令可通过执行 soshelp 查看

.NET Core 3.1

.NET Core 3 开始,官方已提供 dotnet-dump[3] 工具进行 dump 分析,使用起来也相对简单,当然我们依然可以继续使用 lldb 的方式。

安装 dotnet-dump

dotnet tool install --global dotnet-dump --version 3.1.141901

进入分析

dotnet-dump analyze /root/coredump.1

如果出现以下错误,说明 .NET Core SDK 没有安装到 /usr/shard/dotnet 路径下,可通过 DOTNET_ROOT 单独指定或重新安装。

查看正在运行的托管线程:

clrthreads

如果出现以下错误,是因为当前安装的 .NET Core SDK 版本与容器内 createdump 使用的 SDK 版本不一致(如:createdump 使用 3.1.3,分析使用 3.1.12)。

指定当前需要分析的线程 DBG

setthread 7

查看当前线程在托管代码中的堆栈信息

clrstack

更多 dotnet-dump 命令请查看:https://docs.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-dump#analyze-sos-commands

案例说明

以下是生产环境中遇到的一个具体案例,有一服务运行一段时间就会出现 CPU 100%,而且也降不下来,如下监控:

通过锁定异常线程后,多次 dump 并对堆栈信息进行分析,发现出问题时都和以下代码相关:

这里使用了一个表达式计算的开源组件 NCalc[4] ,初步判断可能是表达式本身的不合法引起的循环解析,通过 dumpobj 对方法参数的查看,发现都是很正常的表达式,所以猜测并不成立。

继续在 Github 项目中的 issues 进行查找可能存在的类似问题,发现在较早版本中,确实存在卡死的现象 https://github.com/sklose/NCalc2/issues/22,这个问题在新版本中已修复,而我们出问题的这个服务使用的 NuGet 包确实是比较老的一个版本,所以问题基本上可以定位,在经过 NuGet 包版本升级后,这种现象终于消失了。

总结

实际在遇到棘手问题的时候,可能经常毫无头绪,太多问题都不是那么容易定位的。在构建服务支持业务能力的同时,要注意代码本身的健壮性,在使用外部组件时,需要多关注其生态情况,dump 分析只是一种协助解决问题的手段。

参考资料

[1]

6opuc/lldb-netcore: https://hub.docker.com/r/6opuc/lldb-netcore

[2]

lldb-netcore 源码: https://github.com/6opuc/lldb-netcore

[3]

dotnet-dump: https://docs.microsoft.com/zh-cn/dotnet/core/diagnostics/dotnet-dump

[4]

NCalc: https://github.com/sklose/NCalc2

分享、点赞,再看、三连走一波

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外国人最常说的100个“中国词”出炉,第一个你绝对想不到…

近几年,“汉语热”在全球兴起,外国人说的念的中国词儿变多了!那外国人最常说的、最热的“中国词”到底是啥呢?2月17日,中国外文局首次发布《中国话语海外认知度调研报告》。报告显示,近两年中国话语以汉语拼…

python 什么可以作为变量名_为什么强烈禁止开发人员使用isSuccess作为变量名

在日常开发中,我们会经常要在类中定义布尔类型的变量,比如在给外部系统提供一个RPC接口的时候,我们一般会定义一个字段表示本次请求是否成功的。关于这个”本次请求是否成功”的字段的定义,其实是有很多种讲究和坑的,稍…

自建Git服务器系列——Gitea(Gogs的孪生兄弟)

概述该项目的目标是提供一种最简单,最快,最轻松的方式来建立自托管的Git服务。使用Go,可以在Go支持的所有平台上进行独立的二进制分发 ,包括x86,amd64,ARM和PowerPC体系结构上的Linux,macOS和Wi…

干货|吴恩达Coursera课程教你学习神经网络!

吴恩达Coursera机器学习课程系列笔记讲解课程笔记|吴恩达Coursera机器学习 Week1 笔记-机器学习基础干货|机器学习零基础?不要怕,吴恩达机器学习课程笔记2-多元线性回归干货|机器学习零基础?不要怕,吴恩达课程笔记第三周&#xff…

笔记本内置扬声器三强PK

内置扬声器PK要点外观设计差异。外表是否美观直接影响使用者的心情,扬声器的结构设计直接影响放音效果。实际听音较量。利用真实的人耳感受则是最能体现扬声器实际效果的。奥特蓝星:音质纯净,低音欠佳代表机型:惠普,华…

mysql内连接查询原理_MySQL全面瓦解12:连接查询的原理和应用

概述MySQL最强大的功能之一就是能在数据检索的执行中连接(join)表。大部分的单表数据查询并不能满足我们的需求,这时候我们就需要连接一个或者多个表,并通过一些条件过滤筛选出我们需要的数据。了解MySQL连接查询之前我们先来理解下笛卡尔积的原理。数据…

如何在 .NET 中使用 Kafka

Kafka 是一个开源的,分布式的,可扩展的,高性能的发布订阅模式的消息中间件,如果你要构建一个处理海量数据的系统,那么 Kafka 将会是一个非常好的选择,这篇文章我们将会讨论如何基于 Kakfa 构建一个发布订阅…

傅里叶变换和拉普拉斯变换的物理解释及区别

傅里叶变换在物理学、数论、组合数学、信号处理、概率论、统计学、密码学、声学、光学、海洋学、结构动力学等领域都有着广泛的应用(例如在信号处理中,傅里叶变换的典型用途是将信号分解成幅值分量和频率分量)。傅里叶变换能将满足一定条件的…

Teleport 开源堡垒机的使用

公司的服务器可能会存在这样一种情况,具体的应用是部署在一个或多个内网服务器上,然后由一台外网服务器通过代理的方式对外提供服务,例如下图:我们如果需要进入到内网服务器进行操作就必须先要进入外网服务器,然后再远…

python拼图游戏_乐趣无穷的Python课堂

Python world/特慧编/你所认为的.........pythonpython&枯燥、无趣boring“安全”提示走进特慧编走进“python编程课”让我们进入真正的编程世界,培养逻辑数理思维,学习掌握python特色,让你的学习过程不再枯燥、不再无趣~~~下面跟着我的脚…

让 Python 更加充分的使用 Sqlite3

我最近在涉及大量数据处理的项目中频繁使用 sqlite3。我最初的尝试根本不涉及任何数据库,所有的数据都将保存在内存中,包括字典查找、迭代和条件等查询。这很好,但可以放入内存的只有那么多,并且将数据从磁盘重新生成或加载到内存…

techempower之Plaintext上7百万RPS

在Plaintext这项测试中第一阶梯的分隔线基本算是7百万RPS,Beetlex并没有到到这一阶梯停留在69X万RPS处,虽然只差那数万但在排名上让人感觉不爽。Beetlex在很多项测都微微领先aspcore,但在最基础项落下一点点的确让我感觉到不太满意,更希望Bee…

详解全排列算法

简介给定 {1, 2, 3, , , n},其全排列为 n! 个,这是最基础的高中组合数学知识。我们以 n4 为例,其全部排列如下图(以字典序树形式来呈现):我们很容易想到用递归来求出它的所有全排列。仔细观察上图&#xff…

VS2019 调试技巧之附加进程

C# 创建服务并附加到进程进行调试步骤一:在任务栏右键-》》点击任务管理器-》》选择服务,找到启动的进程PID或者WINR 进入cmd命令 输入 netstat -ano | find "进程端口" 找端口步骤二:VS中找到“调试”菜单,选择“…

sql同时向两个表插入数据_SQL入门-数据库和客户端的安装,表的创建和数据插入...

1、如何验证MySQL数据库安装成功按照上图操作打开SQL命令行客户端输入安装MySQL时设置的密码并按enter键,得到下图:如果有显示出来红框里的内容,就表示安装成功。红框里的内容表示的是MySQL数据库版本号。2、如何用客户端(Navicat…

我是怎么进入Oracle这样的大企业的?

导语:人工智能是泡沫么?AI产业的未来将何去何从?机器学习又该怎么学习?AI行业从业者又是怎么看待这个行业的呢?踏入一个行业之前最好对这个行业有个全方位的了解。本文作者饶毅,现就职于甲骨文公司。AI行业…

websocket文档_WebSocket推送 原理扫盲到上手实践

关于服务端推送技术,大家比较熟悉的可能就是轮询,但是轮询只能是由客户端先发起http请求。在HTTP1.1中的keep-alive方式建立的http连接,但是一个Request只能对应一个Response,而且这个Response是被动的,不能主动发起。…

DISCUZ7.2在通达OA2009桌面显示技巧

最近在测试DISCUZ 和通达...猛然间看到,,,可以DISCUZ可以和通达完美结合,禁不住进行了测试.....效果还挺好的...最初效果图如下:感觉挺别扭的,于是将DISCUZ调用代码更改了代码如下:[show1] <table width"100%" > <tr> <td alignleft> <di…

如何在 ASP.Net Core 中使用 Lamar

ASP.Net Core 自带了一个极简的 开箱即用 的依赖注入容器&#xff0c;实际上&#xff0c;你还可以使用第三方的 依赖注入容器 来替代它&#xff0c;依赖注入是一种设计模式&#xff0c;它能够有效的实现对象之间的解耦并有利于提高单元测试和维护性&#xff0c;你可以使用 依赖…

扎克伯格做了26张PPT,员工效率提10倍,已被疯狂传阅!

1、时间常有&#xff0c;时间在于优先。2、时间总会有的&#xff1a;每天只计划 4&#xff5e;5 小时真正的工作。3、当你在状态时&#xff0c;就多干点&#xff1b;不然就好好休息&#xff1a;有时候会连着几天不是工作状态&#xff0c;有时在工作状态时却又能天天忙活 12 小时…