Heroku 上的 Elixir + Phoenix:15 秒后出现超时错误
Elixir + Phoenix on Heroku : Timeout error after 15 seconds
上下文: 我是 运行 elixir+phoenix 应用程序 https://github.com/endeepak/stub_on_web on Heroku. I've followed steps mentioned in http://www.phoenixframework.org/docs/heroku 用于部署应用程序。
问题: 当一个 POST 请求超过 15 秒时,网络服务器 returns 500 Internal server error with logs showing error as no case clause matching: {:error, :timeout}
。错误堆栈粘贴在下方
2015-11-10T16:56:06.680425+00:00 app[web.1]: 16:56:06.680 request_id=19c1ba3f-cfaf-476f-a145-12d234b61c55 [info] POST /stub_urls
2015-11-10T16:56:21.684018+00:00 heroku[router]: at=info method=POST path="/stub_urls" host=stubonweb.herokuapp.com request_id=19c1ba3f-cfaf-476f-a145-12d234b61c55 fwd="43.247.159.40" dyno=web.1 connect=1ms service=15004ms status=500 bytes=243
2015-11-10T16:56:21.683882+00:00 app[web.1]: 16:56:21.683 [error] #PID<0.429.0> running StubOnWeb.Endpoint terminated
2015-11-10T16:56:21.683887+00:00 app[web.1]: Server: stubonweb.herokuapp.com:80 (http)
2015-11-10T16:56:21.683888+00:00 app[web.1]: Request: POST /stub_urls
2015-11-10T16:56:21.683889+00:00 app[web.1]: ** (exit) an exception was raised:
2015-11-10T16:56:21.683890+00:00 app[web.1]: ** (CaseClauseError) no case clause matching: {:error, :timeout}
2015-11-10T16:56:21.683891+00:00 app[web.1]: (plug) lib/plug/parsers/urlencoded.ex:10: Plug.Parsers.URLENCODED.parse/5
2015-11-10T16:56:21.683892+00:00 app[web.1]: (plug) lib/plug/parsers.ex:186: Plug.Parsers.reduce/6
2015-11-10T16:56:21.683893+00:00 app[web.1]: (stub_on_web) lib/stub_on_web/endpoint.ex:1: StubOnWeb.Endpoint.phoenix_pipeline/1
2015-11-10T16:56:21.683894+00:00 app[web.1]: (stub_on_web) lib/phoenix/endpoint/render_errors.ex:34: StubOnWeb.Endpoint.call/2
2015-11-10T16:56:21.683894+00:00 app[web.1]: (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
2015-11-10T16:56:21.683895+00:00 app[web.1]: (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
我的观察
如果请求花费的时间超过 30 秒,这不是 Heroku 路由器的 "H12 error"。参考:https://devcenter.heroku.com/articles/request-timeout。我无法从 heroku 支持中获得太多帮助,因为它似乎是网络服务器问题而且他们不知道 erlang/elixir.
我已经在本地使用生产配置尝试 运行,模拟了 60 秒的延迟。请求 returns 200 OK 在 60 秒后响应,没有任何超时错误,如上。
这里是否缺少任何配置?还有其他想法吗?
问题发生是因为我添加了一个插件来读取请求正文并将其保存为 conn 中的私有分配以供将来访问。之前使用的代码是
defp copy_req_body(conn, _) do
{:ok, body, _} = Plug.Conn.read_body(conn, length: 1_000_000_000)
Plug.Conn.put_private(conn, :raw_request_body, body)
end
plug :copy_req_body
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Poison
插件似乎存在问题,导致 Plug.Parsers 再次尝试读取正文时超时。
目前的临时解决方法是使用 https://github.com/phoenixframework/phoenix/issues/459#issuecomment-155671415
中建议的代码
参考提交:https://github.com/endeepak/stub_on_web/commit/47192558f501652edd8cd237a5a2430f38177ca4
上下文: 我是 运行 elixir+phoenix 应用程序 https://github.com/endeepak/stub_on_web on Heroku. I've followed steps mentioned in http://www.phoenixframework.org/docs/heroku 用于部署应用程序。
问题: 当一个 POST 请求超过 15 秒时,网络服务器 returns 500 Internal server error with logs showing error as no case clause matching: {:error, :timeout}
。错误堆栈粘贴在下方
2015-11-10T16:56:06.680425+00:00 app[web.1]: 16:56:06.680 request_id=19c1ba3f-cfaf-476f-a145-12d234b61c55 [info] POST /stub_urls
2015-11-10T16:56:21.684018+00:00 heroku[router]: at=info method=POST path="/stub_urls" host=stubonweb.herokuapp.com request_id=19c1ba3f-cfaf-476f-a145-12d234b61c55 fwd="43.247.159.40" dyno=web.1 connect=1ms service=15004ms status=500 bytes=243
2015-11-10T16:56:21.683882+00:00 app[web.1]: 16:56:21.683 [error] #PID<0.429.0> running StubOnWeb.Endpoint terminated
2015-11-10T16:56:21.683887+00:00 app[web.1]: Server: stubonweb.herokuapp.com:80 (http)
2015-11-10T16:56:21.683888+00:00 app[web.1]: Request: POST /stub_urls
2015-11-10T16:56:21.683889+00:00 app[web.1]: ** (exit) an exception was raised:
2015-11-10T16:56:21.683890+00:00 app[web.1]: ** (CaseClauseError) no case clause matching: {:error, :timeout}
2015-11-10T16:56:21.683891+00:00 app[web.1]: (plug) lib/plug/parsers/urlencoded.ex:10: Plug.Parsers.URLENCODED.parse/5
2015-11-10T16:56:21.683892+00:00 app[web.1]: (plug) lib/plug/parsers.ex:186: Plug.Parsers.reduce/6
2015-11-10T16:56:21.683893+00:00 app[web.1]: (stub_on_web) lib/stub_on_web/endpoint.ex:1: StubOnWeb.Endpoint.phoenix_pipeline/1
2015-11-10T16:56:21.683894+00:00 app[web.1]: (stub_on_web) lib/phoenix/endpoint/render_errors.ex:34: StubOnWeb.Endpoint.call/2
2015-11-10T16:56:21.683894+00:00 app[web.1]: (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
2015-11-10T16:56:21.683895+00:00 app[web.1]: (cowboy) src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
我的观察
如果请求花费的时间超过 30 秒,这不是 Heroku 路由器的 "H12 error"。参考:https://devcenter.heroku.com/articles/request-timeout。我无法从 heroku 支持中获得太多帮助,因为它似乎是网络服务器问题而且他们不知道 erlang/elixir.
我已经在本地使用生产配置尝试 运行,模拟了 60 秒的延迟。请求 returns 200 OK 在 60 秒后响应,没有任何超时错误,如上。
这里是否缺少任何配置?还有其他想法吗?
问题发生是因为我添加了一个插件来读取请求正文并将其保存为 conn 中的私有分配以供将来访问。之前使用的代码是
defp copy_req_body(conn, _) do
{:ok, body, _} = Plug.Conn.read_body(conn, length: 1_000_000_000)
Plug.Conn.put_private(conn, :raw_request_body, body)
end
plug :copy_req_body
plug Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Poison
插件似乎存在问题,导致 Plug.Parsers 再次尝试读取正文时超时。
目前的临时解决方法是使用 https://github.com/phoenixframework/phoenix/issues/459#issuecomment-155671415
中建议的代码参考提交:https://github.com/endeepak/stub_on_web/commit/47192558f501652edd8cd237a5a2430f38177ca4