重新整理.netcore实践篇—linux上排查问题实用工具[外篇]

dotNET跨平台 dotNET跨平台     2023-03-22     497

关键词:

前言

介绍下面几个工具:

Lldb
createdump
dotnet-dump
dotnet-gcdump
dotnet-symbol
Procdump

该文的前置篇为:

https://www.cnblogs.com/aoximin/p/16839812.html

献给初学者,这篇就只介绍下看下日志和lldb,毕竟东西太多了。

正文

我以官网的例子作为演示:https://buggyambfiles.blob.core.windows.net/bin/buggyamb_v1.1.zip

项目地址:https://github.com/ahmetmithat/buggyamb

我这里就已经发布可以访问了,并且用户nginx 作为转发,已经启动起来了。

步骤在前面两篇,如果看需要发布的,可以往前面两篇看看,这里就不多复述了。

[Unit]
Description=BuggyAmb

[Service]
WorkingDirectory=/var/buggyamb
ExecStart=/usr/bin/dotnet /var/buggyamb/BuggyAmb.dll
Restart=aways
RestartSec=10
SyslogIdentifier=BuggyAmb
User=root
Environment=ASPNETCORE_ENVIRONMENT=Development
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment=ASPNETCORE_URLS=http://0.0.0.0:6000
[Install]
WantedBy=multi-user.target

service 的配置如上。

页面测试如下:

里面分别是:

慢、处理异常、不处理异常、崩溃、未找到页面、批处理

崩溃情况

这种比较好排查的,其实一般看日志就行。

我这里点一下Crash2,让程序崩溃。这里说明一下,上面我用的是官方例子,直接可以看代码怎么崩溃的哈。

public class Crash2Model : PageModel

	public string quote;
	~Crash2Model()
	
		if (quote.ToString() != string.Empty)
		
			quote = null;
		
	
	public void OnGet()
	
	

这个可以看下。

那么我们进行日志排查一下错误。

journalctl -r --identifier=BuggyAmb --since "10 minute ago"

告诉我们15行错误。

-r:按反向顺序打印日志,以便首先列出最新日志。
--identifier:请记住 SyslogIdentifier=buggyamb-identifier 测试应用程序的服务文件中的行。(可以使用此方法强制日志仅显示适用于有问题的应用程序的条目。)
--since:显示在指定的上一时期记录的信息。示例:--since "10 minute ago" 或 --since "2 hour ago".

journalctl 还有很多其他的功能,这里就不一一举例了。

核心转储

centos 默认不开启的:

可以看下这个怎么开启的:

https://blog.csdn.net/ProgramVAE/article/details/105921381

#!/bin/bash

#me: coredumpshell.sh
### Description: enable coredump and format the name of core file on centos system

# enable coredump whith unlimited file-size for all users
echo -e "\\n# enable coredump whith unlimited file-size for all users\\n* soft core unlimited" >> /etc/security/limits.conf

# set the path of core file with permission 777 
cd /var/buggyamb && mkdir corefile && chmod 777 corefile

# format the name of core file.   
# %% – 符号%
# %p – 进程号
# %u – 进程用户id
# %g – 进程用户组id
# %s – 生成core文件时收到的信号
# %t – 生成core文件的时间戳(seconds since 0:00h, 1 Jan 1970)
# %h – 主机名
# %e – 程序文件名
echo -e "/var/buggyamb/corefile/core-%e-%s-%u-%g-%p-%t" > /proc/sys/kernel/core_pattern

# for centos7 system(update 2017.2.3 21:44)
echo -e "/var/buggyamb/corefile/core-%e-%s-%u-%g-%p-%t" > /etc/sysctl.conf

# suffix of the core file name
echo -e "1" > /proc/sys/kernel/core_uses_pid

运行之后就开启了。

centos 一般用不上,我也没有去调试过,这里就不演示了,只能说有这种东西。

使用lldb

安装:yum install lldb

前文提及到这个要安装lldb 3.9 以上的。

按照这个文档来编译安装也行:

https://github.com/dotnet/diagnostics/blob/main/documentation/lldb/linux-instructions.md

在 lldb 中打开核心转储文件之前,请按照以下必需步骤设置符号路径,下载符号,并在打开 lldb 时自动加载 SOS :

安装 dotnet 符号工具:

dotnet tool install -g dotnet-symbol

下载目标转储文件的符号:

dotnet-symbol <path_of_dump_file>

安装 SOS:

安装 dotnet-sos 全局工具:

dotnet tool install -g dotnet-sos

安装 SOS:

dotnet-sos install

最后成功的样子:

使用createdump:

Createdump 会与每个 .NET Core 运行时一起自动安装。

如 创建的ump 配置策略 文档中所述,可以设置具有环境变量的配置选项。这些将作为参数传递给创建的ump 命令。下面是支持的环境变量:

COMPlus_DbgEnableMiniDump:如果设置为 1,则在终止时启用自动核心转储生成。默认值为 0 。
COMPlus_DbgMiniDumpType:这是将要创建的微型转储文件的类型。此值的默认值为 2 (或枚举类型 MiniDumpWithPrivateReadWriteMemory) 。这意味着生成的转储文件将包括 GC 堆以及捕获进程中所有现有线程的堆栈跟踪所需的信息。
COMPlus_DbgMiniDumpName:如果设置,请用作模板来创建转储文件路径和文件名。可以使用参数将 PID 放入名称中 %d 。默认模板为 /tmp/coredump.%d. 通过使用此环境变量,可以配置输出目录。
COMPlus_CreateDumpDiagnostics:如果设置为 1,则启用创建的ump 工具诊断消息 (TRACE 宏) 。如果 createdump 不能按预期工作并且不生成内存转储文件,则此设置可能很有用。

详细信息如下:https://github.com/dotnet/coreclr/blob/master/Documentation/botr/xplat-minidump-generation.md#configurationpolicy

进行开启:

然后重启,再来点击clash3进行崩溃一下。

可以看到这里就有了。

这里我们先转储文件符号一下:

dotnet-symbol /tmp/coredump.9784-o /dumps/symbols/ --host-only

然后进去一下:

lldb --core /tmp/coredump.9784

这个时候要加载一下dotnet 符号。

setsymbolserver -directory /dumps/symbols/

然后加载转储文件符号:

loadsymbols

这样就搞定了。

clrsthread 查看一下线程的情况:

这里可以看到里面有个异常是15号线程。

切到15号线程:

setthread 15:

然后查看一下clrstack(调用栈信息):

这个似乎没有告诉我们很多很有用的信息,只能告诉我们线程异常了,当然也告诉我们具体的行,可以去看下去源代码看下什么类型异常,但是有跟好用的pe。

用pe查看下:

pe  -- Displays and formats fields of any object derived from the Exception class at the specified address.

这样就定位到具体的崩溃文件了。

知道了崩溃是因为HttpWebRequest,希望的是能查到到底是哪个访问url造成了崩溃。

下面这个图,证明可调用了HttpWebRequest引发的:

使用dumpheap:dumpheap -stat -type System.Net.HttpWebRequest 查看httpwebrequest 调用栈:

查看栈地址:

然后是根据地址查看对象:dumpobj 00007fe0c4442f28

这个webrequest 里面有一个是system.url 我们写程序的知道这是访问地址。

然后继续查这个对象,上面那个value 就是地址哈。

00007fe0c4437cf8

然后可以看到url 地址:

第一个就是了,为什么确认第一个就是,看名字。

这样就查到了。

先到这里吧,介绍这个lldb 是为了查看非托管栈的,如果查看托管的一般使用dotnet-dump 就好了。

而且一般是用来分析cpu 和 内存高的地方,一般服务端错误会有日志的。

继续后面演示cpu 和 内存高的例子,这个对服务端更有实用性。

重新整理.netcore实践篇—————应用层[三十](代码片段)

前言简单介绍一下应用层。正文应用层用来做什么的呢?应用层用来做处理api请求的。[HttpPost]publicTask<long>CreateOrder([FromBody]CreateOrderVeiwModelviewModel) varmodel=viewModel.ToModel(); returnawaitorderService.CreateOrder(model); 查看详情

重新整理.netcore实践篇—————工作单元模式[二十六](代码片段)

前言简单整理一下工作单元模式。正文工作单元模式有3个特性,也算是其功能:使用同一上下文跟踪实体的状态保障事务一致性工作单元模式主要关注事务,所以重点在事务上。在共享层的基础建设类库中加入:///<summary>///工... 查看详情

重新整理.netcore实践篇—————静态中间件[二十一](代码片段)

前言简单整理一下静态中间件。正文我们使用静态文件调用:app.UseStaticFiles();那么这个默认会将我们根目录下的wwwroot作为静态目录。这个就比较值得注意的,可能刚开始学.netcore的小伙伴,会直接把脚本写在更目录script这样是访... 查看详情

重新整理.netcore实践篇—————仓储层的具体实现[二十七](代码片段)

前言简单整理一下仓储层。正文在共享层的基础建设类库中:///<summary>///泛型仓储接口///</summary>///<typeparamname="TEntity">实体类型</typeparam>publicinterfaceIRepository<TEntity>whereTEntity:Entity,IAggregate 查看详情

重新整理.netcore实践篇—————路由和终结点[二十三](代码片段)

前言简单整理一下路由和终节点。正文路由方式主要有两种:1.路由模板方式2.RouteAttribute方式路由约束:1.类型约束2.范围约束3.正则表达式4.是否必选5.自定义IRootConstaintURL生成1.LinKGenerator2.IUrlHelper先搭建一个swagger:services.AddSwaggerGen(... 查看详情

重新整理.netcore实践篇—————应用分层[二十四](代码片段)

前言简单整理一下分层。正文应用程序分层,分为:1.领域模型层2.基础设施层3.应用层4.共享层共享层共享层一般包括下面几个类库。有一个Core的类库,比如说BLog.Core.这个类库用来,主要用来承载一些基础简单的类型,比如说一... 查看详情

重新整理.netcore实践篇—————entity的定义[二十五](代码片段)

前言简单介绍一下实体模型的设计。正文前文提及了我们的应用分为:共享层基础设施层领域层应用层今天来介绍领域模型层。前文提及到领域模型在共享层有一个领域模型抽象类库。里面有这些类:先分别介绍一下这些类是做... 查看详情

重新整理.netcore实践篇—————微服务的桥梁eventbus[三十一](代码片段)

前言简单介绍一下EventBus.正文EventBus也就是集成事件,用于服务与服务之间的通信。比如说我们的订单处理事件,当订单处理完毕后,我们如果通过api马上去调用后续接口。比如说订单完成给用户通知的话,如果是大量订单,即... 查看详情

重新整理.netcore实践篇—————日志系统之结构化[十八](代码片段)

前言什么是结构化呢?结构化,就是将原本没有规律的东西进行有规律话。就比如我们学习数据结构,需要学习排序然后又要学习查询,说白了这就是一套,没有排序,谈如何查询是没有意义的,因为查询算法就是根据某种规律... 查看详情

实践.netcore在linux环境下的第一个helloworld

...系统的文件)3、XShell软件(Windows环境下的Linux终端)4、.NetCore安装参考网址,https://www.microsoft.com/net/core#centos5、.NetCore下载地址,https://www.micros 查看详情

asp.netcore在centos上的最小化部署实践(代码片段)

原文:ASP.NETCore在CentOS上的最小化部署实践引言    本文从Linux小白的视角,在CentOS7.x服务器上搭建一个Nginx-PoweredAspNetCoreWeb准生产应用。在开始之前,我们还是重温一下部署原理,正如你所常见的.NetCore部署图:在Lin... 查看详情

.net跨平台实践:.netcore.net5/6linux守护进程设计

几年前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是《.NET跨平台实践:用C#开发Linux守护进程.NET跨平台实践:再谈用C#开发Linux守护进程—完整篇这就是本文的初衷。关于LinuxDaemon程序的原理之类的&#x... 查看详情

.netcore杂记

...解了.netcore设计理念和设计思想(纯属跟人理解)。再此整理了之前写的一些学习笔记,后续也会把新的学习新的加上。1..netcore跨平台实践2.asp.netcore使用EF7CodeFirst创建数据库,同时使用命令创建数据库 查看详情

.netcore实践篇————网关

参考技术A简单整理一下网关。在介绍网关之前,介绍一下BFF,BFF全称是BackendForFrontend,它负责认证授权,服务聚合,目标是为前端提供服务。说的通透一点,就是有没有见过这种服务。上述就是buff通过代理其他服务来让前端访... 查看详情

嵌入式linux开发实践专栏目录

...a;2021年9月17日目前总文章数为3篇,后序会不断更新并整理目录,感谢支持!已经整理输出的专栏,主要集中在基础,本专刊则主要集中在实践及面试高频知识Linux环境编程玩转UbuntuLinuxMakefile入门Linux内核下面... 查看详情

嵌入式linux开发实践专栏目录

...a;2021年9月17日目前总文章数为3篇,后序会不断更新并整理目录,感谢支持!已经整理输出的专栏,主要集中在基础,本专刊则主要集中在实践及面试高频知识Linux环境编程玩转UbuntuLinuxMakefile入门Linux内核下面... 查看详情

asp.netcore分布式项目实战整理identityserver4mvc授权consent功能实现(代码片段)

...前言由于之前的博客都是基于其他的博客进行开发,现在重新整理一下方便以后后期使用与学习新建IdentityServer4服务端服务端也就是提供服务,如Q 查看详情

linux中以单容器部署nginx+asp.netcore

...转发请求到KestrelHttp服务器,本文将会实践将Nginx--->ASP.NETCore部署架构容器化的过程。 Nginx->ASP.NETCoe部署架构容器化  在Docker中部署Nginx--->ASP.NETCore有两种选择,第一种是在单容器内部署Nginx+ASP.NETCore,这是本文着 查看详情