I am writing an Elixir project that connects to a Postgres database via Ecto. The database server is on a different server from the application itself, and is more subject to outages that would not affect the Elixir project than if they were running on the same hardware.
我正在编写一个Elixir项目,通过Ecto连接到Postgres数据库。数据库服务器与应用程序本身位于不同的服务器上,并且与在同一硬件上运行时相比,更容易受到不会影响Elixir项目的中断。
When the application starts normally, the database connection seems to be made automatically, and everything works fine. But if there is a connection error, Ecto simply spews any errors into the log.
当应用程序正常启动时,数据库连接似乎是自动进行的,一切正常。但是如果出现连接错误,Ecto只会将任何错误发送到日志中。
What I would like to do is detect the current connection status, and report that information via a simple Plug route to an external load balancer, such that traffic can be routed to a separate server with an active connection.
我想要做的是检测当前的连接状态,并通过简单的插件路由将该信息报告给外部负载均衡器,以便可以将流量路由到具有活动连接的单独服务器。
The trouble is, I'm unsure how to determine if Ecto has a viable connection to the database, apart from listening to the log, which doesn't then report that the database connection has been restored.
麻烦的是,我不确定如何确定Ecto是否与数据库有可行的连接,除了监听日志,然后报告数据库连接已经恢复。
What can I call to determine if an Ecto connection is live and usable, preferably without making no-op queries against that connection?
我可以调用什么来确定Ecto连接是否正常并且可用,最好不要对该连接进行无操作查询?
2 个解决方案
#1
0
Ecto simply spews any errors into the log.
Ecto只是将任何错误喷射到日志中。
This is the default strategy with enabled backoff
for the connection. You can disable the backoff by setting backoff_type
to :stop
in repo options and deal with errors by yourself.
这是启用连接退避的默认策略。您可以通过将backoff_type设置为:在repo选项中停止并自行处理错误来禁用退避。
What can I call to determine if an Ecto connection is live and usable, preferably without making no-op queries against that connection?
我可以调用什么来确定Ecto连接是否正常并且可用,最好不要对该连接进行无操作查询?
I think you can check if the connection "usable" only by using it :)
我想你可以通过使用它来检查连接是否“可用”:)
try do
Ecto.Adapters.SQL.query(MyApp.Repo, "SELECT 1")
rescue
e in DBConnection.ConnectionError -> :down
end
BTW, the module mentioned above is the default pool module for the connection you can rely on its internals(don't) and do the checkout manually. Own pool can be implemented instead of this one :)
顺便说一句,上面提到的模块是连接的默认池模块,你可以依赖它的内部(不),并手动进行结账。可以实现自己的池而不是这个:)
#2
0
To detect whether a connection to the database is live and usable, you can try connecting to it directly outside of Ecto using :gen_tcp.connect/3
. The code could look something like this:
要检测与数据库的连接是否可用,您可以尝试使用以下命令直接在Ecto外部连接:gen_tcp.connect / 3。代码看起来像这样:
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
Note that Ecto gets the details of the server to connect to through the Mix config you set for it. If you want to change the server it connects to, you'll have to run Application.put_env/4
and then restart the Ecto repository for Ecto to recognize the new config. For example:
请注意,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)
#1
0
Ecto simply spews any errors into the log.
Ecto只是将任何错误喷射到日志中。
This is the default strategy with enabled backoff
for the connection. You can disable the backoff by setting backoff_type
to :stop
in repo options and deal with errors by yourself.
这是启用连接退避的默认策略。您可以通过将backoff_type设置为:在repo选项中停止并自行处理错误来禁用退避。
What can I call to determine if an Ecto connection is live and usable, preferably without making no-op queries against that connection?
我可以调用什么来确定Ecto连接是否正常并且可用,最好不要对该连接进行无操作查询?
I think you can check if the connection "usable" only by using it :)
我想你可以通过使用它来检查连接是否“可用”:)
try do
Ecto.Adapters.SQL.query(MyApp.Repo, "SELECT 1")
rescue
e in DBConnection.ConnectionError -> :down
end
BTW, the module mentioned above is the default pool module for the connection you can rely on its internals(don't) and do the checkout manually. Own pool can be implemented instead of this one :)
顺便说一句,上面提到的模块是连接的默认池模块,你可以依赖它的内部(不),并手动进行结账。可以实现自己的池而不是这个:)
#2
0
To detect whether a connection to the database is live and usable, you can try connecting to it directly outside of Ecto using :gen_tcp.connect/3
. The code could look something like this:
要检测与数据库的连接是否可用,您可以尝试使用以下命令直接在Ecto外部连接:gen_tcp.connect / 3。代码看起来像这样:
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
Note that Ecto gets the details of the server to connect to through the Mix config you set for it. If you want to change the server it connects to, you'll have to run Application.put_env/4
and then restart the Ecto repository for Ecto to recognize the new config. For example:
请注意,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)