gpt4 book ai didi

Azure函数应用程序间歇性返回502 Bad Gateway

转载 作者:行者123 更新时间:2023-12-03 02:02:36 39 4
gpt4 key购买 nike

我们的 Azure 功能已开始返回 502 Bad Gateways,但并非所有调用都返回。我没有使用“间歇性”这个词,因为它总是进行相同类型的调用,但现在总是使用相同的数据。

常规配置

  • Azure 中的操作系统:Windows
  • Azure Functions 运行时:3
  • 应用服务计划:消耗

AF 公开的 API 非常简单

  1. GET myazure.com/api/v1/entityid?quantity=1 将返回新的实体 ID
  2. PUT myazure.com/api/v1/{modelName},正文包含 JSON 格式的模型
  3. GET myazure.com/api/v1/{modelName}/{entityIdFromStep1} 将返回第 2 步中添加的模型
  4. DELETE myazure.com/api/v1/{modelName} 正文包含在第 2 步中添加的模型。此端点可以采用模型数组,并将删除所有模型

我们有一个包含 1200 次调用的测试脚本,尝试添加、检查和删除我们的所有模型和各种错误场景。这些测试使用 Postman 运行,并在 Azure Dev Ops 中运行,但如果我从本地 Postman 代理运行,问题仍然存在。返回 502 的调用是 GET,有时是第一次调用,有时是第三次或第四次调用。

我对 AF 进行了一些更改,为迁移到函数运行时 4 做准备。它们围绕依赖注入(inject)以及从函数中的静态方法迁移到非静态方法。

在测试运行期间,我确实在 App Insights 中看到了条目,但从未看到返回 502 的调用。

如果我针对上次推送到生产环境的代码运行测试,这些 502 就不会发生

最佳答案

TLDR;

这归因于两个错误的组合

  1. 错误配置 AF 的应用程序设置之一,这意味着 AF 尝试创建具有无效 uri 的 System.Uri
  2. 尝试廉价而肮脏的“一劳永逸”,如这个问题中所讨论的,FireAndForget call to WebApi from Azure Function

更详细

我们想在其中一个函数的处理结束时调用 WebApi。该 api 的基本 uri 需要可配置,并且在服务中我从配置中读取并构建 System.Uri

string azureAdClientId = Environment.GetEnvironmentVariable("AzureAd__ClientId", EnvironmentVariableTarget.Process);
string azureAdInstance = Environment.GetEnvironmentVariable("AzureAd__Instance", EnvironmentVariableTarget.Process);
string azureAdTenantId = Environment.GetEnvironmentVariable("AzureAd__TenantId", EnvironmentVariableTarget.Process);
string azureAdClientSecret = Environment.GetEnvironmentVariable("AzureAd__ClientSecret", EnvironmentVariableTarget.Process);

string uri = $"{azureAdInstance}{azureAdTenantId}/";
Uri authorityUri = new System.Uri(uri);

var app = ConfidentialClientApplicationBuilder.Create(azureAdClientId)
.WithClientSecret(azureAdClientSecret)
.WithAuthority(authorityUri)
.Build();

“AzureAd__Instance”设置在我们的 ARM 模板中命名不正确,因此 azureAdInstance 为 null,这意味着传递到 System.Uri 时的 uri 无效并会引发异常。

在正常情况下,这个异常会被捕获并记录下来,我会相对较快地解决这个问题。

但是,我使用“Fire & Forget”方法调用 WebApi,为此我滥用了异步/等待功能并调用以下方法,而无需等待它。请注意异步但没有任务返回,并且没有等待它。

public async void RequestSignalRecalc(Guid patientId, string clientTzo)
{
await this.PrepareAuthenticatedClient();

dynamic bodyObject = new ExpandoObject();
bodyObject.clientTZO = clientTzo;
string json = Newtonsoft.Json.JsonConvert.SerializeObject(bodyObject);
StringContent bodyContent = new StringContent(json, Encoding.UTF8, "application/json");

Task task = this.httpClient.PutAsync($"{this.signalApiBaseAddress}v1/patients/{patientId}/recalc", bodyContent);
}

比我聪明得多的人告诉我这是一个愚蠢的想法,但我还是这么做了,请参阅 FireAndForget call to WebApi from Azure Function 上的评论

正如问题部分中提到的,当调用因 502 失败而导致难以诊断时,Appinsights 中没有日志。我终于通过 Azure 门户中的 Kudu 工具找到了一些日志记录。请参阅高级工具 -> 工具 -> 诊断转储。这给了我一个包含 eventlog.xml 的 zip 文件。这显示了以下事件(我已经删除了其中的大部分)

1032 CoreCLR Version: 4.700.22.55902 .NET CoreVersion: 3.1.32 Description: The process was terminated due to anunhandled exception. Exception Info: System.UriFormatException:Invalid URI: The format of the URI could not be determined. atSystem.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)at System.Uri..ctor(String uriString) [OurCode] atSystem.Threading.Tasks.Task.<>c.<ThrowAsync>b__139_1(Objectstate) atSystem.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallbackquwi) atSystem.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContextexecutionContext, Action`1 callback, TState& state) atSystem.Threading.QueueUserWorkItemCallback.Execute() atSystem.Threading.ThreadPoolWorkQueue.Dispatch() atSystem.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

关键部分是异常信息、调用堆栈和“进程已终止”行,我假设这就是我从未将日志写入 App Insights 的原因。我不知道为什么它会导致 502,但我已经停止尝试做廉价和肮脏的火灾并忘记了。

这个故事的寓意是,如果聪明有经验的人建议你正在做的事情是一个坏主意,请认真考虑不这样做:-)

关于Azure函数应用程序间歇性返回502 Bad Gateway,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75648648/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com