在应用程序运行多个线程的情况下,我对 owin 自托管 Web 服务器的响应能力有一个奇怪的问题。
我提供了一个演示问题的简单示例:
- Web 服务器启动
- 应用程序开始 150(虚拟线程)
- 如果您尝试调用 http://localhost:5000/api/administration/getAllSmtpSettings
- 你不会在 30-40 秒内得到回应
- CPU使用率一般在7-10%
申请代码:
using System;
using System.Threading;
using System.Threading.Tasks;
using Test.Api;
namespace Test.Web
{
class Program
{
public static void RunWebServer()
{
Task.Factory.StartNew(() =>
{
StartWebServer();
}, TaskCreationOptions.LongRunning);
}
private static void StartWebServer()
{
WebServer.StartWebServer();
while (true)
{
Thread.Sleep(10);
}
}
private static void StartThreads(int maxthreads)
{
for (int m = 0; m < maxthreads; m++)
{
Task.Factory.StartNew(() =>
{
while (true)
{
Thread.Sleep(1000);
}
});
Thread.Sleep(10);
}
}
static void Main(string[] args)
{
RunWebServer();
StartThreads(150);
Console.ReadKey();
}
}
}
网络服务器代码:
using Microsoft.Owin.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Ninject;
using Ninject.Web.Common;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Reflection;
using System.Web.Http;
namespace Test.Api
{
//************************************WEB SERVER*************************************
public class RouteConfig
{
public static HttpConfiguration RegisterRoutes()
{
var config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
return config;
}
}
public static class NinjectConfig
{
public static Lazy<IKernel> CreateKernel = new Lazy<IKernel>(() =>
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
RegisterServices(kernel);
return kernel;
});
private static void RegisterServices(KernelBase kernel)
{
kernel.Bind<IAdministrationManager>().To<AdministrationManager>().InRequestScope();
}
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = RouteConfig.RegisterRoutes();
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// Add Ninject middleware
app.UseNinjectMiddleware(() => NinjectConfig.CreateKernel.Value);
app.UseNinjectWebApi(config);
// Use JSON formater
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
config.Formatters.JsonFormatter.SerializerSettings =
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
config.Formatters.JsonFormatter.SerializerSettings.Converters
.Add(new StringEnumConverter());
//app.UseWebApi(config);
}
}
public class WebServer
{
private static IDisposable _webApplication = null;
public static void StartWebServer()
{
try
{
var webPort = 5000;
var httpHost = "localhost";
StartOptions options = new StartOptions();
options.Urls.Add($"http://{httpHost}:{webPort}");
Console.WriteLine($"Url used http://{httpHost}:{webPort}");
_webApplication = WebApp.Start<Startup>(options);
Console.WriteLine("Web server successfully started");
}
catch(Exception)
{
}
}
}
//************************************MANAGERS*************************************
public interface IAdministrationManager
{
string GetAllSmtpSettings();
}
public class AdministrationManager : IAdministrationManager
{
public string GetAllSmtpSettings()
{
Console.WriteLine("Response");
return "JESSSSSSSSSSSSSSS" + Guid.NewGuid().ToString();
}
}
//************************************Controllers*************************************
[RoutePrefix("api/administration")]
public class AdministrationController : ApiController
{
IAdministrationManager _mng = null;
public AdministrationController(IAdministrationManager mng)
{
_mng = mng;
}
[HttpGet]
[Route("getAllSmtpSettings")]
public HttpResponseMessage GetAllSmtpSettings()
{
var result = _mng.GetAllSmtpSettings();
Console.WriteLine("Response created");
return Request.CreateResponse(HttpStatusCode.OK, result);
}
}
}
用过的包:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Castle.Core" version="4.3.1" targetFramework="net471" />
<package id="LimitsMiddleware" version="3.2.0" targetFramework="net471" />
<package id="LimitsMiddleware.OwinAppBuilder" version="3.2.0" targetFramework="net471" />
<package id="Microsoft.AspNet.Cors" version="5.2.7" targetFramework="net471" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.2" targetFramework="net471" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.2" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.7" targetFramework="net471" />
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.7" targetFramework="net471" />
<package id="Microsoft.Owin" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.Cors" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.Diagnostics" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.FileSystems" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.Host.HttpListener" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.Hosting" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.Security" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.Security.Cookies" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.Security.OAuth" version="4.0.1" targetFramework="net471" />
<package id="Microsoft.Owin.StaticFiles" version="4.0.1" targetFramework="net471" />
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net471" />
<package id="Ninject" version="3.3.4" targetFramework="net471" />
<package id="Ninject.Extensions.ContextPreservation" version="3.3.1" targetFramework="net471" />
<package id="Ninject.Extensions.Factory" version="3.3.2" targetFramework="net471" />
<package id="Ninject.Extensions.NamedScope" version="3.3.0" targetFramework="net471" />
<package id="Ninject.Web.Common" version="3.3.1" targetFramework="net471" />
<package id="Ninject.Web.Common.OwinHost" version="3.3.1" targetFramework="net471" />
<package id="Ninject.Web.WebApi" version="3.3.0" targetFramework="net471" />
<package id="Ninject.Web.WebApi.OwinHost" version="3.3.0" targetFramework="net471" />
<package id="Owin" version="1.0" targetFramework="net471" />
<package id="Owin.Limits" version="1.0.1.0" targetFramework="net471" />
</packages>
我试图让服务器运行线程优先,但它没有帮助。在最初的 30-40 秒后,Web 服务器开始正确响应。
提前感谢您的任何帮助或建议。