【问题标题】:Making requests to localhost within Azure App Services application在 Azure App Services 应用程序中向 localhost 发出请求
【发布时间】:2020-04-15 16:47:42
【问题描述】:

我有一个持续的网络作业,它监听包含诊断信息的请求。

为了测试连接性,我尝试在我的网络作业中进行健康检查,但无法根据 azure 应用服务文档向 localhost 发出请求。

下面的代码是我用来验证我可以从我部署的应用程序连接的代码:

    var uri = new Uri("http://localhost:8989/ping");
    var response = await client.GetAsync(uri);

我得到了这个例外:

System.Net.Http.HttpRequestException: An error occurred while sending the request. 
---> System.Net.WebException: Unable to connect to the remote server 
---> System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:8989

Web 作业是通过 Kudu (SCM) 的站点扩展安装脚本安装的,这意味着 Web 作业最终是 Kudu (SCM) 的子进程。启动时的网络作业应用程序将自身绑定到端口 8989。在 Windows 上本地启动应用程序,我可以毫无问题地进行健康检查。

Azure 应用服务文档说,除非同一沙箱中的应用程序绑定到端口 (https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#local-address-requests),否则对 localhost 的请求将失败。

azure 应用服务文档指出 Kudu 与主应用 (https://github.com/projectkudu/kudu/wiki/Kudu-architecture#security-model) 在同一沙箱中运行。

如何通过 http 与我的网络作业进行通信?

最好是我可以从站点扩展安装过程中做的事情,但任何选项都是好的。

2019 年 12 月 26 日更新:

我已尝试强制 SCM 和主应用程序与 WEBSITE_DISABLE_SCM_SEPARATION=true (https://github.com/projectkudu/kudu/wiki/Configurable-settings#use-the-same-process-for-the-user-site-and-the-scm-site) 在同一沙箱中运行。

文档声明它们已经在同一个沙箱中运行,并且如果一个进程在同一个沙箱中侦听端口,那么这些请求应该可以工作。 值得注意的是,实际的 SCM w3wp.exe 进程已经能够使用 http 访问 localhost 以执行我的 Web 作业。不过,此设置似乎并没有改善这种情况。

2020 年 4 月 2 日更新:

我正式放弃了使用 Web 作业的想法,现在我将进程作为主应用程序实例的子进程启动。这让我可以毫无问题地与localhost:8989 交流。

虽然我现在需要管理自己的保持活动逻辑。

如果可能的话,我仍然很想知道是否有一种方法可以通过 TCP 与网络作业进行通信。

【问题讨论】:

  • 这是我发现的最相似的问题:stackoverflow.com/questions/56572039/…
  • 访问问题可能是由 Kudu 的身份验证/授权引起的。请分享客户端实例创建的详细信息。
  • 这是在请求离开应用程序上下文之前
  • 就像我在回答中建议的那样,WebJobs 的套接字连接未启用,因为它们在 IHost 容器内运行。我的回答中提供了更多详细信息。
  • GitHub 上的 Wiki 文档并不总是最新的。也不是官方文件。我怀疑这是否应该工作......

标签: .net azure http azure-web-app-service azure-app-service-envrmnt


【解决方案1】:

如何通过 http 与我的网络作业进行通信?

没有。 WebJob 无法通过 localhost 直接向站点发送请求。 此限制记录在您提供的 sandbox 页面上。

到本地地址(例如 localhost、127.0.0.1)和机器自身 IP 的连接尝试将失败,除非同一沙箱中的另一个进程在目标端口上创建了侦听套接字。

被拒绝的连接尝试,例如以下尝试从 .NET 连接到 127.0.0.1:80 的示例将导致上述异常。

更多详情可以参考这个SO thread

【讨论】:

  • 您说网络作业无法向站点发送请求,但我想要相反的方向。此外,“除非同一沙箱中的另一个进程在目标端口上创建了侦听套接字”让我相信这是可能的。
【解决方案2】:

我认为问题与分配给您的应用的端口 (8989) 有关。您需要使用其他服务(旧的云服务)、虚拟机或 Service Fabric 才能在端口 8989 上打开和接收请求。

更多信息:

网络端点监听是访问应用程序的唯一途径

通过互联网是通过已经暴露的 HTTP (80) 和 HTTPS (443) TCP 端口;应用程序可能不会在其他端口上侦听 来自互联网的数据包。但是,应用程序可能会创建一个 可以侦听来自沙箱内的连接的套接字。为了 例如,同一应用程序中的两个进程可能与一个进程通信 另一个通过 TCP 套接字;从外部传入的连接尝试 沙盒,尽管它们在同一台机器上,但会失败。看下一个 主题以获取更多详细信息。

https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox

【讨论】:

  • 如果我动态选择一个空闲端口,它也不起作用。
【解决方案3】:

您不应该在您的 WebJob 中实现 HTTP 服务器,因为这不是它们的预期运行方式。

WebJob 基本上在 IHost 容器内执行,该容器专为无头服务而设计,可以促进后台处理任务。与IWebHost 不同,IHost 不适合网络托管。

因此,您创建的 WebJob 可能没有有效地将自身绑定到您提到的端口。如果是这样,沙盒的安全策略很可能会限制对用户创建的任意套接字的访问,而不是那些为访问您的站点和 kudu 服务而公开的套接字。这在您共享的错误堆栈跟踪 sn-p 中由 "System.Net.Sockets.SocketException: An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:8989" 准确指出。

如何通过 http 与我的网络作业进行通信? - 可以通过WebJobs API 建立与 WebJob 的通信。

您可能必须创建 多个 WebJobs 来实现您尝试的 HTTP 服务器实现所期望的各种功能。

参考文献

【讨论】:

    猜你喜欢
    • 2016-06-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 2019-06-21
    • 2018-08-22
    • 2018-06-26
    • 2020-11-30
    • 1970-01-01
    相关资源
    最近更新 更多