ruby - 使用 Sinatra 模块化样式为每个实例而不是每个请求创建一个变量

标签 ruby heroku redis sinatra connection-pooling

我有一个 Sinatra 应用程序,以模块化风格编写,在 Heroku 上运行。它使用 Redis,我的 Redis 连接数量有限 (10)。我发现它经常会抛出错误,提示它用完了 Redis 连接。所以我开始使用 connection_pool希望能解决问题;单个 Redis 连接池,应用程序每次都会选择其中一个,而不是尝试在每个请求上创建一个新连接。

但我仍然遇到同样的问题。我可以在单个查询上执行大量 Redis 查询而不会产生任何提示。但是,如果我重新加载一个测试页面,它只执行一些 Redis 查询,并且相当快地连续多次,我会再次收到“Redis::CommandError - ERR max number of clients reached”错误。

所以我假设,它可能会在每个请求上创建一个新的 connection_pool 实例……我不知道。但它并不像我期望的那样“汇集”。

我有这样的东西:

# myapp.rb
$LOAD_PATH.unshift(File.dirname(__FILE__))
$stdout.sync = true

require 'thin'
require 'myapp/frontend'

MyApp::Frontend.run!

还有 Sinatra 应用程序:

# myapp/frontend.rb
require 'sinatra/base'
require 'redis'
require 'connection_pool'
require 'uuid'

module MyApp
  class Frontend < Sinatra::Base

    helpers do
      def redis_pool
        @redis_pool ||= ConnectionPool.new(:size => 8, :timeout => 5) do
          redis_uri = URI.parse(ENV['REDISCLOUD_URL'])
          client = ::Redis.new(:host => redis_uri.host,
                               :port => redis_uri.port,
                               :password => redis_uri.password)
        end
      end
    end

    get '/tester/'
      redis_pool.with do |r|
        id = UUID.generate
        r.hset(:user, id, "Some data")
        r.hget(:user, id)
        r.hdel(:user, id)
      end
      p "DONE"
    end
  end
end

Procfile 看起来像:

web: ruby myapp.rb

有什么想法吗?当前站点的流量非常低,所以这应该是可能的。

最佳答案

每次处理/tester/的get请求都会创建一个新的@redis_pool实例,因为调用了辅助方法redis_pool每次。

您只能使用 sinatra 的设置助手来初始化一个 redis 连接:

config do
  redis_uri = URI.parse(ENV['REDISCLOUD_URL'])
  set :redis, Redis.new(:host => redis_uri.host,
                        :port => redis_uri.port,
                        :password => redis_uri.password)
end

现在应用程序的每个实例都有一个 redis 连接,该连接对所有请求都有效。像这样访问设置

get '/tester/'
  id = UUID.generate
  settings.redis.hset(:user, id, "some data")
  settings.redis.hget(:user, id)
  settings.redis.hdel(:user, id)
  p "DONE"
end

关于ruby - 使用 Sinatra 模块化样式为每个实例而不是每个请求创建一个变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21098623/

相关文章:

javascript - 在 heroku 上使用 socket.io 的 Nodejs

configuration - 如何让 redis-server 在重新启动时刷新所有数据?

mongodb - 使用 Mongo Cache 替代 Redis

ruby-on-rails - 当我们需要使用 bundle :lock and unlock on rails3

ruby-on-rails - Rails 现在可以使用 Ruby 1.9 了吗?

ruby-on-rails - 一种更快/更具可扩展性的 Twitter OAuth Dance in Rails 方法?

node.js - Node 为 : hgetall returns true, 的 Redis 但回调返回 null

ruby - 使 rvm 切换到 osx 上的系统 ruby

ruby-on-rails - 为什么 Rails 试图预编译 .css 文件

ruby-on-rails - CloudFlare SSL + Heroku 自定义域不起作用