架构师训练营第 7 周课后练习

用户头像
菜青虫
关注
发布于: 2020 年 12 月 06 日
  1. 性能压测的时候,随着并发压力的增加,系统响应时间和吞吐量如何变化,为什么?



并发数比较低时,系统资源比较充足,随着并发数的增加,响应时间可以近似恒定,TPS近似线性增长;当并发数超过某个点后,资源请求可能会排队等待,响应时间会变长,TPS增长开始变缓;当并发数继续增加达到系统最大负载点后,某些系统资源可能已经耗尽,响应时间会变得非常长,TPS开始急剧下降,直到系统崩溃



  1. 用你熟悉的编程语言写一个 Web 性能压测工具,输入参数:URL,请求总次数,并发数。输出参数:平均响应时间,95% 响应时间。用这个测试工具以 10 并发、100 次请求压测 www.baidu.com。



namespace Geektime.LoadTest
{
public class LoadTestOption
{
public int RequestCount { get; set; }
public int ConcurrentCount { get; set; }
public string TargetUrl { get; set; }
}
}



using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
namespace Geektime.LoadTest
{
class LoadTestEngine : BackgroundService
{
private readonly LoadTestOption option;
private readonly ILogger logger;
private readonly IHostApplicationLifetime lifetime;
public LoadTestEngine(
LoadTestOption option,
ILogger<LoadTestEngine> logger,
IHostApplicationLifetime lifetime
)
{
this.option = option;
this.logger = logger;
this.lifetime = lifetime;
}
protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
await Task.Delay(1000);
var tasks = new List<Task>();
var globalTotal = 0;
var globalTimings = new ConcurrentBag<double>();
for (var i = 0; i < this.option.ConcurrentCount; i++)
{
var task = Task.Factory.StartNew((state) =>
{
var threadId = Thread.CurrentThread.ManagedThreadId;
this.logger.LogInformation($"{threadId}: task start");
var localTotal = 0;
while (true)
{
Interlocked.Increment(ref globalTotal);
if (globalTotal > this.option.RequestCount)
break;
++localTotal;
DateTime startTime = DateTime.Now;
var request = WebRequest.Create(this.option.TargetUrl);
request.GetResponse();
globalTimings.Add((DateTime.Now - startTime).TotalMilliseconds);
}
this.logger.LogInformation($"{threadId}: task end with {localTotal} requests");
}, null, TaskCreationOptions.LongRunning);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
try
{
var average = globalTimings.Average();
var percentile = GetPercentile(globalTimings, 0.95);
this.logger.LogInformation($"Avg: {average : 0.00}ms");
this.logger.LogInformation($"95th: {percentile : 0.00}ms");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
this.lifetime.StopApplication();
}
protected static double GetPercentile(IEnumerable<double> seq, double percentile)
{
var elements = seq.ToArray();
Array.Sort(elements);
double realIndex = percentile * (elements.Length - 1);
int index = (int)realIndex;
double frac = realIndex - index;
if (index + 1 < elements.Length)
return elements[index] * (1 - frac) + elements[index + 1] * frac;
else
return elements[index];
}
}
}



15: task start
9: task start
10: task start
7: task start
13: task start
12: task start
14: task start
16: task start
11: task start
8: task start
15: task end with 10 requests
11: task end with 9 requests
14: task end with 9 requests
7: task end with 11 requests
9: task end with 11 requests
10: task end with 10 requests
16: task end with 9 requests
12: task end with 10 requests
8: task end with 10 requests
13: task end with 11 requests
Avg: 25.91ms
95th: 144.47ms



用户头像

菜青虫

关注

还未添加个人签名 2017.11.20 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第 7 周课后练习