Web 应用程序是 REST API 和 SPA。它已得到维护,目前在 .NET 6.0 上运行,多年来一直稳定运行。
请求是 CORS,并且服务器已为此正确配置。
突然间,我们每天都会爆发几次
POST
和 PUT
请求,持续失败并出现 500 服务器错误。而且它们很快就会失败,只有 30 毫秒。这种情况持续 5-15 分钟,然后再次恢复正常。
所有
GET
请求在其间仍然工作得很好,这很奇怪。
更奇怪的是,这些失败的请求不会被记录下来,就像它们从未到达网络服务器一样。检查了 Web 服务器日志 (IIS) 和 ASP.NET Core 应用程序异常和跟踪。
这些失败的请求中也缺少响应标头
X-Powered-By: ASP.NET
。正常的 500 服务器错误会出现这种情况。
还表明请求永远不会到达服务器。
应用服务计划当前仅使用 30% 的资源。
Chrome、Edge 和 Safari 也证实了相同的行为。但是,您可能会在 Chrome 中遇到问题,而 Edge 中的会话在同一台 PC 上可以完美运行。
如果我们关闭浏览器并重新打开,问题就消失了。
这一切都从本月开始:2024 年 5 月。
还值得一提的是,我们有一个 DNS 负载均衡器,Azure 流量管理器。
这只适用于 DNS 查询并返回 REST API 服务的两个实例中最接近的一个。
因此,流量管理器不会记录任何请求。
更新确认也发生错误没有流量管理器。
更新 2 我们已经测试了在全新应用服务上的部署。并尝试升级到.NET8.0。没有效果
这使得我们只能在浏览器的网络日志中进行检查。我们导出了许多 HAR 文件,并寻找失败请求和工作请求之间的差异,但没有发现任何差异。
有人经历过类似的行为吗?
Startup.cs
中ASP.NET Core的配置:
public class Startup
{
readonly string _corsPolicyName = "corsOrigins";
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; }
private static IConfiguration config;
public static IConfiguration GetConfiguration()
{
return config;
}
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
config = configuration;
Environment = environment;
}
public void ConfigureServices(IServiceCollection services)
{
if (Environment.IsDevelopment())
IdentityModelEventSource.ShowPII = true;
// logging
services.AddApplicationInsightsTelemetry();
services.AddLogging(logging =>
{
logging.AddSimpleConsole();
logging.AddAzureWebAppDiagnostics();
});
services.Configure<AzureFileLoggerOptions>(options =>
{
options.FileName = "filelog-";
options.FileSizeLimit = 50 * 1024;
options.RetainedFileCountLimit = 5;
});
services.Configure<AzureBlobLoggerOptions>(options =>
{
options.BlobName = "Backend.txt";
});
// so our claims will not be translated
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
// configure languages
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("en"),
new CultureInfo("no")
};
options.DefaultRequestCulture = new RequestCulture("en");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
// add Identity
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<AuthContext>()
.AddRoleManager<RoleManager<ApplicationRole>>()
.AddDefaultTokenProviders();
services.AddUserAndPasswordPolicies();
services.AddCors(options =>
{
{
options.AddPolicy(_corsPolicyName, builder =>
builder.SetIsOriginAllowedToAllowWildcardSubdomains()
.WithOrigins("https://*.our.domain")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
}
});
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.MapInboundClaims = false;
o.Authority = Configuration.GetValue<string>("authServerUrl");
o.Audience = "backend";
o.RequireHttpsMetadata = true;
o.SaveToken = true;
o.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "role",
ValidateIssuer = true,
ValidateAudience = true
};
});
services.AddControllersWithViews(options =>
{
options.Filters.Add<WebCustomExceptionFilter>();
})
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
});
services.AddSignalRManager();
services.AddRazorPages()
.AddRazorRuntimeCompilation();
services.AddSwaggerGenNewtonsoftSupport();
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo { Title = "server debug api spec", Version = "v1" });
options.SchemaFilter<EnumSchemaFilter>();
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
StaticEnvironment.IsDebug = env.IsDevelopment();
StaticEnvironment.ContentRootPath = env.ContentRootPath;
app.UseCors(_corsPolicyName);
if (env.IsDevelopment())
{
app.UseStaticFiles();
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => {
c.DocumentTitle = "Backend Swagger docs";
var sidebar = Path.Combine(env.ContentRootPath, "wwwroot/sidebar.html");
c.HeadContent = File.ReadAllText(sidebar);
c.InjectStylesheet("/colors.css");
c.InjectStylesheet("/style.css");
c.SwaggerEndpoint("/swagger/v1/swagger.json", "server");
});
}
else
{
app.UseHttpsRedirection();
app.UseHsts();
}
// Localization
app.UseRequestLocalization();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Enable static files for use in MVC views.
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), @"Style")),
RequestPath = new PathString("/Style")
});
}
}
典型控制器签名:
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class ImprovementController : ControllerBase
Web客户端获取代码
const fullUrl = `${baseUrl}/${url}`
const bearer = getBearer()
const connectionId = getConnectionId()
const req = {
method: "POST",
headers: {
"Authorization": bearer,
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}
const res = await fetch(fullUrl, req)
微软收到了几张罚单。请参阅https://learn.microsoft.com/en-us/answers/questions/1687258/our-azure-app-service-application-started-to-exper
我们有同样的问题,很多其他人也有。 Post 请求随机失败并出现 500 错误,而获取工作正常。一段时间后又可以工作了。显然可以通过将 HTTP/2 设置回 HTTP/1.1 来修复它
我希望在下周一所有客户都恢复工作时确认这一点