Azure:为什么我的前端应用程序容器客户端无法向我的后端应用程序容器服务器发出 gRPC 请求

问题描述 投票:0回答:1

注意:我的整个应用程序部署在 Azure 上,并且位于同一虚拟网络 (vnet1) 中。我的应用程序是用 Go 构建的,并使用 gRPC 从客户端向服务器发出请求。我正在测试的整个流程在本地运行时有效。

设置

我正在 Azure 上构建一个标准 Web 应用程序。我正在利用一个 Azure MySql 数据库、一个为我的后端服务部署映像的应用程序容器、另一个为我的前端服务部署映像的应用程序容器,以及一个允许公共访问我的前端的 API 网关,该网关与虚拟网络中的后端和数据库。

请求的生命周期因此可以被视为这样(对于任何不良的格式表示歉意):


                 *Within a virtual network
                 The API Gateway acts as the public access point*
                 ----------------------------------------------------------------
                |                *within the same container app environment*     |
                |                ----------------------------------------        |
user_browser -> | API Gateway -> | frontendContainer -> backendContainer | -> DB |
                |                ----------------------------------------        |
                 ----------------------------------------------------------------

我确实有一个通配符私有 DNS 区域,以便我面向公众的 API 网关可以将请求路由到我的 vnet 包含的容器应用程序中。这会将

azurecontainerapps.io
映射到容器应用程序环境的静态 IP 地址,后端和前端容器都位于其中。这应该意味着 APIGateway->Frontend 和 Frontend->Backend 请求都应使用此 DNS 列表将基于容器的 FullQualifiedDomainName 的请求路由到容器应用程序环境,然后使用端口号路由到正确的容器/端点.

问题

TLDR;为什么前端容器中的 gRPC 客户端无法成功与后端容器上的 gRPC 服务器建立 gRPC 连接/调用?

我的数据库已启动并正在运行。我可以通过公共接入点远程连接到它来验证这一点(我稍后会清理它)。 我的 backendContainer 也已启动并正在运行,容器上的日志显示它正在正确连接到数据库。 然而,frontendContainer 没有成功连接到后端容器,我不明白为什么。 API网关正在按预期工作,并且frontendContainer的网站已按预期公开可用。 frontendContainer 和 backendContainer 都位于同一个应用程序容器应用程序环境 (containerAppEnv1) 中,并且也位于同一个虚拟网络 (vnet1) 中。后端容器公开端口 8080。这反映在服务的 docker 文件以及后端容器的入口配置中:

az containerapp show --name {name} --resource-group {group_name} --query properties.configuration.ingress --output json { "additionalPortMappings": null, "allowInsecure": true, "clientCertificateMode": "Ignore", "corsPolicy": null, "customDomains": null, "exposedPort": 0, "external": true, "fqdn": "{redacted}", "ipSecurityRestrictions": null, "stickySessions": { "affinity": "none" }, "targetPort": 8080, "traffic": [ { "latestRevision": true, "weight": 100 } ], "transport": "Http2" }

前端服务器在启动时使用上面输出中给出的后端服务器的FullyQualifiedDomainName 启动与后端服务器的连接,代码如下:

// Set up a connection to the backend server. conn, err := grpc.Dial(cfg.BackendURL, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatalf("did not connect: %v", err) } onboardingClient = onboardingpb.NewOnboardingServiceClient(conn)

连接在创建时不会失败,但第一次尝试向客户端发出请求时,出现以下错误:

Error: {"message": "connection error: desc = "transport: Error while dialing: dial tcp {containerAppEnvironmentStaticIpAddress}:8080: i/o timeout""}

更新:似乎当我尝试阻止与后端建立的连接时,它失败并导致崩溃循环前端 Pod,当我尝试向前端发出请求时,Web 控制台上显示以下错误:

upstream connect error or disconnect/reset before headers. retried and the latest reset reason: connection termination

我已经在这个问题上绞尽脑汁了,不明白为什么前端服务无法成功向后端服务发出请求,尽管拥有 FQDN 并且位于同一个 VNet 上。我真的很感激任何人的帮助:)

我已验证:

后端容器正在运行
  • 前端容器正在运行
  • 两个容器都位于同一容器应用程序环境和 vnet 中
  • 后端容器启用入口
  • 后端容器的端口 8080 可用,并且应用程序正在侦听该端口
  • 前端应用程序/容器正在向容器应用程序环境的静态 IP 和预期端口 8080 发出请求。我的理解是,这应该自动路由到正在侦听此端口的容器应用程序环境中的正确容器。
  • 整个流程在本地主机上运行时有效
azure azure-web-app-service azure-container-instances
1个回答
0
投票

lis, err := net.Listen("tcp", ":8080") if err != nil { log.Fatalf("failed to listen: %v", err) } server := grpc.NewServer() onboardingpb.RegisterOnboardingServiceServer(server, s)

	
© www.soinside.com 2019 - 2024. All rights reserved.