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

时间:2017-03-12 22:02:16

标签: iis elixir phoenix-framework

我正在尝试原型化一个小型Web应用程序,看看我是否可以使用Phoenix和Elixir构建一些内部网Web应用程序供我公司的同事使用。我们一直是一个典型的Microsoft .NET商店,但我有兴趣玩其他一些技术,Elixir和Phoenix就是其中两个。

我有一台运行Windows 10IIS 8的虚拟机。我在VM上安装了HttpPlatformHandler以运行Phoenix应用程序并从IIS传递请求(这是有原因的,我稍后会介绍)。

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

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

有没有人在尝试过此之前看过同样的问题?我对Elixir和Phoenix的调试相对较新,并且会喜欢我可以做些什么来试图找出Erlang运行时为什么会这样做,或者如何确定它是否是我在我的代码中所做的事情。 / p>

我不确定这是不是我,因为我发现这是在使用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>

我的run.bat文件:

mix phoenix.server

我非常感谢任何人提供的任何帮助或建议。如果我能提供其他任何有助于诊断问题的信息,请告诉我。

提前谢谢。

更新

由于this gist,我想出了如何使用Observer连接到我在IIS中运行的Phoenix应用程序。看起来问题过程是用户进程:

Observer Processes tab showing the user process consuming memory

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

Observer Ports tab

Trace log for the user process and its port

我猜测这是内核用户进程。有谁知道我怎么能弄清楚那个端口是什么以及为什么它会发送连续的事件流?

1 个答案:

答案 0 :(得分:3)

我找到了解决方法。这是我对Elixir和Erlang的新手身份发挥作用的地方。当您运行Elixir / Erlang应用程序时,Erlang用户服务器开始处理应用程序的标准I / O.在我的问题更新中的第二个图像上,您可以看到该端口&lt; 10014.664&gt;控制“0/1”。我现在的理解是基本上意味着0 ==标准输入和1 ==标准输出。

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

解决方案是告诉Erlang VM和用户服务器忽略标准输入。在我的run.bat脚本中,我运行mix phoenix.server,但基于我曾经命名节点的要点,以便我可以将Observer附加到它,我将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外部的控制台运行时相同。