public Tester(string host, string userId, Counter c, DelayCounter dc, DelayCounter prepareConnectCounter, HttpClient httpClient) { this.host = host; _httpClient = httpClient; Counter = c; DelayCounter = dc; PrepareConnectCounter = prepareConnectCounter; if (string.IsNullOrWhiteSpace(userId)) { this.userId = Guid.NewGuid().ToString(); } else { this.userId = userId; } Task.Run(async() => { await Connect(); }); }
private void OnConnected() { // record the reconnection cost long reconnectCost = 0; if (_timestampWhenConnectionClosed != 0) { reconnectCost = Utils.Timestamp() - _timestampWhenConnectionClosed; DelayCounter.Add(reconnectCost); if (reconnectCost > 40000) { logger.Info($"user {userId} reconnected cost {reconnectCost} ms"); } _timestampWhenConnectionClosed = 0; } logger.Info($"user {userId} Connected,cost {(DateTimeOffset.UtcNow - lastConnectTime).TotalMilliseconds} ms"); IsConnected = true; IsConnecting = false; Counter.ConnectionSuccess(); }
static void Main(string[] args) { NLog.Logger logger = NLog.LogManager.GetLogger("PerformanceTest.Program"); //if (args.Length > 0 && args[args.Length - 1].StartsWith("&")) //{ // Array.Resize(ref args, args.Length - 1); //} CommandLine.Parser.Default.ParseArguments <Options>(args) .WithParsed <Options>(async(options) => { Random random = new Random(); if (options.ThreadCount < 1) { logger.Error("线程数配置错误"); return; } else if (options.Size > 10000 || options.Size < 1) { logger.Error("消息字节数配置错误"); return; } else if (options.DelayMilliseconds < 10) { logger.Error("消息间隔不能低于10毫秒"); return; } else if (string.IsNullOrWhiteSpace(options.Url) || !options.Url.StartsWith("http")) { logger.Error("服务器地址错误"); return; } else if (options.AvgCount < 10 || options.AvgCount > 1000) { logger.Error("AvgCount配置错误"); return; } else if (options.UserIdPrfix.Length > 40) { logger.Error("UserIdPrfix配置错误"); return; } if (string.IsNullOrWhiteSpace(options.UserIdPrfix)) { options.UserIdPrfix = "user-" + random.Next(1000, 9999); } var httpClient = new HttpClient(); ConcurrentBag <Tester> testers = new ConcurrentBag <Tester>(); DelayCounter dc = new DelayCounter(); DelayCounter counter4PrepareConnect = new DelayCounter("PrepareConnectCounter.txt"); Counter c = null; if (options.UseCounter == 1) { c = new Counter(); } else { logger.Info("Counter is not set"); } await Task.Run(() => { logger.Info("start connections"); var sw = new Stopwatch(); sw.Start(); for (int i = 1; i <= options.ThreadCount; i++) { var tester = new Tester(options.Url, options.UserIdPrfix + "_" + i, c, dc, counter4PrepareConnect, httpClient) { AvgCount = options.AvgCount }; int retry = 10; while (retry > 0) { retry--; if (tester.IsConnected) { testers.Add(tester); logger.Info($"start {i} instance"); break; } Thread.Sleep(TimeSpan.FromMilliseconds(100)); } } sw.Stop(); logger.Info($"Build {options.ThreadCount} connections takes {sw.ElapsedMilliseconds} ms"); logger.Info($"Finish startup with {testers.Count} instances"); }); c?.StartPrint(); dc.StartPrint(); counter4PrepareConnect.StartPrint(); await Task.Run(async() => { logger.Info("start sending"); byte[] content = new byte[options.Size]; while (true) { DateTimeOffset start = DateTimeOffset.UtcNow; foreach (Tester tester in testers) { if (!tester.IsConnected) { await tester.Connect(); } else { random.NextBytes(content); tester.RunTest(content); } } TimeSpan delay = TimeSpan.FromMilliseconds(options.DelayMilliseconds) - (DateTimeOffset.UtcNow - start); if (delay.TotalMilliseconds > 0) { Thread.Sleep(delay); //logger.Info($"delay {delay}"); } } }); c?.Dispose(); dc.Dispose(); httpClient.Dispose(); }).WithNotParsed <Options>(error => { logger.Error("参数错误"); }); Thread.Sleep(int.MaxValue); }