Elixir、Phoenix和Ecto:当数据库关闭时,为缓存数据提供服务的请求变得非常慢(从100ms到3秒)

Elixir、Phoenix和Ecto:当数据库关闭时,为缓存数据提供服务的请求变得非常慢(从100ms到3秒),elixir,ecto,phoenix,Elixir,Ecto,Phoenix,我创建了一个没有html和mysql数据库的phoenix项目 我们在工作中使用的版本是: Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe] Elixir 1.8.0 (compiled with Erlang/OTP 20) 我正在做一个项目,它充当状态页面工具(hund.io)和我们自己的API和报告工具之间的代理,因此我需要一个数据库来存储服务名称

我创建了一个没有html和mysql数据库的phoenix项目

我们在工作中使用的版本是:

Erlang/OTP 21 [erts-10.2] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe]

Elixir 1.8.0 (compiled with Erlang/OTP 20)
我正在做一个项目,它充当状态页面工具(hund.io)和我们自己的API和报告工具之间的代理,因此我需要一个数据库来存储服务名称和请求的url,并且,我需要一点与数据库Cachex()分离以将数据放入缓存中

当数据被缓存时,使用邮递员请求我的包装器的api需要大约100毫秒才能得到响应,phoenix的日志显示类似于
[info]在1毫秒内发送了200个

但是,我曾经关闭过数据库,邮递员需要整整3秒钟才能收到回复,凤凰城的日志仍然说这种事情
[info]在1ms内发送了200次

我确信包装器在这两种情况下都使用缓存数据:

我的代码:

def show(conn, %{"service_name" => service_name}) do
    Logger.debug("Top of show func")

    case Cachex.get(:proxies, service_name) do
      {:ok, nil} ->
        Logger.debug("Service #{service_name} not found in cache")
        proxy = Health.get_proxy_by_name!(service_name)
        Logger.debug("Service #{service_name} found in db")
        Cachex.put(:proxies, service_name, proxy)
        proxy_with_health = Checker.call_api(proxy)

        render(conn, "show.json", proxy_health: proxy_with_health)

      {:ok, proxy} ->
        Logger.debug("Found service #{service_name} in cache")
        proxy_with_health = Checker.call_api(proxy)
        render(conn, "show.json", proxy_health: proxy_with_health)
    end
  end
日志:

[info] GET /api/proxies_health/docto
[debug] Processing with StatusWeb.ProxyHealthController.show/2
  Parameters: %{"service_name" => "docto"}
  Pipelines: [:api]
[debug] Top of show func
[debug] Found service docto in cache
对于路由器部分:

 pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/api", StatusWeb do
    pipe_through :api

    resources "/proxies", ProxyController, except: [:new, :edit]
    get "/proxies_health", ProxyHealthController, :index
    get "/proxies_health/:service_name", ProxyHealthController, :show
  end
我在日志中还发现两个错误:

[error] MyXQL.Connection (#PID<0.373.0>) failed to connect: ** (DBConnection.ConnectionError) connection refused

但是它没有改变我的问题

因为我的代码,在缓存中找到的对象的路径中没有(根本没有)涉及到数据库,我们最终在不一致的情况下发现问题来自端点中的一个插件,该插件应该只出现在开发环境中(MyAppWeb/endpoint.ex)

它是一个插件,可以在每次请求时检查数据库是否已启动、迁移是否已运行等 等待来自Ecto的应答,而genserver中的超时意识到该调用会导致所经历的延迟

解决方法是简单地对行进行注释

          plug Phoenix.Ecto.CheckRepoStatus, otp_app: :status
backoff_type: :stop
   if code_reloading? do
      plug Phoenix.CodeReloader
      plug Phoenix.Ecto.CheckRepoStatus, otp_app: :status
  end
          plug Phoenix.Ecto.CheckRepoStatus, otp_app: :status