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

如何在Rails应用中实现可控的无限短轮询循环?

方案建议:Rails 原生实现 vs Node 独立进程

优先选择:Rails 内部实现独立后台轮询脚本

完全可以在现有 Rails 代码库内搞定,这是成熟的实践方式,无需额外引入 Node 技术栈,实现步骤也很简单:

1. 编写轮询脚本

在项目中创建 lib/scripts/api_poller.rb(目录不存在可自行新建),示例代码如下:

#!/usr/bin/env ruby

# 加载完整 Rails 环境,可直接调用模型、日志等组件
require_relative '../../config/environment'

# 基础配置参数
BASE_INTERVAL = 1       # 正常请求间隔(秒)
MAX_INTERVAL = 30       # 错误时最大重试间隔(秒)
current_interval = BASE_INTERVAL

loop do
  begin
    # 同步发起请求,确保当前请求完成后才进入下一轮循环
    response = HTTParty.get('https://你的外部API地址', timeout: 10)

    case response.code
    when 200
      # 请求成功,重置间隔为基础值
      current_interval = BASE_INTERVAL
      # 检查是否有新数据,有则触发业务逻辑
      if has_new_data?(response.body)
        ExternalDataSyncService.call(response.body) # 替换为你的业务处理逻辑
      end
    when 500..599
      # 服务器错误,采用指数退避延长间隔
      current_interval = [current_interval * 2, MAX_INTERVAL].min
      Rails.logger.warn("External API 5xx error, next poll in #{current_interval}s")
    else
      Rails.logger.warn("Unexpected API response code: #{response.code}")
    end
  rescue HTTParty::Error, Timeout::Error => e
    # 超时或网络错误,同样延长重试间隔
    current_interval = [current_interval * 2, MAX_INTERVAL].min
    Rails.logger.error("API request failed: #{e.message}, next poll in #{current_interval}s")
  end

  # 等待指定间隔后再发起下一次请求,避免并发请求
  sleep(current_interval)
end

# 自定义判断新数据的逻辑
def has_new_data?(api_response)
  latest_local = ExternalData.last&.updated_at
  api_updated_at = JSON.parse(api_response)['updated_at']
  api_updated_at > latest_local.to_s
end

2. 部署与进程守护

  • 给脚本添加可执行权限:chmod +x lib/scripts/api_poller.rb
  • 用工具管理进程,确保后台稳定运行:
    • 本地/测试环境:在 Procfile 中添加一行 poller: bundle exec ruby lib/scripts/api_poller.rb,通过 foreman start 启动
    • 生产环境:编写 systemd 服务配置,实现进程崩溃自动重启

3. 为什么不选 ActiveJob?

ActiveJob 更适合一次性任务或固定间隔的周期性任务,但你的场景需要:

  • 上一次请求处于 pending 状态时不触发下一轮(ActiveJob 的 cron 或可重复任务无法感知上一次任务的执行状态)
  • 根据错误动态调整轮询间隔(指数退避)
    用循环脚本可以直接实现这些需求,ActiveJob 反而需要额外加锁、手动管理间隔,徒增复杂度。

Node 方案的适用场景

如果你的团队对 Node 技术栈更熟悉,或者需要处理极高频率的请求(比如每秒10次以上),Node 的异步IO模型可能更高效,但需要额外维护一套独立代码库,还要处理与 Rails 服务器的通信(比如 HTTP 调用、Redis 发布订阅),整体复杂度更高。

总结

优先选择Rails 独立脚本方案:

  • 复用现有代码库,无需引入额外技术栈
  • 逻辑完全可控,轻松实现请求等待、动态间隔等需求
  • 与 Rails 应用统一运维,成本更低

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 03:01:03