uWSGI 上的 Redmine(RoR rack 应用程序)在使用多个进程运行时会忘记会话

uWSGI 上的 Redmine(RoR rack 应用程序)在使用多个进程运行时会忘记会话

当我登录 redmine 时,它​​会忘记我在第一次点击任何链接后或登录重定向后立即登录。在我刷新页面几次后,我仍然在某些刷新中登录。

注意:没有登录错误。_redmine_session cookie 存在。

这让我想起了这样的情况:负载均衡器后面有多个节点,它们不共享相同的会话存储,所以我将 uWSGI 进程的数量减少到 1,然后瞧 - 它可以按预期工作。

这很奇怪,因为据称 redmine 现在将其会话存储在 cookie 中,因此根本不使用共享存储。

出于性能原因,我希望有更多进程。我只是好奇发生了什么。我是部署 ruby​​ 应用程序的新手(我根本不使用 ruby​​,所以我还不了解整个生态系统)。

我在用着:

  • CentOS 6.3
  • redmine 2.2.3
  • ruby 1.8.7
  • uWSGI 1.4.8 带有静态链接的 rack 插件

我的 redmine 的 uWSGI .ini 文件:(请注意,只有当进程 > 1 时才会出现问题)

[uwsgi]
socket = 127.0.0.1:3032
master = true
processes = 1
post-buffering = 4096
env = RAILS_ENV=production
logto = /var/log/uwsgi/redmine.log
uid = dsh
gid = nginx
rack = /home/dsh/redmine/config.ru

答案1

如果你正在使用 PostgreSQL,请尝试设置

  • lazy = true在 uWSGI 配置中
  • 和/或prepared_statements: false在 database.yml 中。

就我而言,用户表的查询随机失败PG::Error: ERROR: prepared statement "a1" already exists,并返回到匿名用户。

似乎被避开了prepared_statements: false

http://edgeguides.rubyonrails.org/configuring.html#configuring-a-database

但有时还是会message type 0x54 arrived from server while idle出错,Redmine 停止响应。怀疑所有 Worker 共享同一个数据库连接。

http://www.ruby-forum.com/topic/127814

lazy = true通过在工作进程而不是主进程中加载​​应用程序解决了这个问题。 prepared_statements: false没有必要。

uWSGI 会尽可能地尝试(滥用)使用 fork() 调用的“写时复制”语义。默认情况下,它会在加载应用程序后进行分叉,以尽可能多地共享内存。如果出于某种原因不希望出现此行为,请使用 lazy 选项。这将指示 uWSGI 在每个 worker 的 fork() 之后加载应用程序。惰性模式改变了优雅重新加载的工作方式:不是重新加载整个实例,而是逐个重新加载每个 worker。如果您想要“惰性应用程序加载”,但又想保持标准的 uWSGI 重新加载行为,那么从 1.3 开始,您可以使用 lazy-apps 选项。

(摘自 uWSGI 文档的“需要了解的事情(最佳实践和“问题”)”)

希望这可以帮助。

相关内容