当前位置: 首页 > 面试题库 >

Rails Puma用尽Redis连接

姬英耀
2023-03-14
问题内容

我已经在SO上寻找了其他类似的问题,但是不能很好地将事情拼凑在一起。我有一个Rails应用程序(在Heroku上),该应用程序在多个进程和多个线程中都使用了Puma。我的应用程序还使用Redis作为辅助数据存储(除了SQL数据库),直接(通过connection_poolgem)查询Redis
。这是我的Puma配置文件:

workers Integer(ENV["WEB_CONCURRENCY"] || 4)
threads_count = Integer(ENV["MAX_THREADS"] || 5)
threads threads_count, threads_count

preload_app!

rackup DefaultRackup
port ENV["PORT"] || 3000
environment ENV["RACK_ENV"] || "development"

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  ActiveRecord::Base.establish_connection

  redis_connections_per_process = Integer(ENV["REDIS_CONNS_PER_PROCESS"] || 5)
  $redis = ConnectionPool.new(size: redis_connections_per_process) do
    Redis.new(url: ENV["REDIS_URL"] || "redis://localhost:6379/0")
  end
end

我的Redis实例的连接限制为20,尽管有4个工作进程中每个进程应该有5个连接(据我所知),但我发现自己经常超过该限制。

实际上,max number of clients reached当我设置REDIS_CONNS_PER_PROCESS为1
时,我什至会收到Redis错误。是on_worker_boot为每个线程而不是每个进程调用的吗?

我也尝试过使用单独的redis.rb初始化程序,即使在REDIS_CONNS_PER_PROCESS1
时也仍然会出现错误。这似乎很奇怪,因为如果我正确地进行数学运算,我应该可以将其设置为4(4个工作进程+ 1个主进程)
)*每个进程4个连接。(请注意,出于这个问题的目的,我忽略了部署过程中发生的错误,因为我假设Heroku在该过程中可能同时连接了新旧进程,即使我没有使用Preboot。)

我在哪里误解了这一切如何融合在一起?


问题答案:

经过进一步的阅读和测试之后,我最终将Redis连接池代码移到了单独的初始化程序中。不幸的是,这根本解决不了我的问题-
尽管对进程和连接号进行了很多修改,但max number of clients reached在我本应该解决之前,我仍然遇到了错误。

事实证明,答案是将Redis提供程序从Heroku Redis切换到Redis
Cloud。我不知道为什么的Heroku的Redis是不允许其通告的连接数,但在一番调查Redis的云实际上出现,让 更多
的连接比广告(或者至少限制连接,透明,不错误)没有任何问题的任何责任。哇。他们当然赢得了我的生意。



 类似资料:
  • 我们在应用程序中使用redis进行缓存。 我们的目标是在池大小耗尽或超过某个阈值时创建新的Redis连接,以便将空闲连接的数量保持在最小。通过这种方式,redis服务器资源被分配给真正需要它的应用服务器。 在我们的java应用程序中,我们使用的是spring的JedisConnectionFactory of spring数据redis 1.4.2,它在内部使用了Jedis 2.6.2和commo

  • 主要内容:Redis 连接,1.Auth 命令,2.Echo 命令,3.Ping 命令,4.Quit 命令,5.Select 命令Redis 连接 Redis 连接命令主要是用于连接 redis 服务。 1.Auth 命令 Redis Auth 命令用于检测给定的密码和配置文件中的密码是否相符。 密码匹配时返回 OK ,否则返回一个错误。 2.Echo 命令 Redis Echo 命令用于打印给定的字符串。 3.Ping 命令 Redis Ping 命令使用客户端向 Redis 服务器发送一个

  • 我在项目中使用ApacheTomcat JDBC连接池。我很困惑,因为在重负下,我一直看到以下错误: 我的期望是,使用池,新连接的请求将被保留在队列中,直到连接可用。相反,当池达到容量时,请求似乎会被拒绝。这种行为可以改变吗? 谢谢, 达尔 这是我的池配置:

  • 我想监控并定期记录有关Redis连接池使用情况的信息。 我通过spring-data-redis RedisTemboard对象使用Redis。 有办法进入游泳池吗?

  • 问题内容: 我是Redis的新手…我最近刚拿起Redisent来在PHP中使用Redis …并且我玩得很开心!但是,我注册了Redis服务,并一直在努力使用该服务… URI字符串如下: redis:// [用户名]:[pass] @ [服务器] .redistogo.com:[端口] / Redisent客户端只需输入主机名和端口…并且我没有地方输入用户名/密码…:-/我也一直在摆弄fsockop

  • 我有使用hikari池创建连接池的Spring启动应用程序。我们正在使用postgres sql用于db。当我以低qps命中系统时,请求需要大约200毫秒来执行。当部署一个pod并且qps为15时,事情保持良好状态。但是一旦我将qps增加到20,请求就开始需要大约10秒来处理,连接池变空(java.sql.SQLTransientConntion异常:菲尼克斯-连接不可用,请求在30183毫秒后超