sukria
(Alexis Sukrieh)
1
我运营着一个 Discourse 站点,首先我想说,我非常喜爱这款软件。感谢整个团队出色的工作,这真是一个强大的工具。
在升级到 2.5.0 后,我遇到了大麻烦。以下是问题总结和我的临时解决方案。希望这能促使未来版本提供更完善的修复。
我们数据库中的一些主题包含损坏的上传文件。我们曾使用“S3 上传”功能,但不小心删除了存储桶。是的,这确实是个非常愚蠢的操作,但我们确实这么做了!结果导致所有主题中的图片都丢失了。
除了丢失大量图片外,其他一切正常:Discourse 显示了指向不存在图片的损坏链接,但系统本身运行良好。
然而,当我们尝试升级到 2.5.0 时,系统彻底崩溃:所有已登录用户都收到 500 错误,而匿名访客却能正常访问网站。
经过调查,我发现 Discourse 因“文件不存在”错误而崩溃。它似乎正在尝试下载这些文件。我被迫在 /var/www/discourse/app/models/upload.rb 中将 local? 方法强制设为 true,这才解决了问题,但我对未来的升级有些担忧……
这显然是一个新问题,因为之前的升级并未出现此类故障。
顺便问一下,有没有什么方法可以清除我们主题中所有失效的图片链接?
谢谢。
我们遇到了相反的行为:已登录用户正常,未登录用户无法连接并出现 500 错误。
Falco
(Falco)
3
您能分享一个此类错误的完整堆栈跟踪吗?
请检查您的 /logs 页面。
sam
(Sam Saffron)
4
这听起来非常像是一个不兼容的插件。你正在运行哪些非官方插件?你试过在不使用它们的情况下重新构建吗?
sukria
(Alexis Sukrieh)
5
当然,在我的 log/production.log 中,出现了以下异常(当 Discourse 访问空的 S3 存储桶时(我重新创建了该存储桶,希望这能解决问题))。
2020-05-16 14:29:06 +0000 来自 86.246.127.170 的 GET “/” 请求已启动
正在以 HTML 格式处理 ListController#latest
创建作用域 :open。覆盖现有方法 Poll.open。
3638 毫秒内完成 500 内部服务器错误(ActiveRecord: 0.0 毫秒 | 分配: 135090)
NoMethodError(nil:NilClass 没有定义方法 path') /var/www/discourse/lib/file_store/base_store.rb:150:in cache_file’
希望这能有所帮助。
sukria
(Alexis Sukrieh)
6
谢谢,可能就是这个原因。我确实安装了两款插件:Discourse Adsense 和 discourse-chat-integration,我会尝试在不加载它们的情况下重建。
sukria
(Alexis Sukrieh)
7
我可以确认,这并非由插件引起:我在全新安装并恢复最新备份、且未安装任何插件(除 docker_manager 外)的环境中复现了相同的错误。
我收到的第一个堆栈跟踪如下:
完成 500 内部服务器错误,耗时 4169 毫秒(ActiveRecord: 0.0 毫秒 | 内存分配:72058)
NoMethodError(nil:NilClass 未定义方法 path') /var/www/discourse/lib/file_store/base_store.rb:150:in cache_file’
我通过以下方式进行了修复:
def cache_file(file, filename)
path = get_cache_path_for(filename)
dir = File.dirname(path)
FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
if file.nil?
return
end
FileUtils.cp(file.path, path)
但这导致了第二个错误(即我在初始帖子中提到的错误):
2020-05-18 07:37:40 +0000,来自 86.246.127.170 的 GET 请求“/”已启动
正在处理 CategoriesController#index,格式为 HTML
完成 500 内部服务器错误,耗时 4342 毫秒(ActiveRecord: 0.0 毫秒 | 内存分配:60478)
NoMethodError(nil:NilClass 未定义方法 path') /var/www/discourse/app/models/upload.rb:193:in fix_dimensions!’
我通过将 local? 强制设为 true 来修复此问题:
def local?
return true
!(url =~ /^(https?:)?///)
end
sam
(Sam Saffron)
8
您是否曾在某个时间点将文件移动至或从 S3 移出?
sukria
(Alexis Sukrieh)
9
是的,我确实这样做了。但后来存储桶被删除了。于是我又切换回了本地存储(显然,之前话题中的图片链接都已失效)。
sam
(Sam Saffron)
10
我认为这里最好的办法是直接从数据库中彻底删除所有有问题的上传记录。
如果没有上传数据,就不要保留它。
sukria
(Alexis Sukrieh)
11
是的,我同意,但我不太敢直接在数据库上手动执行这种大规模清理操作。有没有更“规范”的建议?还是说真的只能“手动”处理?
另外,我觉得 Discourse 的这种行为变化有点令人担忧。据我所知,这意味着如果某个地方出现死图片链接,应用就会崩溃。
以前并不是这样的。我建议在这种情况下应该让系统更加健壮。
david
(David Taylor)
13
是的,这看起来是同一个问题。@sukria,如果你更新到最新的测试通过版本,我已添加了一个修复方案,使处理损坏的上传更加稳健(不过,你仍应尝试清理损坏的上传引用)。
sukria
(Alexis Sukrieh)
15
谢谢 @david,我确认针对 tests-passed 的全新构建开箱即用。感谢!
关于如何妥善/简便地移除主题中的死链,有什么建议吗?