【发布时间】:2017-11-27 06:47:39
【问题描述】:
我有两台服务器运行一个非常简单的 Phoenix 框架 API,每周左右,其中一台服务器开始抛出 502 错误。
15:35:08.260 [error] 'File operation error: emfile. Target: /usr/lib/erlang/lib/stdlib-3.2/ebin/erl_posix_msg.beam. Function: get_file. Process: code_server.'
15:35:08.323 [error] 'File operation error: emfile. Target: erl_posix_msg.beam. Function: get_file. Process: code_server.'
15:35:08.324 [error] GenServer #PID<0.6569.17> terminating
** (UndefinedFunctionError) function :erl_posix_msg.message/1 is undefined (module :erl_posix_msg is not available)
(stdlib) :erl_posix_msg.message(:emfile)
(redix) lib/redix.ex:393: Redix.format_error/1
(redix) lib/redix/connection.ex:108: Redix.Connection.connect/2
(connection) lib/connection.ex:622: Connection.enter_connect/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: nil
State: %Redix.Connection{backoff_current: nil, opts: [socket_opts: [], sync_connect: false, backoff_initial: 500, backoff_max: 30000, log: [disconnection: :error, failed_connection: :error, reconnection: :info], exit_on_disconnection: false, host: "redis.host.not", port: 6379], receiver: nil, shared_state: nil, socket: nil}
15:35:08.324 [error] Ranch protocol #PID<0.6568.17> (:cowboy_protocol) of listener Auth.Endpoint.HTTP terminated
** (exit) an exception was raised:
** (UndefinedFunctionError) function :erl_posix_msg.message/1 is undefined (module :erl_posix_msg is not available)
(stdlib) :erl_posix_msg.message(:emfile)
(redix) lib/redix.ex:393: Redix.format_error/1
(redix) lib/redix/connection.ex:108: Redix.Connection.connect/2
(connection) lib/connection.ex:622: Connection.enter_connect/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
如果我只是重新启动凤凰服务器,繁荣,一切又开始工作了。显然这不是一个可扩展的解决方案,但我正在努力诊断发生了什么。
任何帮助都会很甜蜜。
谢谢
【问题讨论】:
-
emfile=too many files open(blog.izs.me/post/56827866110/…)。某些东西很可能会泄漏文件描述符,并且它在一周后达到了打开文件的数量限制。 -
好点,你没看错。所以我跑了:
ulimit -a并为此...打开文件(-n)1024 ...然后我运行:lsof -i -n -P | wc -l` 打开总连接数(99% 到 Redis)。结果是 1028。所以这绝对是问题所在。那么接下来的问题是为什么 Elixir/Phoenix 没有杀死文件描述符。 -
你能把代码贴在你创建 Redix 实例的地方吗?也许它们由于某种原因没有关闭,或者您创建了太多实例。
-
所以我正在使用Redix,我有一个非常简单的模块,如下所示:gist.github.com/jakowicz/7c46bfcdd16216322d844f63183b8a61 get_conn 方法在每个控制器之前由插件运行,而 kill_conn 方法正在运行通过我们的响应模块,我使用日志来保证连接终止肯定正在运行。
-
一周后您只有约 1000 个额外连接。也许
kill_conn不在某些极端情况下?
标签: erlang elixir phoenix-framework gen-server beam