如何启用 Solid Queue 作为 Rails 默认后台队列并配置 Workers 与 Dispatchers

📅 发布时间:2026/9/9 23:33:29
如何启用 Solid Queue 作为 Rails 默认后台队列并配置 Workers 与 Dispatchers
如何启用 Solid Queue 作为 Rails 默认后台队列并配置 Workers 与 Dispatchers【免费下载链接】railsRuby on Rails项目地址: https://gitcode.com/GitHub_Trending/rai/rails这篇文章解决一个具体任务在 Rails 8.0 及以上版本的应用中启用 Solid Queue 作为 Active Job 的默认后台队列并配置config/queue.yml中的 Workers 与 Dispatchers。完成后可得到的结果是任务持久化在数据库中而不是内存里进程重启不丢任务并通过bin/jobs start或 Puma 插件拉起一套独立的后台处理进程。Solid Queue 是一个基于数据库的队列后端它复用你现有的数据库来持久化和执行任务不需要 Redis 这类额外组件。它支持延迟任务、任务优先级、并发控制、周期性任务和批量入队自 Rails 8.0 起就是默认队列后端。启用前检查适配器与数据库配置新建的 Rails 应用已经默认引入 Solid Queue。应用Gemfile中包含gem solid_cache gem solid_queue生产环境的默认配置位于config/environments/production.rb# config/environments/production.rb # Replace the default in-process and non-durable queuing backend for Active Job. config.active_job.queue_adapter :solid_queue config.solid_queue.connects_to { database: { writing: :queue } }同时config/database.yml中配置了一个名为queue的独立数据库连接# config/database.yml production: primary: : *default database: storage/production.sqlite3 queue: : *default database: storage/production_queue.sqlite3 migrations_paths: db/queue_migrate这里有一个必须核对的点database.yml中的queue键名必须与config.solid_queue.connects_to里使用的键名一致两者不匹配会导致 Solid Queue 找不到数据库。文档说明 Rails 8 默认让 Solid Queue 使用独立数据库以避免与应用数据共享事务带来的隐式耦合。初始化数据库并验证表结构启用步骤只有一条命令——为数据库创建 Solid Queue 相关表$ bin/rails db:prepare执行完成后的验证方式查看自动生成的db/queue_schema.rb。该文件包含solid_queue_jobs、solid_queue_recurring_executions、solid_queue_scheduled_executions等表看到这些表定义即说明初始化成功。启动处理进程Workers、Dispatchers 与 SupervisorSolid Queue 用三种进程处理任务的入队与执行Workers 轮询队列取出可以执行的任务并运行Dispatchers 处理计划任务——检查未来到期的任务把它们移入就绪队列供 Workers 取走Supervisor 通过 fork 并监控的方式管理前两者。启动整条链路即 Supervisor 进程的命令是$ bin/jobs startbin/jobs start拉起的是 Supervisor它按照config/queue.yml的配置 fork 并管理 Workers 与 Dispatchers。配置 Workers 与 Dispatchersconfig/queue.yml是可选文件。不提供任何配置时Solid Queue 以 1 个 dispatcher 和 1 个 worker 的默认设置运行。需要调整时参考默认配置示例# config/queue.yml default: default dispatchers: - polling_interval: 1 batch_size: 500 workers: - queues: * threads: 3 processes: % ENV.fetch(JOB_CONCURRENCY, 1) % polling_interval: 0.1文档给出的主要配置项及其默认值选项说明默认值polling_intervalworker/dispatcher 检查新任务前的等待秒数dispatcher 1 秒worker 0.1 秒batch_size每批派发dispatched的任务数量500concurrency_maintenance_intervaldispatcher 检查可解除阻塞任务的等待秒数600 秒queuesworker 从哪些队列取任务支持*表示全部队列或队列名前缀*threads每个 worker 的线程池最大尺寸决定一次取多少任务3processessupervisor fork 的 worker 进程数每个进程可占一个 CPU 核心1concurrency_maintenancedispatcher 是否执行并发维护工作true上表之外还有可配置项文档指引参考 Solid Queue 官方文档的 configuration 章节也可在config/environment.rb中设置更多应用级选项。用队列顺序控制优先级队列顺序是 Solid Queue 中控制处理顺序的主要机制worker 配置中queues数组的排列顺序就是轮询顺序后面的低优先级队列只有在前面所有高优先级队列清空后才会被取任务。production: workers: - queues: [critical, default, low] threads: 5上面配置下critical队列有待处理任务时不会取default队列的任务critical或default有任务时不会取low。文档明确提醒Solid Queue 是严格排序不像其他后端按权重分配份额高优先级队列持续繁忙时低优先级队列可能被饿死。queue_with_priority设置的数值优先级只在同一队列内部生效跨队列不生效两者同时使用时队列顺序优先。队列名支持通配符例如queues: [active_storage*, mailers]会先取所有active_storage前缀队列如active_storage_analyze、active_storage_transform的任务清空后才轮到mailers。但文档警告在 SQLite 和 PostgreSQL 上通配符队列名需要额外的DISTINCT查询来匹配队列任务量大时会拖慢轮询性能。按队列调整轮询间隔polling_interval直接决定 worker 多快能取到新任务。高优先级队列配了过慢的轮询间隔实际响应会跟不上production: workers: - queues: critical threads: 5 polling_interval: 0.1 # Poll every 100ms — fast response - queues: low threads: 2 polling_interval: 10 # Poll every 10s — fine for low-priority work重试需要显式声明在 Solid Queue 中重试必须用 Active Job 的retry_on显式配置未配置retry_on的失败任务会直接进入失败执行不会重试class ExternalApiJob ApplicationJob retry_on Net::TimeoutError, wait: :exponentially_longer, attempts: 5 retry_on ActiveRecord::Deadlocked, wait: 2.seconds, attempts: 3 def perform # ... end end也可以在ApplicationJob中全局设置默认重试策略。另外注意并发控制limits_concurrency的任务不兼容perform_all_later批量入队。可选分支在开发环境启用 Solid Queue开发环境默认使用async适配器任务保留在内存中进程崩溃或机器重启后未完成任务全部丢失对非关键任务可以接受。如果要在开发环境也使用数据库持久化按与生产相同的方式配置# config/environments/development.rb config.active_job.queue_adapter :solid_queue config.solid_queue.connects_to { database: { writing: :queue } }并在config/database.yml的开发段加入queue连接# config/database.yml development: primary: : *default database: storage/development.sqlite3 queue: : *default database: storage/development_queue.sqlite3 migrations_paths: db/queue_migrate可选分支Kamal 部署中让 Puma 托管队列进程如果应用通过 Kamal 部署官方指南的做法是让 Puma 自动拉起和停止 Solid Queue 进程而不是单独部署处理机。在config/deploy.yml的 environment 中加入# config/deploy.yml clear: # Run the Solid Queue Supervisor inside the web servers Puma process to do jobs. # When you start using multiple servers, you should split out job processing to a dedicated machine. SOLID_QUEUE_IN_PUMA: true # Set number of processes dedicated to Solid Queue (default: 1) # JOB_CONCURRENCY: 3应用模板的config/puma.rb中对应一行插件配置# Run the Solid Queue supervisor inside of Puma for single-server deployments. plugin :solid_queue if ![ , false, 0 ].include?(ENV[SOLID_QUEUE_IN_PUMA].to_s.downcase)JOB_CONCURRENCY控制 Solid Queue 的进程数默认 1与queue.yml中processes的取值对应。注意文档中的限制当开始使用多台服务器时应把任务处理拆分到专用机器上。启用后的行为与结果判断按以上步骤完成后可以对照以下由文档给出的行为判断是否生效bin/rails db:prepare之后db/queue_schema.rb中出现solid_queue_jobs等表bin/jobs start启动 Supervisor由其按config/queue.ymlfork 并管理 workers 与 dispatchers生产环境中通过 Action Mailer 的deliver_later发出的邮件进入 Active Job 后台发送发送失败会自动重试且任务在重启期间保存在数据库里不丢失。进一步的能力周期性任务config/recurring.yml、enqueue_after_transaction_commit的事务一致性配置、并发控制的:group分组等见 Active Job 基础指南 中的对应章节config.active_job.queue_adapter的完整说明见 Rails 配置指南。【免费下载链接】railsRuby on Rails项目地址: https://gitcode.com/GitHub_Trending/rai/rails创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考