效能優化之三:將Dottrace過程加入持續整合
阿新 • • 發佈:2020-04-07
之前分享過一篇如何做介面效能分析的文章,但是整個分析過程有點繁瑣,需要寫一個控制檯程式呼叫被測介面,再預熱、啟動dottrace追蹤,最後才能得到我們想要的效能分析報告。如果有辦法一鍵生成效能分析報告,那就會省很多不必要的時間。這裡我們就藉助Jenkins自動化完成這一過程。
目標:
把Dottrace的效能分析整合到Jenkins中,使我們在構建的時候,可以觸發Dottrace分析指定方法,並生成相關測試報告。步驟:
- 開發一個業務程式的Host程式,這個程式可以通過反射呼叫被測的業務方法;
- 在Jenkins中,通過PowerShell呼叫Dottrace的CommandProfile執行Host程式,Host程式再執行被測業務方法,生成報告。
-
通過郵件把生成的報告發送到我們指定的郵箱
開發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 }
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}執行完畢"); } }
整合到Jenkins
在講整合之前,我們再回顧一下整個測試、生成報告的過程:- 在被測方法上,加上 [PerformanceAnalysis] 標籤,編譯,生成dll
- 把被測業務程式的dll複製到Host程式目錄下
- Host在執行的時候,就會載入Test結尾的dll,並且查詢裡面[PerformanceAnalysis]標記的方法,然後執行這些方法
- 執行CommandProfiler,trace模式下執行Host程式,就會生成Host以及業務方法的效能分析報告
- 在專案中新增一個Powershell步驟
- 寫入如下命令:
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 - 把報告(或所在路徑)
執行結果:
Jenkins測試專案:
分析報告郵件: