2018-9-3 记录一次 Ruby on Rails [测试环境]和[生产环境]缓存干扰问题
应该是 memcached 造成的?
刚解决完这个问题。趁着记忆还新鲜赶紧写一下。
这篇文讲什么?
讲 Ruby on Rails 可能碰到的一个奇怪错误。
这个错误是在一台服务器上跑两个 puma,一个生产环境,一个测试环境导致的。
这篇文对谁有用?
Ruby on Rails 程序员
版本
Ruby on Rails 5.2.0
正文开始 ⬇️
具体问题描述
Ubuntu 16.04 服务器上跑了2个 Puma,
一个是 test environment,一个是 production environment。
在 test 环境里 修改某用户的用户名
。
比如如下示例代码,修改了用户id 1 的用户名变成 '3'
u = User.find(1)
u.username = '3'
u.save
会导致生产环境里,用户 id 的用户名显示 3。
看到这里,你可能会想:
是不是 database.yml 里的测试环境 test 和生产环境 production 数据库写了同一个名字,所以变成了操作同一个数据库?
并没有。以下是我的 database.yml
重点:测试和生产环境用的不同数据库
default: &default
adapter: postgresql
pool: 64
timeout: 5000
encoding: utf-8
port: 5432
production:
<<: *default
database: homeland
development:
<<: *default
database: homeland-dev
test:
<<: *default
database: homeland-test
临时解决方法
进入生产环境的 rails console。
运行:
Rails.cache.clear
永久解决方案
修改2个文件:
-
config/enviroments/test.rb
config.cache_store = :memory_store, { size: 64.megabytes } -
config/memcached.yml
原先只有 default 有 namespace,现在4个都加上了
如 namespace: rb-dev
defaults: &defaults
host: 127.0.0.1:11211
namespace: rb-1
compress: true
development:
<<: *defaults
namespace: rb-dev
test:
<<: *defaults
namespace: rb-test
production:
<<: *defaults
namespace: rb-production
重点:让两个环境下的缓存不要串了。这样测试环境下就不会影响到生产环境。
实测:在测试环境下修改 id 为 14 的用户名。生产环境下没有受到影响。
备注
我在这个问题上耗费了大概4-8个小时。不值。发这个文章出来是希望节省其他程序员的时间。
一个花时间的大块是当初出问题的时候,看数据库发现数据本身是没有问题的。只是返回的结果不对。
花了一点时间才找到 Rails.cache.clear 这个临时方法。
第二个花时间的大块是找永久解决方案的,先读一遍 Rails 本身的缓存策略
https://guides.rubyonrails.org/caching_with_rails.html
还有读十来篇网上和 Rails 缓存相关的文章。
最后猜测是 config.cache_store
的问题。
因为这个问题的本质就是缓存串了。两个环境的缓存都在一个地方,所以覆盖了。
然后再看现在的配置是什么情况。再改。
我其实没办法本地完美复现这个 test 和 production 环境下的缓存干扰问题。
我又没有那个心情和时间去纠结一定要完美复现这个问题。
所以以上的方法在我测的时候是没问题的。实际是否完美解决办法不清楚。
先观察一阵子。有情况再更新。