首页 > 其他分享 >记一次 .NET 某物流API系统 CPU爆高分析

记一次 .NET 某物流API系统 CPU爆高分析

时间:2023-07-31 15:47:25浏览次数:43  
标签:Int32 String 爆高 Canon System API NET CPU SqlSugar

一:背景

1. 讲故事

前段时间有位朋友找到我,说他程序CPU直接被打满了,让我帮忙看下怎么回事,截图如下:

看了下是两个相同的程序,既然被打满了那就抓一个 dump 看看到底咋回事。

二:为什么会打满

1. 真的被打满了吗

凡事都要用数据说话,我们使用 !tp 命令观察一下。


0:014> !tp
logStart: 62
logSize: 200
CPU utilization: 100 %
Worker Thread: Total: 16 Running: 0 Idle: 16 MaxLimit: 32767 MinLimit: 8
Work Request in Queue: 0
--------------------------------------
Number of Timers: 8
--------------------------------------
Completion Port Thread:Total: 9 Free: 2 MaxFree: 16 CurrentLimit: 9 MaxLimit: 1000 MinLimit: 8

从卦象看果然是被打满了,那为什么会满呢?一般来说CPU高是线程抬起来的,接下来我们就从线程入手。

2. 线程都在做什么事情

要想观察每个线程都在做什么,可以使用 ~*e !clrstack 命令,打完所有的线程栈后,明显发现有 6 处在 System.Text.RegularExpressions.RegexReplacement.Replace 正则替换这里,截图如下:


0:021> ~14s
ntdll!NtWaitForSingleObject+0x14:
00007ff9`c5d4fa74 c3              ret
0:014> !clrstack
OS Thread Id: 0x6ee0 (14)
        Child SP               IP Call Site
000000AC6CBF99C8 00007ff9c5d4fa74 [HelperMethodFrame: 000000ac6cbf99c8] 
000000AC6CBF9AC0 00007ff942416c05 System.String.Create[[System.Text.SegmentStringBuilder, System.Text.RegularExpressions]](Int32, System.Text.SegmentStringBuilder, System.Buffers.SpanAction`2<Char,System.Text.SegmentStringBuilder>) 
000000AC6CBF9B20 00007ff942416aeb System.Text.SegmentStringBuilder.ToString()
000000AC6CBF9BA0 00007ff9422e62ac System.Text.RegularExpressions.RegexReplacement.Replace(System.Text.RegularExpressions.Regex, System.String, Int32, Int32)
000000AC6CBF9C70 00007ff9422e4ec6 System.Text.RegularExpressions.Regex.Replace(System.String, System.String, System.String, System.Text.RegularExpressions.RegexOptions) 
000000AC6CBF9CD0 00007ff941e157aa SqlSugar.UtilMethods.ReplaceSqlParameter(System.String, SqlSugar.SugarParameter, System.String)
000000AC6CBF9F80 00007ff941e42990 SqlSugar.SqlSugarProvider+d__245`1[[System.Int32, System.Private.CoreLib]].MoveNext()
000000AC6CBFA300 00007ff94190e93c System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.__Canon, System.Private.CoreLib]](System.__Canon ByRef)
000000AC6CBFA360 00007ff941e420bd SqlSugar.SqlSugarProvider.SaveQueuesProviderAsync[[System.Int32, System.Private.CoreLib]](Boolean, System.Func`3<System.String,System.Collections.Generic.List`1<SqlSugar.SugarParameter>,System.Threading.Tasks.Task`1>)
000000AC6CBFA3D0 00007ff941e41a52 SqlSugar.SqlSugarProvider+d__224.MoveNext()
000000AC6CBFA480 00007ff94190e93c System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[System.__Canon, System.Private.CoreLib]](System.__Canon ByRef)
000000AC6CBFA4E0 00007ff941e418f4 SqlSugar.SqlSugarProvider.SaveQueuesAsync(Boolean)
000000AC6CBFA550 00007ff941e417fe SqlSugar.SqlSugarClient.SaveQueuesAsync(Boolean)
000000AC6CBFA5A0 00007ff941e4177e SqlSugar.SqlSugarScope.SaveQueuesAsync(Boolean)
000000AC6CBFA5F0 00007ff941e40fce xxx.Repository.BaseRepository`1+d__76[[System.__Canon, System.Private.CoreLib]].MoveNext()
...
000000AC6D4FAAF0 00007ff9422c9d0c xxx.xxxService+d__15.MoveNext()
...

从上面的 MoveNext 和 AsyncMethodBuilder 来看,这里用的是全异步写法,分析起来那是一个头大哈。。。不过仔细观察是 SqlSugar 在替换sql参数的时候引发的,一般来说和 Regular 有关的操作都是蛮耗 CPU 的,然后顺手看了下cpu配置也才 8 核,难怪 CPU 直接 100% 了。


0:014> !cpuid
CP  F/M/S  Manufacturer     MHz
 0  6,85,7  <unavailable>   2500
 1  6,85,7  <unavailable>   2500
 2  6,85,7  <unavailable>   2500
 3  6,85,7  <unavailable>   2500
 4  6,85,7  <unavailable>   2500
 5  6,85,7  <unavailable>   2500
 6  6,85,7  <unavailable>   2500
 7  6,85,7  <unavailable>   2500


3. SqlSugar 到底在做什么

要想知道做什么,逆向一下代码就好,截图如下:

这种写法好不好我就不评价了,至少简单粗暴,那为什么会很耗时呢?这就要扒一下 ReplaceSqlParameter 方法中的三个参数,尤其是 itemSql 字段,然后使用 !clrstack -a


0:014> !clrstack -a
OS Thread Id: 0x6ee0 (14)
        Child SP               IP Call Site
000000AC6CBF9CD0 00007ff941e157aa SqlSugar.UtilMethods.ReplaceSqlParameter(System.String, SqlSugar.SugarParameter, System.String)
    PARAMETERS:
        itemSql (0x000000AC6CBF9F80) = 0x0000023d802e1020
        itemParameter (0x000000AC6CBF9F88) = 0x0000023c4bd3ae58
        newName (0x000000AC6CBF9F90) = 0x0000023ca9dd3328
    LOCALS:
        0x000000AC6CBF9F68 = 0x0000000000000000

0:014> !do 0x0000023d802e1020
Name:        System.String
MethodTable: 00007ff93caad698
EEClass:     00007ff93ca89d60
Tracked Type: false
Size:        21391508(0x1466894) bytes
File:        C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.12\System.Private.CoreLib.dll
String:      <String is invalid or too large to print>

Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
00007ff93ca99480  40002f2        8         System.Int32  1 instance         10695743 _stringLength
00007ff93c9fea10  40002f3        c          System.Char  1 instance               49 _firstChar
00007ff93caad698  40002f1       e8        System.String  0   static 0000023c3f5613a0 Empty

0:014> ?0n21391508 /0x400
Evaluate expression: 20890 = 00000000`0000519a

从卦中看,简直是吓一跳,这个 sql 居然高达 20M,

标签:Int32,String,爆高,Canon,System,API,NET,CPU,SqlSugar
From: https://www.cnblogs.com/huangxincheng/p/17593608.html

相关文章

  • fastapi 中文档显示空白
    原因:fastapiswaggerjscss都是写死在代码中的,他的正常传参修改地址不没有打开的,所以不能用正常的方式修改他的内置jscss路径:原始路径为:墙内很难打开解决方案:在生命app=FastAPI(....)之前粘贴下面代码,可以修改swaggerjscss引用路径fromfastapiimportapplications......
  • .Net设置SplashScreen,在高DPI下不居中的解决方案
    .Net设置SplashScreen,在高DPI下不居中的解决方案根据.Net官方文档,设置图片类型的软件的启动屏幕非常简单,只需要将图片放在工程里,并将图片的生成操作设置为SplashScreen后即可。但是这个办法在高DPI屏幕中没有适应,图片显示的位置不居中,对于强迫症来说会非常非常难受。查......
  • You must install or update .NET to run this application
    Youmustinstallorupdate.NETtorunthisapplication问题原因在使用.net的环境时,出现这个“Youmustinstallorupdate.NETtorunthisapplication”说明版本不符合系统默认式是2.0,3.0版本的,需要更新到5.0版本才行去官网下载符合自己的版本官网地址:https://do......
  • asp.net repeater控件
    1、ASP.NET数据控件解析2、在asp.net中怎么使用repeater控件动态绑定数据.绑成table形式的...3、c#asp.net里面的Repeater控件绑定数据具体怎么用啊?4、在asp.net中,关于Repeater控件的错误说法是?5、asp.net中怎样获取repeater中的数据ASP.NET数据控件解析1、ASP.Net......
  • DRF之APIView全笔记
    一.APIView基本视图,所有的都用这个来作viewsetmixin主要管as_view{}里的调配让视图不再需要两个类二.通用视图GenericAPIView(rest_framework.viewsets)GenericAPIView一共五个功能,数据库获取、分页、序列化、getobject\还有frilter_queryset__东西挺多的主要管self.get_object......
  • 有没有好用的个微API接口?
    最近公司需要找一家个微的API助手接口服务,具体需求是可以自己批量添加好友、批量打标签等进行好友管理,社群管理需要自动聊天,自动回复,发朋友圈,转发语音,以及定时群发等,还可以提取聊天内容,进行数据汇总,收藏快捷回复各种功能!找了很多天是找到了现在用的一款助手,用起来还是很方便的......
  • .NET下数据库的负载均衡“经典方案”(大项目必备,建议收藏)
    【前言】本文讲述的“数据库负载均衡”方案,为市面上最经典(没有之一),由.NET界骨灰级大佬推出。采用该技术方案的大公司,一年省下了几个亿的支出。 【正文】支持.NetCore(2.0及以上) 与.NetFramework(4.5及以上)可以部署在Docker,Windows,Linux,Mac。为了演示数据库的负载......
  • mediapipe ios framework
    实现“mediapipeiosframework”教程介绍在本教程中,我将教你如何实现“mediapipeiosframework”。Mediapipe是Google开发的一款用于构建机器学习、计算机视觉和图像处理应用程序的框架。该框架提供了许多预训练的模型和工具,以帮助开发者快速构建和部署各种应用。整体流程下......
  • 每个.NET开发都应掌握C#泛型的知识点
    C#泛型编程是.NETframework2.0的新特征,它提高了代码安全性和代码重用的问题。由于泛型必须指定类型,正确的使用可以避免了装箱拆箱的问题;使用了泛型后,可以将算法或组件泛型化,基于类型参数支持任意数据类型,从而提高了代码的重用性。C#泛型编程在C#是很重要的特性,建议.NET开发熟......
  • VB.NET and C# Comparison
    VB.NETandC#Comparison(vb.net与c#对比)//z2012-3-713:30:51PMIS2120@ImportsSystemNamespaceHello  ClassHelloWorld     OverloadsSharedSubMain(ByValargs()AsString)        DimnameAsString="VB.NET"        'See......