在Windows上运行Phoenix时,内存泄漏/持续高CPU使用率 [英] Memory leak/constant high CPU usage when running Phoenix in IIS on Windows

查看:257
本文介绍了在Windows上运行Phoenix时,内存泄漏/持续高CPU使用率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有运行 Windows 10 IIS 8 的虚拟机。我安装



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







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

解决方案

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



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



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

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

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


I am trying to prototype a small web application to see if I can use Phoenix and Elixir to build some intranet web applications for use by my co-workers at my company. We've been a typical Microsoft .NET shop forever, but I'm interested in playing with some other technologies, with Elixir and Phoenix being two of them.

I have a virtual machine running Windows 10 and IIS 8. I installed HttpPlatformHandler on the VM as well to run the Phoenix application and pass requests to it from IIS (there's a reason for this, which I'll get to in a moment).

When I run my Phoenix app standalone on Windows, it runs great. I don't see any issues. When I run my Phoenix app using HttpPlatformHandler and IIS, I see the erl.exe process constantly running and consuming about 35-40% of the CPU (I'm running with 2 cores and 8GB RAM on the VM). I also see the memory constantly growing without stopping. After a couple of minutes, it will blow past 1GB and move on its way to 2GB (I'm watching memory usage using Process Explorer). There's no load or active requests on the Phoenix app. This happens in both dev and prod environments.

I want to run Phoenix behind IIS because it's an intranet application and it will be running on a Windows domain and most of the users will be Windows users. I created a plug that will read the Windows user token from the X-IIS-WindowsAuthToken HTTP header that HttpPlatformHandler adds to the requests that it forwards to the Phoenix process, and I'm using a set of NIFS to call the Windows API to get the Windows SID and domain\username of the authenticated user in order to establish the session and authorize the user.

Has anyone tried this before and seeing the same issue? I'm relatively new to Elixir and Phoenix debugging and would love some hints on what I can do to try to figure out why the Erlang runtime is doing this, or how to determine if it's something that I'm doing in my code.

I'm not sure that it's me, because I see this happening on a plain Phoenix application that is freshly generated using mix phoenix.new.

For reference, here's my web.config for my Phoenix application:

<?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>

My run.bat file:

mix phoenix.server

I greatly appreciate any assistance or suggestions that anyone can provide. Please let me know if there's anything else that I can provide that would be helpful in diagnosing the problem.

Thank you in advance.

UPDATE

I figured out how to connect to my Phoenix application running in IIS using Observer thanks to this gist. It looks like the problem process is the user process:

I started tracing on this process and the port that it is linked to and I see a continual stream of what I am guessing are receive events with empty data:

I'm guessing from looking around that this is the kernel user process. Does anyone know how I can figure out what that port is and why it's sending a continual stream of events?

解决方案

I figured out the solution to this. This is where my newbie status to Elixir and Erlang came into play. When you run an Elixir/Erlang application, the Erlang user server gets started to handle standard I/O for the application. On the second image in my question update, you can see that port <10014.664> controls "0/1". My understanding now is that basically means 0 == standard input and 1 == standard output.

The issue when running with HttpPlatformHandler is that the Phoenix application is running without a shell and there would never be anything coming in via standard input. So when you run using the default settings, standard input basically floods the user server with a bunch of empty data messages.

The solution is to tell the Erlang VM and the user server to ignore standard input. In my run.bat script, I was running mix phoenix.server, but based off the gist that I used to name the node so that I could attach Observer to it, I changed my run.bat script to this:

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

The -noinput flag appears to tell the Erlang VM to never read from standard input. With -noinput passed to the command line, the memory issue went away and CPU usage is typically below 0.2% while idle. CPU and memory appear to be the same as if the Phoenix application were running from a console outside of IIS.

这篇关于在Windows上运行Phoenix时,内存泄漏/持续高CPU使用率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆