我们正在开发我们的第一个单页面应用程序,并注意到静态文件时的一些意外行为。
我们通过使用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降低接受率:文件描述符之外
答案 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)$}
]
]
或类似的。调整此设置仅观看您想要观看的内容。
在test
和production
环境中,此标志显然根本没有设置。您似乎也可能希望确保wrk
运行在test
环境。