c# - Kestrel 将传入的同时请求堆积起来,直到所有请求都堆积起来才读取它们
问题描述
我要求在 10 秒内处理多达 5000 个。问题是 Kestrel 的某个地方似乎存在瓶颈。同时客户端请求越多,我在阅读第一个请求的正文时的延迟就越大。极简的测试控制台应用程序如下:
public interface IMyHandler
{
Func<HttpContext, string> Handler { get; set; }
}
public class MyHandler : IMyHandler
{
public Func<HttpContext, string> Handler { get; set; }
}
public class Startup : IStartup
{
IMyHandler MyHandler;
public Startup(IMyHandler h)
{
MyHandler = h;
}
public void Configure(IApplicationBuilder app)
{
var this_ = this;
app.Run(context =>
{
MyHandler.Handler(context);
var response = String.Format("Hello, Universe! It is {0}", DateTime.Now);
return context.Response.WriteAsync(response);
});
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
// Add framework services
return services.BuildServiceProvider();
}
}
class Program
{
static void Main(string[] args)
{
EventWaitHandle success = new AutoResetEvent(false);
var sentRequests = 0;
var serverTask = Task.Run(() =>
{
MyHandler h1 = new MyHandler();
h1.Handler = (context) =>
{
using (BufferedStream buffer = new BufferedStream(context.Request.Body))
{
using (var reader = new StreamReader(buffer))
{
var body = reader.ReadToEnd();
var _sent = sentRequests;
//success.Set();
}
}
return "OK";
};
var host = new WebHostBuilder()
.UseKestrel((context, options) =>
{
//options.ApplicationSchedulingMode = SchedulingMode.Inline;
options.ListenAnyIP(21122, listenOptions =>
{
});
})
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureServices(services =>
{
services.Add(Microsoft.Extensions.DependencyInjection.ServiceDescriptor.Singleton(typeof(IMyHandler), h1));
})
//.UseIISIntegration()
.UseStartup<Startup>()
//.UseApplicationInsights()
.Build();
host.Run();
});
Enumerable.Range(0, 100).ForEach((n) => {
var clientTask = Task.Run(async () =>
{
var handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
sentRequests++;
var p1 = await client.PostAsync("http://localhost:21122", new StringContent("{test:1}", Encoding.UTF8, "application/json"));
});
});
Assert.IsTrue(success.WaitOne(new TimeSpan(0, 0, 50)));
}
}
对于给定的 100 个请求,我在第一次读取正文时已经有大约 12 秒的延迟。要看到这个,只需在线设置断点
var _sent = sentRequests;
sentRequests 也等于 100,这意味着(这实际上是一些推测,但似乎是合理的)此时所有请求都已发送。这在我看来好像这两件事是由单线程完成的,虽然它接受请求但并没有开始阅读它们。
任何想法如何克服这个问题?
解决方案
推荐阅读
- gpflow - 缺少输入的 GPFlow 中的多任务学习?
- c++ - 将 QAbstractTableModel 与 QML TableView 连接起来
- c# - 强化扫描的路径操纵问题报告
- javascript - 在 React 中为数组中的每个项目创建按钮时,如何根据数组值传入唯一的 onClick 参数?
- ios - 每次创建单元格时,UIPageViewController 中的图像都会在 UICollectionView 中重复。使用库在滚动视图中显示图像
- optimization - 这个向量和问题的一般名称是什么?
- javascript - 不要进入 submit() 函数
- assembly - 检查用户输入是否导致溢出
- php - 我有一个静态表单模板硬拷贝。我想给它添加文字
- flask - 使用flask.create_app时如何在flask.Blueprint中使用oidc(OpenIDConnect对象)?