Почему Kestrel не обрабатывает больше HTTP-соединений одновременно, когда обработчики работают медленно?
У меня есть приложение ASP .NET Core Web API по умолчанию с одним обработчиком:
[HttpGet("{x}")]
public string Get(string x)
{
var guid = Guid.NewGuid();
var start = DateTime.Now;
Console.WriteLine($"{guid}\t1\tSTRT\t{start}");
var sb = new StringBuilder();
using (var conn = new OracleConnection(CONN_STR)) {
using (var cmd = conn.CreateCommand()) {
conn.Open();
Console.WriteLine($"{guid}\t2\tCONN\t{DateTime.Now - start}");
cmd.CommandText = "select hello4(:x) from dual";
var nameParam = cmd.CreateParameter();
nameParam.ParameterName = "x";
nameParam.Value = x;
cmd.Parameters.Add(nameParam);
var ret = cmd.ExecuteScalar();
if (ret is string xname) {
sb.Append("{\"x\":");
sb.Append(x);
sb.Append("\",\"xname\":\"");
sb.Append(xname);
sb.Append("\"}");
} else {
sb.Append("{\"error\":\"no data found\"}");
}
}
}
Console.WriteLine($"{guid}\t3\tDONE\t{DateTime.Now - start}");
return sb.ToString();
}
Я загружаю тест, используя вегету: vegeta attack -targets=targets.txt -duration=10s -rate=100 -timeout=0 | vegeta report
,
когда hello4
быстро, я вижу в stdout, что обработчик вызывается 100 раз в секунду.
когда hello4
содержит dbms_lock.sleep(1);
чтобы смоделировать дополнительное время обработки, я вижу, что обработчик вызывается гораздо реже, примерно 20 раз. Я действительно ожидал, что он будет по-прежнему вызываться примерно 100 раз в секунду, создавая дополнительную нагрузку на БД и исчерпывая SGA (мой пул соединений предел 1024).
Почему этого не происходит и как я могу заставить его одновременно обрабатывать больше входящих соединений?
1 ответ
Бег cmd.ExecuteScalar
в Task
Это была правильная идея, но она должна быть длительной, чтобы не блокировать все потоки в пуле приложений:
private static TaskFactory<object> tf = new TaskFactory<object>();
//and in the method
await tf.StartNew((Func<object>)cmd.ExecuteScalar, TaskCreationOptions.LongRunning).ConfigureAwait(false);
Это позволяет Kestrel продолжать обрабатывать входящие соединения с той скоростью, с которой они поступают.