在Windows上的IIS中运行Phoenix时内存泄漏/持续高CPU使用率

在Windows上的IIS中运行Phoenix时内存泄漏/持续高CPU使用率,iis,elixir,phoenix-framework,Iis,Elixir,Phoenix Framework,我正在尝试制作一个小型web应用程序的原型,看看是否可以使用Phoenix和Elixir构建一些intranet web应用程序,供我公司的同事使用。我们永远都是典型的微软.NET商店,但我对其他一些技术感兴趣,Elixir和Phoenix就是其中的两种 我有一个运行windows10和iis8的虚拟机。我安装在VM上也是为了运行Phoenix应用程序,并从IIS向其传递请求(这是有原因的,我稍后会谈到) 当我在Windows上独立运行Phoenix应用程序时,它运行得非常好。我看不出有什么问题

我正在尝试制作一个小型web应用程序的原型,看看是否可以使用Phoenix和Elixir构建一些intranet web应用程序,供我公司的同事使用。我们永远都是典型的微软.NET商店,但我对其他一些技术感兴趣,Elixir和Phoenix就是其中的两种

我有一个运行
windows10
iis8
的虚拟机。我安装在VM上也是为了运行Phoenix应用程序,并从IIS向其传递请求(这是有原因的,我稍后会谈到)

当我在Windows上独立运行Phoenix应用程序时,它运行得非常好。我看不出有什么问题。当我使用
HttpPlatformHandler
和IIS运行我的Phoenix应用程序时,我看到erl.exe进程不断运行,消耗了大约35-40%的CPU(我在虚拟机上运行2个内核和8GB RAM)。我还看到记忆不断增长,没有停止。几分钟后,它将超过1GB,并朝2GB的方向发展(我正在使用Process Explorer观察内存使用情况)。Phoenix应用程序上没有加载或活动请求。这在dev和prod环境中都会发生

我想在IIS后面运行Phoenix,因为它是一个intranet应用程序,将在Windows域上运行,并且大多数用户都是Windows用户。我创建了一个插件,该插件将从
X-IIS-WindowsAuthToken
HTTP头读取Windows用户令牌,HTTP头将
HttpPlatformHandler
添加到它转发给Phoenix进程的请求中,我正在使用一组NIF来调用Windows API,以获取经过身份验证的用户的Windows SID和domain\username,从而建立会话并授权用户

以前有没有人尝试过这一点,并看到了同样的问题?我对Elixir和Phoenix调试还比较陌生,希望得到一些提示,告诉我如何尝试找出Erlang运行时为什么要这样做,或者如何确定这是否是我在代码中正在做的事情

我不确定是我,因为我在一个普通的Phoenix应用程序上看到了这种情况,该应用程序是使用
mix Phoenix.new
新生成的

以下是我的Phoenix应用程序的
web.config
,仅供参考:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="httpplatformhandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/>
    </handlers>
    <httpPlatform processPath="C:\Projects\neucode\run.bat"
        arguments=""
        stdoutLogEnabled="true"
        forwardWindowsAuthToken="true">
      <environmentVariables>
        <environmentVariable name="MIX_ENV" value="prod"/>
      </environmentVariables>
    </httpPlatform>
  </system.webServer>
</configuration>
我非常感谢任何人能够提供的任何帮助或建议。请让我知道,如果有任何其他我可以提供,将有助于诊断问题

先谢谢你

更新

多亏了,我知道了如何使用Observer连接到在IIS中运行的Phoenix应用程序。问题进程似乎是用户进程:

我开始跟踪这个进程及其链接的端口,我看到一个连续的流,我猜是带有空数据的接收事件:


环顾四周,我猜测这是内核用户进程。有人知道我如何知道该端口是什么,以及它为什么会发送连续的事件流吗?

我找到了解决方案。这就是我对长生不老药和二郎的新手身份发挥作用的地方。运行Elixir/Erlang应用程序时,Erlang用户服务器将开始处理应用程序的标准I/O。在我的问题更新的第二张图片上,您可以看到端口控制“0/1”。我现在的理解是,这基本上意味着0==标准输入,1==标准输出

使用
HttpPlatformHandler
运行时的问题是,Phoenix应用程序在没有外壳的情况下运行,并且永远不会有任何东西通过标准输入进入。因此,当您使用默认设置运行时,标准输入基本上会向用户服务器发送大量空数据消息

解决方案是告诉ErlangVM和用户服务器忽略标准输入。在我的run.bat脚本中,我运行的是
mix phoenix.server
,但根据我用来命名节点以便将观察者附加到它的要点,我将run.bat脚本更改为:

elixir --name phoenix@127.0.0.1 --cookie PUT_COOKIE_HERE --erl "-noinput" -S mix phoenix.server

-noinput
标志会告诉Erlang VM永远不要读取标准输入。将
-noinput
传递到命令行后,内存问题消失,空闲时CPU使用率通常低于0.2%。CPU和内存似乎与Phoenix应用程序在IIS之外的控制台上运行时一样。

如果这种组合能起作用,我会有点惊讶,因为Phoenix和IIS一样是web服务器。@Onriocatenacci为什么不能起作用?这就像使用NGINX或Apache作为代理服务器一样。但它确实有效。我唯一看到的是奇怪的CPU和内存问题。但是web应用程序本身的工作没有问题。我只想说,用IIS包装Phoenix,这样你就可以获得广告认证(这听起来像是你正在尝试做的),这让我觉得是一个很大的难题——不管它是否可行。@OnorioCatenacci这是原因之一,但肯定不是唯一的一个,我甚至不会批评它是一个胡言乱语。在我看来,这有点不合适。这是一个合理的使用案例,尤其是在目标平台中的Windows和Phoenix不应该有任何问题像这样运行的情况下。我要指出的是,他们在指南中用NGINX和Apache记录了这种配置。在Windows身份验证方面,如果您有任何替代方法,我会非常开放。我认为在这种情况下,唯一非黑客/非笨拙的解决方案是为AD身份验证编写NIF。IIS和Phoenix似乎都有相同的用途(Nginx和Apache也是如此),因此将它们结合起来似乎有点笨拙。
elixir --name phoenix@127.0.0.1 --cookie PUT_COOKIE_HERE --erl "-noinput" -S mix phoenix.server