我有以下服务:
public class ServerApp : AppHostHttpListenerPoolBase
{
public ServerApp() : base("Server", 500,
typeof(TestService).Assembly)
{
}
public override void Configure(Container container)
{
ThreadsPerProcessor = 50;
}
}
public class TestService : Service
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
public object Any(Hello hello)
{
_logger.Info("Received: " + hello.Name);
var waitingMinutes = new Random().Next(1, 10);
Thread.Sleep(TimeSpan.FromMinutes(waitingMinutes));
_logger.Info("Response: " + hello.Name);
return new GoodBye(){Message = "Bye Bye " + hello.Name};
}
}
}
我有一个简单的测试项目来将并行请求推送到服务(并且推送一切正常),但Service一次只处理2个请求。处理完请求后,应处理下一个请求。
如何增加并发流程?
答案 0 :(得分:0)
ServiceStack的AppHostHttpListenerPoolBase
通过在新的ThreadPool线程上执行服务来同时执行Service。
为了证明这一点,我创建了一个独立的示例,该示例执行50个并发请求,这些请求在30-60秒之间休眠,根据ConcurrencyTest.cs调用此服务的示例调用独立测试:
public class SleepTest : IReturn<SleepTestResponse>
{
public string Name { get; set; }
public int WaitingSecs { get; set; }
}
public class SleepTestResponse
{
public string Message { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
public class TestConcurrencyService : Service
{
public object Any(SleepTest request)
{
var sw = Stopwatch.StartNew();
Thread.Sleep(TimeSpan.FromSeconds(request.WaitingSecs));
return new SleepTestResponse
{
Message = $"{request.Name} took {sw.Elapsed.TotalSeconds} secs",
};
}
}
使用此客户端负载测试执行,在30-60秒之间执行50个并发请求:
var rand = new Random();
var client = new JsonHttpClient(Config.AbsoluteBaseUri);
client.GetHttpClient().Timeout = TimeSpan.FromMinutes(5);
long responsesReceived = 0;
long totalSecondsWaited = 0;
var sw = Stopwatch.StartNew();
const int ConcurrentRequests = 50;
ConcurrentRequests.Times(i =>
{
Interlocked.Increment(ref responsesReceived);
ThreadPool.QueueUserWorkItem(async _ => {
var request = new SleepTest {
Name = $"Request {i+1}",
WaitingSecs = rand.Next(30, 60),
};
Interlocked.Add(ref totalSecondsWaited, request.WaitingSecs);
log.Info($"[{DateTime.Now.TimeOfDay}] Sending {request.Name} to sleep for {request.WaitingSecs} seconds...");
try
{
var response = await client.GetAsync(request);
log.Info($"[{DateTime.Now.TimeOfDay}] Received {request.Name}: {response.Message}");
}
catch (Exception ex)
{
log.Error($"[{DateTime.Now.TimeOfDay}] Error Response: {ex.UnwrapIfSingleException().Message}", ex);
}
finally
{
Interlocked.Decrement(ref responsesReceived);
}
});
});
等待所有线程完成:
while (Interlocked.Read(ref responsesReceived) > 0)
{
Thread.Sleep(10);
}
log.Info($"Took {sw.Elapsed.TotalSeconds} to execute {ConcurrentRequests} Concurrent Requests waiting a total of {totalSecondsWaited} seconds.");
结果是:
INFO:执行246.4556327执行50个并发请求,总共等待2228秒。
,如果请求没有同时执行,那么就会少得多。
显示请求的full log for all requests执行时间略长于请求服务器等待的时间。
您指出的2并发限制表明它是每个域的http客户端连接限制。您应该确保使用的负载测试工具没有wrk或apacahe bench这些限制。
请注意,如果您想要自助托管ServiceStack服务的最大吞吐量,我们建议running ServiceStack on .NET Core,最好是在.NET Core运行时,但如果需要,您还可以运行ServiceStack ASP.NET Core on the .NET Framework。