Goreplay来做流量回放
最近做項目,用到goreplay來做流量回放,什么是goreplay?
GoReplay is an open-source network monitoring tool which can record your live traffic, and use it for shadowing, load testing, monitoring and detailed analysis.
本質(zhì)上就是通過監(jiān)控網(wǎng)絡,錄制http請求信息(對應用無入侵),然后再把請求重新播放出來。
這是官方給出來運行原理圖。
關(guān)于goreplay的使用方式,命令用法官方文檔給的很全面了,不作贅述,本篇文章關(guān)注的是除雜(過濾)。官方本來是支持過濾filtering的,但過濾的范圍有限,目前只有Allow?url regexp,Disallow url regexp,Filter based on regexp of header,Filter based on HTTP method,也就是對url,header,method三個方向作了過濾,我的需求是對body過濾,不包括在范圍內(nèi)(也有可能我沒找到對應文檔)
官方找不到對應辦法,只能“曲線救國”了,因為goreplay錄制的內(nèi)容是文本性質(zhì),所以可以對錄制內(nèi)容下手,把自己認定的雜質(zhì)除掉,然后再播放,這樣就達到效果了。
錄制:
我是在windows下demo的,所以下載goreplay的winodwst版本【https://github.com/buger/goreplay/releases/download/v1.3.2/gor-1.3.2_windows.zip】,同時還需要安裝WinPcap配合【https://www.winpcap.org/install/bin/WinPcap_4_1_3.exe】,這樣就可以通過命令進行錄制了:
gor?--input-raw?:5000?--output-file?request.gor
被錄制的服務是一個api,實現(xiàn)如下
[HttpPost("/order")] public IActionResult Post([FromBody] Order order) {_logger.LogInformation(System.Text.Json.JsonSerializer.Serialize(order));order.Status = 200;return new JsonResult(order); }public class Order {public string Code { get; set; }public?decimal?Amount?{?get;?set;?}public int Status { get; set; } }gorreplay錄制的內(nèi)容格式如下:
除雜
文中的json就是我請求的body,就要依據(jù)這個json中的一些數(shù)據(jù)來除雜,所以就得寫段代碼解決這個事情。
其實原理很簡單,因為我知道我請求的都是json,所以就是從錄制的文件中,按段切割,很明細就是三只猴子????????????為分割點,把內(nèi)容中的json查詢出來,然后運用上規(guī)則引擎達到過濾作用,把符合條件的數(shù)據(jù)留下,不符合條件的數(shù)據(jù)就除雜,最后保存成一個新文件,供流量回放時使用。
規(guī)則引擎
桂素偉,公眾號:桂跡一個簡單的規(guī)則引擎例子
步驟確定了,下面是代碼:
using RulesEngine; using RulesEngine.Models; using RulesEngine.Extensions; using System.IO; using System.Text; using System.Text.RegularExpressions; using Newtonsoft.Json.Converters; using Newtonsoft.Json; using System.Dynamic;var path = @"C:\MyFile\Source\Repos\Asp.NetCoreExperiment\Asp.NetCoreExperiment\GoReplay\GoReplayDemo01\request_0.gor"; var expression = "input1.amount >= 900.00"; await ImpurityRemoval(path, expression);/// <summary> /// 除雜方法,會重新生成一個帶有日期時間的新.gor文件 /// </summary> static async Task ImpurityRemoval(string path, string expression) {using var readFile = new StreamReader(path, Encoding.UTF8);using var writeFile = new StreamWriter(@$"{path.Replace(Path.GetFileName(path), Path.GetFileNameWithoutExtension(path) + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + Path.GetExtension(path))}", true, Encoding.UTF8);var split = "????????????";string? line;var request = new StringBuilder();while ((line = await readFile.ReadLineAsync()) != null){if (line != split){request.Append(line + "\n");}else{request.Append(line + "\n");var list = GetJson(request.ToString());foreach (var item in list){var converter = new ExpandoObjectConverter();var entity = JsonConvert.DeserializeObject<ExpandoObject>(item, converter);if (await Filter(entity, expression)){await writeFile.WriteAsync(request.ToString());}}request.Clear();}} } /// <summary> /// 獲取json,這里沒有完全測試 /// </summary> static List<string> GetJson(string jsonString) {var pattern = @"\{(.|\s)*\}";var list = new List<string>();var matches = Regex.Matches(jsonString, pattern, RegexOptions.IgnoreCase);foreach (Match m in matches){list.Add(m.Value);}return list; } /// <summary> /// 用規(guī)則引擎匹配過濾規(guī)則 /// </summary> static async Task<bool> Filter(dynamic? entity, string expression) {var workRules = new WorkflowRules();workRules.WorkflowName = "ImpurityRemoval";workRules.Rules = new List<Rule>{new Rule{RuleName="ImpurityRemoval01",SuccessEvent= "10",RuleExpressionType= RuleExpressionType.LambdaExpression,Expression= expression, }};var rulesEngine = new RulesEngine.RulesEngine(new WorkflowRules[] { workRules });List<RuleResultTree> resultList = await rulesEngine.ExecuteAllRulesAsync("ImpurityRemoval", entity);var result = false;resultList.OnSuccess((eventName) =>{result = true;});return result; }回放
gor?--input-file=request_0_20210821234723.gor?--output-http="http://localhost:5000"
注意事項:
在錄制的時候本機請求不進行錄制,需要外部訪問api
在除雜過程中,重新生成gor文件時,換行一定要UNIX(LF),不要是Windows(CRLF),說人話就是生成文件的換行用\n,不要\r\n,否則回放時goreplay不起作用
總結(jié)
以上是生活随笔為你收集整理的Goreplay来做流量回放的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SqlBulkCopy只支持SQL Se
- 下一篇: 如何对 string 进行Base64编