You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 5 API 数据库连接断开时返回自定义JSON响应解决方案咨询

解决方案

1. 控制器层全局捕获数据库连接异常

在app/controllers/application_controller.rb中添加全局异常捕获逻辑,这是最简便的实现方式:

class ApplicationController < ActionController::API
  # 捕获所有数据库连接相关异常
  rescue_from ActiveRecord::ConnectionNotEstablished,
              Mysql2::Error::ConnectionError,
              ActiveRecord::StatementInvalid,
              with: :handle_database_unavailable

  private

  def handle_database_unavailable
    # 返回503服务不可用状态码,符合HTTP语义
    render json: { error: "Database unavailable" }, status: :service_unavailable
  end
end

注意:开发环境默认会展示异常详情页,如需测试该效果,可修改config/environments/development.rb中的config.consider_all_requests_local = false

2. 可选:添加Rack中间件实现更前置的拦截

如果需要在请求进入控制器层之前就完成数据库状态检查(避免部分前置插件触发连接异常无法被控制器捕获),可以自定义Rack中间件:

  1. 新建app/middleware/database_connection_check.rb
class DatabaseConnectionCheck
  def initialize(app)
    @app = app
  end

  def call(env)
    # 提前检查数据库连接是否可用
    ActiveRecord::Base.connection.verify!
    @app.call(env)
  rescue ActiveRecord::ConnectionNotEstablished, Mysql2::Error::ConnectionError
    [503, { "Content-Type" => "application/json" }, [{ error: "Database unavailable" }.to_json]]
  end
end
  1. 在config/application.rb中注册中间件,放在中间件链的靠前位置:
config.middleware.insert_before 0, DatabaseConnectionCheck

3. 优化数据库连接超时配置

在你的database.yml的default块中添加超时参数,避免连接异常时请求长时间卡住:

default: &default
  adapter: mysql2
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: XXXX
  password: XXXX
  host:  XXXX.com
  port: 3306
  encoding: utf8mb4
  # 新增超时配置,单位为秒
  connect_timeout: 2
  read_timeout: 3
  write_timeout: 3

关于旧版本Rails静态页可正常访问的说明

旧版本Rails处理静态资源请求时,不会主动触发数据库连接获取;现在的Rails版本尤其是API模式下,默认不托管静态资源,生产环境静态资源一般由Nginx等反向代理直接处理,所有进入Rails进程的请求基本都会触发业务逻辑、主动获取数据库连接,因此会出现全应用不可用的表现。如果有不需要依赖数据库的接口,可以在中间件或者控制器中跳过数据库连接检查逻辑。

内容的提问来源于stack exchange,提问作者Hussain Niazi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 06:12:01