当前位置:首页 > 科技  > 软件

记一次 .NET某网络边缘计算系统 卡死分析

来源: 责编: 时间:2024-07-01 17:13:43 226观看
导读一、背景1. 讲故事早就听说过有什么 网络边缘计算,这次还真给遇到了,有点意思,问了下 chatgpt 这是干嘛的 ?网络边缘计算是一种计算模型,它将计算能力和数据存储位置从传统的集中式数据中心向网络边缘的用户设备、传感器

一、背景

1. 讲故事

早就听说过有什么 网络边缘计算,这次还真给遇到了,有点意思,问了下 chatgpt 这是干嘛的 ?IAY28资讯网——每日最新资讯28at.com

网络边缘计算是一种计算模型,它将计算能力和数据存储位置从传统的集中式数据中心向网络边缘的用户设备、传感器和其他物联网设备移动。这种模型的目的是在接近数据生成源头的地方提供更快速的计算和数据处理能力,从而减少数据传输延迟并提高服务质量。网络边缘计算使得在设备本地进行数据处理和决策成为可能,同时也有助于减轻对中心数据中心的网络流量和负载。IAY28资讯网——每日最新资讯28at.com

看到.NET还有这样的应用场景还是挺欣慰的,接下来就来分析下这个dump到底是怎么回事?IAY28资讯网——每日最新资讯28at.com

二、WinDbg 分析

1. 为什么会卡死

不同程序的卡死有不同的分析方式,所以要先鉴别下程序的类型以及主线程的调用栈即可,参考如下:IAY28资讯网——每日最新资讯28at.com

0:000> !eeversion5.0.721.255085.0.721.25508 @Commit: 556582d964cc21b82a88d7154e915076f6f9008eServer mode with 64 gc heapsSOS Version: 8.0.10.10501 retail build0:000> k # Child-SP          RetAddr               Call Site00 0000ffff`e0dddac0 0000fffd`c194c30c     libpthread_2_28!pthread_cond_wait+0x238...18 (Inline Function) --------`--------     libcoreclr!RunMain::$_0::operator()::{lambda(Param *)#1}::operator()+0x14c [/__w/1/s/src/coreclr/src/vm/assembly.cpp @ 1536] 19 (Inline Function) --------`--------     libcoreclr!RunMain::$_0::operator()+0x188 [/__w/1/s/src/coreclr/src/vm/assembly.cpp @ 1538] 1a 0000ffff`e0dde600 0000fffd`c153e860     libcoreclr!RunMain+0x298 [/__w/1/s/src/coreclr/src/vm/assembly.cpp @ 1538] ...20 0000ffff`e0dded10 0000fffd`c1bf7800     libhostpolicy!corehost_main+0xc0 [/root/runtime/src/installer/corehost/cli/hostpolicy/hostpolicy.cpp @ 409] 21 (Inline Function) --------`--------     libhostfxr!execute_app+0x2c0 [/root/runtime/src/installer/corehost/cli/fxr/fx_muxer.cpp @ 146] 22 (Inline Function) --------`--------     libhostfxr!<unnamed-namespace>::read_config_and_execute+0x3b4 [/root/runtime/src/installer/corehost/cli/fxr/fx_muxer.cpp @ 520] 23 0000ffff`e0ddeeb0 0000fffd`c1bf6840     libhostfxr!fx_muxer_t::handle_exec_host_command+0x57c [/root/runtime/src/installer/corehost/cli/fxr/fx_muxer.cpp @ 1001] 24 0000ffff`e0ddf000 0000fffd`c1bf4090     libhostfxr!fx_muxer_t::execute+0x2ec25 0000ffff`e0ddf130 0000aaad`c9e1d22c     libhostfxr!hostfxr_main_startupinfo+0xa0 [/root/runtime/src/installer/corehost/cli/fxr/hostfxr.cpp @ 50] 26 0000ffff`e0ddf200 0000aaad`c9e1d468     dotnet!exe_start+0x36c [/root/runtime/src/installer/corehost/corehost.cpp @ 239] 27 0000ffff`e0ddf370 0000fffd`c1c63fe0     dotnet!main+0x90 [/root/runtime/src/installer/corehost/corehost.cpp @ 302] 28 0000ffff`e0ddf3b0 0000aaad`c9e13adc     libc_2_28!_libc_start_main+0xe029 0000ffff`e0ddf4e0 00000000`00000000     dotnet!start+0x34

从卦中的指标来看,这是一个 Linux 上部署的 Web网站,既然是网站的卡死,那就要关注各个线程都在做什么。IAY28资讯网——每日最新资讯28at.com

2. 线程都在干嘛

以我多年的分析经验,绝大多数都是由于 线程饥饿 或者说 线程池耗尽 导致的,首先我们看下线程池的情况。IAY28资讯网——每日最新资讯28at.com

0:000> !tThreadCount:      365UnstartedThread:  0BackgroundThread: 354PendingThread:    0DeadThread:       10Hosted Runtime:   no                                                                                                            Lock   DBG   ID     OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception   0    1    31eaf 0000AAADF267C600  2020020 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn ... 423  363    36d30 0000FFDDB4000B20  1020220 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn (Threadpool Worker)  424  364    36d31 0000FFDDA8000B20  1020220 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn (Threadpool Worker)  425  365    36d32 0000FFDDAC000B20  1020220 Preemptive  0000000000000000:0000000000000000 0000aaadf26634b0 -00001 Ukn (Threadpool Worker) 0:000> !tpUsing the Portable thread pool.CPU utilization:  9%Workers Total:    252Workers Running:  236Workers Idle:     13Worker Min Limit: 64Worker Max Limit: 32767Completion Total:   0Completion Free:    0Completion MaxFree: 128Completion Current Limit: 0Completion Min Limit:     64Completion Max Limit:     1000

从卦中看当前有 365 个托管线程,这个算多吗?对于64core 来说,这个线程其实算是正常,训练营里的朋友都知道,server版的gc仅gc线程就有 64*2=128 个,接下来再看一个指标就是当前是否存在任务积压?可以使用 !ext tpq 命令,参考输出如下:IAY28资讯网——每日最新资讯28at.com

0:000> !ext tpqglobal work item queue________________________________local per thread work items_____________________________________

从卦中看当前没有任务积压,这就有点反经验了。IAY28资讯网——每日最新资讯28at.com

3. 真的不是线程饥饿吗

最后一招比较彻底,就是看各个线程栈都在做什么,可以使用 ~*e !clrstack 命令。IAY28资讯网——每日最新资讯28at.com

这不看不知道,一看吓一跳,有 193 个线程在 Task.Result 上等待,这玩意太经典了,然后从上面的调用栈 UIUpdateTimer_Elapsed 来看,貌似是一个定时器导致的,接下来我就好奇这代码是怎么写的?IAY28资讯网——每日最新资讯28at.com

分析上面的代码之后,我发现它是和 Linux Shell 窗口进行命令交互,不知道为何 Shell 没有响应导致代码在这里卡死。IAY28资讯网——每日最新资讯28at.com

4. 为什么线程池没有积压

相信有很多朋友对这个反经验的东西很好奇为什么请求没有积压在线程池,其实这个考验的是你对 PortableThreadPool 的底层了解,这里我就简单说一下吧。IAY28资讯网——每日最新资讯28at.com

  • 在 ThreadPool 中有一个 GateThread 线程是专门给线程池动态注入线程的,参考代码如下:
private static class GateThread{    private static void GateThreadStart()    {        while (true)        {            bool wasSignaledToWake = DelayEvent.WaitOne((int)delayHelper.GetNextDelay(tickCount));            WorkerThread.MaybeAddWorkingWorker(threadPoolInstance);        }    }}
  • 一旦有人调用了 Task.Result 代码,内部会主动唤醒 DelayEvent 事件,告诉 GateThread 赶紧通过 MaybeAddWorkingWorker 方法给我注入新的线程,参考代码如下:
private bool SpinThenBlockingWait(int millisecondsTimeout, CancellationToken cancellationToken){    bool flag3 = ThreadPool.NotifyThreadBlocked();}internal static bool NotifyThreadBlocked(){    if (UsePortableThreadPool)    {        return PortableThreadPool.ThreadPoolInstance.NotifyThreadBlocked();    }    return false;}public bool NotifyThreadBlocked(){    GateThread.Wake(this);}

上面这种主动唤醒的机制是 C# 版 PortableThreadPool 做的优化来缓解线程饥饿的,这里有一个重点就是它只能缓解,换句话说如果上游太猛了还是会有请求积压的,但为什么这里没有积压呢?很显然上游不猛呗,那如何眼见为实呢?这就需要看 timer 的周期数即可,到当前的线程栈上给扒出来。IAY28资讯网——每日最新资讯28at.com

0:417> !DumpObj /d 0000ffee380757f8Name:        System.Timers.TimerMethodTable: 0000fffd4ab24030EEClass:     0000fffd4ad6e140Size:        88(0x58) bytesFile:        /home/user/env/dotnet/shared/Microsoft.NETCore.App/5.0.7/System.ComponentModel.TypeConverter.dllFields:              MT    Field   Offset                 Type VT     Attr            Value Name0000fffd4c947498  400001c        8 ...ponentModel.ISite  0 instance 0000000000000000 _site0000000000000000  400001d       10 ....EventHandlerList  0 instance 0000000000000000 _events0000fffd479195d8  400001b       98        System.Object  0   static 0000000000000000 s_eventDisposed0000fffd47926f60  400000e       40        System.Double  1 instance 3000.000000 _interval0000fffd4791fb10  400000f       48       System.Boolean  1 instance                1 _enabled0000fffd4791fb10  4000010       49       System.Boolean  1 instance                0 _initializing0000fffd4791fb10  4000011       4a       System.Boolean  1 instance                0 _delayedEnable0000fffd4ab241d8  4000012       18 ...apsedEventHandler  0 instance 0000ffee3807aae8 _onIntervalElapsed0000fffd4791fb10  4000013       4b       System.Boolean  1 instance                1 _autoReset0000fffd4c944ea0  4000014       20 ...SynchronizeInvoke  0 instance 0000000000000000 _synchronizingObject0000fffd4791fb10  4000015       4c       System.Boolean  1 instance                0 _disposed0000fffd49963e28  4000016       28 ...m.Threading.Timer  0 instance 0000ffee38098dc8 _timer0000fffd48b90a30  4000017       30 ...ing.TimerCallback  0 instance 0000ffee3807aaa8 _callback0000fffd479195d8  4000018       38        System.Object  0 instance 0000ffee38098db0 _cookie

从卦中看当前是 3s 为一个周期,这就能解释为什么线程池没有积压的底层原因了。IAY28资讯网——每日最新资讯28at.com

三、总结

这个卡死事故还是蛮好解决的,如果有一些经验直接用dotnet-counter也是能搞定的,重点在于这是一个 Linux的dump,同时又是 .NET上的一个很好玩的场景,故此分享出来。IAY28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-97895-0.html记一次 .NET某网络边缘计算系统 卡死分析

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 都用10年了,gRPC有什么不好的?

下一篇: 深入探讨 C++ 中的内部类:封装与模块化的利器

标签:
  • 热门焦点
  • 把LangChain跑起来的三个方法

    使用LangChain开发LLM应用时,需要机器进行GLM部署,好多同学第一步就被劝退了,那么如何绕过这个步骤先学习LLM模型的应用,对Langchain进行快速上手?本片讲解3个把LangChain跑起来
  • 谷歌KDD'23工作:如何提升推荐系统Ranking模型训练稳定性

    谷歌在KDD 2023发表了一篇工作,探索了推荐系统ranking模型的训练稳定性问题,分析了造成训练稳定性存在问题的潜在原因,以及现有的一些提升模型稳定性方法的不足,并提出了一种新
  • 三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • 只需五步,使用start.spring.io快速入门Spring编程

    步骤1打开https://start.spring.io/,按照屏幕截图中的内容创建项目,添加 Spring Web 依赖项,并单击“生成”按钮下载 .zip 文件,为下一步做准备。请在进入步骤2之前进行解压。图
  • 一文掌握 Golang 模糊测试(Fuzz Testing)

    模糊测试(Fuzz Testing)模糊测试(Fuzz Testing)是通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法。可以用来发现应用程序、操作系统和网络协议等中的漏洞或
  • 一个注解实现接口幂等,这样才优雅!

    场景码猿慢病云管理系统中其实高并发的场景不是很多,没有必要每个接口都去考虑并发高的场景,比如添加住院患者的这个接口,具体的业务代码就不贴了,业务伪代码如下:图片上述代码有
  • 华为发布HarmonyOS 4:更好玩、更流畅、更安全

    在8月4日的华为开发者大会2023(HDC.Together)大会上,HarmonyOS 4正式发布。自2019年发布以来,HarmonyOS一直以用户为中心,经历四年多的发展HarmonyOS已
  • OPPO K11采用全方位护眼屏:三大护眼能力减轻视觉疲劳

    日前OPPO官方宣布,全新的OPPO K11将于7月25日正式发布,将主打旗舰影像,和同档位竞品相比,其最大的卖点就是将配备索尼IMX890主摄,堪称是2000档位影像表
  • SN570 NVMe SSD固态硬盘 价格与性能兼具

    SN570 NVMe SSD固态硬盘是西部数据发布的最新一代WD Blue系列的固态硬盘,不仅闪存技术更为精进,性能也得到了进一步的跃升。WD Blue SN570 NVMe SSD的包装外
Top