性能优化之三:将Dottrace过程加入持续集成

之前分享过一篇如何做接口性能分析的文章,但是整个分析过程有点繁琐,需要写一个控制台程序调用被测接口,再预热、启动dottrace追踪,最后才能得到我们想要的性能分析报告。如果有办法一键生成性能分析报告,那就会省很多不必要的时间。这里我们就借助Jenkins自动化完成这一过程。

目标:

把Dottrace的性能分析集成到Jenkins中,使我们在构建的时候,可以触发Dottrace分析指定方法,并生成相关测试报告。

步骤:

  1. 开发一个业务程序的Host程序,这个程序可以通过反射调用被测的业务方法;
  2. 在Jenkins中,通过PowerShell调用Dottrace的CommandProfile执行Host程序,Host程序再执行被测业务方法,生成报告。
  3. 通过邮件把生成的报告发送到我们指定的邮箱

开发Host程序

1. 按照我们公司的规范,每个接口都需要创建UnitTest,用于调试具体某个业务方法。那么,我们被测程序自然就选择这些UnitTest。
2. 做一个PerformanceAnalysisAttribute类,用于标识该方法将被用来执行性能分析。

    [AttributeUsage(AttributeTargets.Method)]      public class PerformanceAnalysisAttribute:Attribute      {          public PerformanceAnalysisAttribute()          {          }          /// <summary>          /// 暂不支持环境设置,取决于CI环境而定          /// </summary>          /// <param name="env"></param>          public PerformanceAnalysisAttribute(EnvironmentType env)          {              Env = env;          }          public PerformanceAnalysisAttribute(EnvironmentType env,params object[] args)          {              Args = args;              Env = env;          }          public Object[] Args { get; set; }          public EnvironmentType Env { get; set; }      }      public enum EnvironmentType      {          Development = 1,          Testing = 2      }

View Code

3. 开发Host程序,加载符合要求的dll,然后查找带有PerformanceAnalysisAttribute标记的方法,逐个执行

       static void Main(string[] args)          {              var methods = Load();              Console.WriteLine("Config and assemblies loaded");              FirstPreHeat(methods);              Console.WriteLine("Finished preheat");              Test(methods);              Environment.Exit(0);          }          static List<MethodInfo> Load()          {              string dllDir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;              //1. 加载目录下的*Test.dll              //2. 查找*Test.dll中,具备 包含 "PerformanceAnalysis"标签的方法              //3. 逐个执行              var files = Directory.GetFiles(dllDir, "*test.dll");              var assemblies = files.Select(p => Assembly.LoadFile(p));              List<MethodInfo> methodsToRun = new List<MethodInfo>();              foreach(var assembly in assemblies)              {                  foreach(var type in assembly.ExportedTypes)                  {                      foreach(var method in type.GetMethods())                      {                          if (method.GetCustomAttributes().Any(att => att.GetType().Name.Contains("PerformanceAnalysis")))                              methodsToRun.Add(method);                      }                  }              }              return methodsToRun;          }          static void FirstPreHeat(List<MethodInfo> methods)          {              RunTestMethod(methods);          }          static void Test(List<MethodInfo> methods)          {              RunTestMethod(methods);          }          static void RunTestMethod(List<MethodInfo> methods)          {              foreach(var method in methods)              {                  Object instance = Activator.CreateInstance(method.DeclaringType);                  method.Invoke(instance, null);                  Console.WriteLine($"{method.DeclaringType.Name}.{method.Name}执行完毕");              }          }

View Code

 

集成到Jenkins

在讲集成之前,我们再回顾一下整个测试、生成报告的过程:
  1. 在被测方法上,加上 [PerformanceAnalysis] 标签,编译,生成dll
  2. 把被测业务程序的dll复制到Host程序目录下
  3. Host在运行的时候,就会加载Test结尾的dll,并且查找里面[PerformanceAnalysis]标记的方法,然后执行这些方法
  4. 运行CommandProfiler,trace模式下运行Host程序,就会生成Host以及业务方法的性能分析报告
Jenkins就是通过powershell把这一个过程参数化、自动化。
具体步骤为:
  1. 在项目中添加一个Powershell步骤
  2. 写入如下命令:

    Invoke-Expression "chcp 65001"    write-host $ENV:TestReportPath  write-host $ENV:BUILD_TAG    $SolutionFile=$ENV:WORKSPACE+"SolutionMyProject.Dev.sln"  $ConFile=$ENV:NuGetConfigFile  $TestDlls =$ENV:WORKSPACE+"SrcMyProject.TestbinDebug*.*"  $ClearReportFiles =$ENV:WORKSPACE+"PerfResult*.*"  $ReportDir =$ENV:WORKSPACE+"PerfResult"      write-host "SolutionFile "  write-host $SolutionFile  write-host "ConFile"  write-host $ConFile    nuget restore -Force $SolutionFile -ConfigFile $ConFile  MSBuild  $SolutionFile      write-host "----------------Build Test Perf---------------------"    write-host $TestDlls  write-host $ClearReportFiles  write-host $ReportDir    write-host "-------------MKDIR------------"  $CurPerfPath =$ReportDir+$ENV:BUILD_NUMBER  write-host $CurPerfPath  mkdir $CurPerfPath    write-host "-------------COPY------------"  copy D:dottracePerformanceAnalysisHost*.* $CurPerfPath  copy $TestDlls $CurPerfPath    write-host "-------------ReportDir------------"  $CurReportPath =$ENV:WORKSPACE+"PerformanceReport"+$ENV:BUILD_NUMBER  mkdir $CurReportPath  write-host $CurReportPath    write-host "-------------ReportVar------------"  $ReportFileName =$CurReportPath +"snapshot.dtp"  $PerfToolPath =$CurPerfPath+"PerformanceAnalysisDemo.exe"  write-host $ReportFileName  write-host $PerfToolPath    write-host "-------------Report------------"  D:dottraceDotTraceCommandLineConsoleProfiler start --save-to=$ReportFileName --overwrite --profiling-type=Tracing $PerfToolPath

    View Code

  3. 把报告(或所在路径)

 运行结果:

Jenkins测试项目:

 

分析报告邮件: