phoenix打开静态文件的频率/时间是多少?

时间:2017-04-28 12:28:38

标签: static elixir phoenix-framework

我们正在开发我们的第一个单页面应用程序,并注意到静态文件时的一些意外行为。

我们通过使用Plug.Static包含我们的静态文件来设置endpoint.ex:

plug Plug.Static,
    at: "/", from: :app,
    only: ~w(js index.html robots.txt)

我们的router.ex包含以下路由:

scope "/", App do
    pipe_through :browser # Use the default browser stack
    get "/*path", PageController, :index
end

PageController重定向到静态文件:

@index "/index.html"

def index(conn, _params) do
   redirect(conn, to: @index)
end

我们希望在服务器启动时加载一次静态文件。 但是,当我们使用wrk来测试(结果如下)性能并注意到对 /index.html (静态资源)的请求只是对任何其他路由的请求的一半。使用PageController的重定向。

./wrk -t4 -c200 -d30S --timeout 2000 "http://localhost:4000/index.html"
Running 30s test @ http://localhost:4000/index.html
  4 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
  Latency    46.39ms   31.24ms 443.14ms   95.68%
  Req/Sec     1.13k   264.38     1.49k    80.27%
134494 requests in 30.03s, 92.89MB read
   Socket errors: connect 0, read 30, write 0, timeout 0
Requests/sec:   4478.30
Transfer/sec:      3.09MB

./wrk -t4 -c200 -d30S --timeout 2000 "http://localhost:4000/anythingelse"
Running 30s test @ http://localhost:4000/indexjhtml
  4 threads and 200 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    30.88ms   49.61ms 760.40ms   94.79%
    Req/Sec     2.16k   679.55     4.58k    75.39%
256135 requests in 30.08s, 105.08MB read
Requests/sec:   8515.77
Transfer/sec:      3.49MB

我们想知道为什么与重定向到静态资源的其他路径相比,使用直接路由访问静态资源的请求更慢。

当我们希望它只打开一次时,静态文件似乎会多次打开。

也许有人可以向我们解释静态资源?

我们(有时)在为 /index.html 进行测试时会收到警告

  

13:59:00.247 [warn] Ranch acceptor降低接受率:文件描述符之外

2 个答案:

答案 0 :(得分:2)

  

我们想知道为什么与重定向到静态资源的其他路径相比,请求使用直接路由访问静态资源的速度较慢。

这是因为wrk不遵循重定向。这可以通过计算统计信息中每个请求的字节来验证。

/index.html:30.03s中的134494个请求,每个请求读取92.89MB = ~724个字节

/anythingelse:30.08s中256135个请求,105.08MB读取=每个请求大约430个字节

根据/anythingelse/index.html小于wrk

430字节的响应只是phoenix为redirect(conn, to: "/index.html")写的302重定向响应。正如您所期望的那样,只需编写302响应比读取和写入文件index.html的内容更快。

  

当我们希望它只打开一次时,静态文件似乎会多次打开。

Plug.Static提供的文件不会被读取和缓存一次;他们会在每个请求中从磁盘读取。如果要在编译时将内容存储在内存中,可以在控制器中读取该文件,然后在操作中自行编写:

@index_html File.read!("path/to/index.html)

def index(conn, _params) do
  send_resp(conn, 200, @index_html)
end

答案 1 :(得分:0)

在开发模式下,通过设置监视文件以进行实时重新加载,phoenix使您可以轻松地开发应用程序。该设置位于config/dev.exs

config :your_app, YourApp.Web.Endpoint,
  ...
  watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
               cd: Path.expand("../assets", __DIR__)]]


# Watch static and templates for browser reloading.
config :your_app, YourApp.Web.Endpoint,
  live_reload: [
    patterns: [
      ~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
      ~r{priv/gettext/.*(po)$},
      ~r{lib/your_app/web/views/.*(ex)$},
      ~r{lib/your_app/web/templates/.*(eex)$}
    ]
  ]

或类似的。调整此设置仅观看您想要观看的内容。

testproduction环境中,此标志显然根本没有设置。您似乎也可能希望确保wrk运行test环境