我如何检测 Elixir Ecto 的数据库连接问题?

How do I detect database connection issues from Elixir Ecto?

我正在编写一个通过 Ecto 连接到 Postgres 数据库的 Elixir 项目。数据库服务器与应用程序本身位于不同的服务器上,与 运行 在同一硬件上相比,更容易发生不会影响 Elixir 项目的中断。

当应用程序正常启动时,数据库连接似乎是自动建立的,一切正常。但是,如果出现连接错误,Ecto 会将所有错误简单地输出到日志中。

我想做的是检测当前连接状态,并通过简单的 Plug 路由向外部负载均衡器报告该信息,这样流量就可以路由到具有活动连接的单独服务器。

问题是,我不确定如何确定 Ecto 是否与数据库建立了可行的连接,除了侦听日志之外,日志不会报告数据库连接已恢复。

我可以调用什么来确定 Ecto 连接是否有效且可用,最好不要对该连接进行空操作查询?

要检测与数据库的连接是否有效且可用,您可以尝试使用 :gen_tcp.connect/3 在 Ecto 之外直接连接到它。代码可能如下所示:

case :gen_tcp.connect('127.0.0.1', 5432, []) do
  {:ok, _} ->
    # code for handling ok scenario
  {:error, error} ->
    # code for handling error scenario. Typically, you'll get the econnrefused error when the server is down
end

请注意,Ecto 通过您为其设置的 Mix 配置获取要连接的服务器的详细信息。如果你想更改它连接的服务器,你必须 运行 Application.put_env/4 然后重新启动 Ecto 存储库以便 Ecto 识别新配置。例如:

Application.put_env(:my_app, MyApp.Repo, [adapter: Ecto.Adapters.Postgres, username: "postgres", password: "postgres",database: "new_db", hostname: "different_host.com", pool_size: 20])
Supervisor.stop(MyApp.Repo)

Ecto simply spews any errors into the log.

这是默认策略 with enabled backoff for the connection。您可以通过在 repo 选项中将 backoff_type 设置为 :stop 来禁用退避并自行处理错误。

What can I call to determine if an Ecto connection is live and usable, preferably without making no-op queries against that connection?

我想你可以检查连接是否 "usable" 只有使用它:)

try do
  Ecto.Adapters.SQL.query(MyApp.Repo, "SELECT 1")
rescue
  e in DBConnection.ConnectionError -> :down
end

顺便说一句,上面提到的模块 the default pool module 用于连接,您可以依赖它的内部结构(不要)并手动进行结帐。可以实现自己的池而不是这个 :)