首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用MiniProfiler小结

使用MiniProfiler小结

作者头像
小蜜蜂
发布2019-08-02 17:04:04
1.4K0
发布2019-08-02 17:04:04
举报
文章被收录于专栏:明丰随笔明丰随笔明丰随笔

为什么要使用MiniProfiler?

如果程序需要性能调优,我们使用它可以帮我们分析代码的执行情况。

MiniProfiler是一款性能分析的小程序。

可以对一个页面本身,及该页面通过直接引用、Ajax、Iframe形式访问的其它页面进行监控。

监控内容包括数据库访问,网络请求等,并可以显示数据库访问的SQL,以及网络请求的地址等。

最后以很友好的方式展现在页面上。

我们先以Console程序为例,使用MiniProfiler小工具。

1. 安装包:MiniProfiler

2. 创建一个profiler对象

//profiler和MiniProfiler.Current是相等的
var profiler = MiniProfiler.StartNew("My Pofiler Name");

3. 创建一个Step,作为一个记录单元

using (profiler.Step("CallDataBase")){ ... }

4. 对于数据库的操作,ADO.NET里面里面的对象,需要使用ProfiledXXX类包装一下:

DbConnection cnn = new SqlConnection(@"...");
cnn = new ProfiledDbConnection(cnn, profiler);
DbCommand dbCommand = new SqlCommand("SELECT name FROM [ActionType_lkp]");
dbCommand = new ProfiledDbCommand(dbCommand, cnn, profiler);

5. 对于网络请求,需要使用CustomTiming方法,把网络请求的地址输入,后面在分析性能的时候,可以友好的展示出来:

using (var wc = new WebClient())
using (profiler.CustomTiming("https", "GET https://www.baidu.com"))
{
  wc.DownloadString("https://www.baidu.com");
}

6. Step可以嵌套Step:

using (profiler.Step("outer"))
{
  System.Threading.Tasks.Parallel.For(0, 5, i =>
  {
    doWork();
    using (profiler.Step("step " + i))
    {
      doWork();
      using (profiler.Step("sub-step" + i))
      {
        doWork();
      }
    }
  });
}

7. 在最后代码的结尾位置,停止profiler

profiler.Stop();

8. 打出出来结果:

Console.WriteLine(profiler.RenderPlainText());

我们使用MiniProfiler对Asp.Net MVC应用程序进行性能分析,基本思路和Console程序是一样的。

1. 安装包:MiniProfiler.Mvc5

2. 注册全局的Filters,并对视图引擎进行Profilling包装,还可以对MiniProfiler全局配置,这些内容应该放在,应用程序启动的时候:

protected void Application_Start()
{
  ...
  //NO.1
  GlobalFilters.Filters.Add(new ProfilingActionFilter());
  //NO.2
  var copy = ViewEngines.Engines.ToList();
  ViewEngines.Engines.Clear();
  foreach (var item in copy)
  {
    ViewEngines.Engines.Add(new ProfilingViewEngine(item));
  }
  //NO.3
  MiniProfiler.Configure(new MiniProfilerOptions
  {
    // Different RDBMS have different ways of declaring sql parameters - SQLite can understand inline sql parameters just fine.
    // By default, sql parameters will be displayed.
    //SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter(),
    // These settings are optional and all have defaults, any matching setting specified in .RenderIncludes() will
    // override the application-wide defaults specified here, for example if you had both:
    //    PopupRenderPosition = RenderPosition.Right;
    //    and in the page:
    //    @MiniProfiler.Current.RenderIncludes(position: RenderPosition.Left)
    // ...then the position would be on the left on that page, and on the right (the application default) for anywhere that doesn't
    // specified position in the .RenderIncludes() call.
    PopupRenderPosition = RenderPosition.Right,  // defaults to left
    PopupMaxTracesToShow = 10,                   // defaults to 15
    // ResultsAuthorize (optional - open to all by default):
    // because profiler results can contain sensitive data (e.g. sql queries with parameter values displayed), we
    // can define a function that will authorize clients to see the JSON or full page results.
    // we use it on http://stackoverflow.com to check that the request cookies belong to a valid developer.
    ResultsAuthorize = request => request.IsLocal,
    // ResultsListAuthorize (optional - open to all by default)
    // the list of all sessions in the store is restricted by default, you must return true to allow it
    ResultsListAuthorize = request =>
    {
      // you may implement this if you need to restrict visibility of profiling lists on a per request basis
      return true; // all requests are legit in this example
    },
    // Stack trace settings
    StackMaxLength = 256, // default is 120 characters
    // (Optional) You can disable "Connection Open()", "Connection Close()" (and async variant) tracking.
    // (defaults to true, and connection opening/closing is tracked)
    TrackConnectionOpenClose = true
  });
}

3. 在每一个请求的开始的时候,应该开始一个profiler:

protected void Application_BeginRequest()
{
  //NO.4
  // You can decide whether to profile here, or it can be done in ActionFilters, etc.
  // We're doing it here so profiling happens ASAP to account for as much time as possible.
  if (Request.IsLocal) // Example of conditional profiling, you could just call MiniProfiler.StartNew();
  {
    MiniProfiler.StartNew();
  }
}

4. 在请求结束的时候,应该停止profiler:

protected void Application_EndRequest()
{
  //NO.5
  MiniProfiler.Current?.Stop(); // Be sure to stop the profiler!
}

5. 在web.config文件中编辑

<system.webServer>
    ...
    <handlers>
      <!--NO.6-->
      <add name="MiniProfiler" path="mini-profiler-resources/*" verb="*"
           type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified"
           preCondition="integratedMode" />
    </handlers>
</system.webServer>

6. 在html页面的</body>之前添加:

@StackExchange.Profiling.MiniProfiler.Current.RenderIncludes();

7. 浏览器访问某页面,在页面的右上角有一个加载时间:

8. 点击时间,可以打开独立的profiler页面:

通过上面的截图,我们可以看到:

a. 访问页面的URL

b. 服务器的名称

c. 页面加载的总时间

d. 代码执行栈的每一步花费的时间

e. 代码执行是否包含数据库访问和网络请求

f. 浏览器视角花费的时间,包括请求,响应,DOM加载,Paint等等

g. 对于数据库的访问,有更多细节,包括sql语句是什么

h. 对于网络请求的访问,可以知道,请求是什么类型的,网络地址是什么

通过这些信息可以帮我们定位出那些步骤执行时间较长,我们就可以进一步对其进行性能分析和优化。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 明丰随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档