性能优化之三:将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+"\Solution\MyProject.Dev.sln"
    $ConFile=$ENV:NuGetConfigFile
    $TestDlls =$ENV:WORKSPACE+"\Src\MyProject.Test\bin\Debug\*.*"
    $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:\dottrace\PerformanceAnalysisHost\*.* $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:\dottrace\DotTraceCommandLine\ConsoleProfiler start --save-to=$ReportFileName --overwrite --profiling-type=Tracing $PerfToolPath
    View Code
  3. 把报告(或所在路径)

 运行结果:

Jenkins测试项目:

 

分析报告邮件:

 

 

 

 

posted @ 2020-04-07 17:24  Snow~Forever  阅读(345)  评论(0编辑  收藏  举报