错误 500 导致中间件内存 bloat/leak
Error 500 causes memory bloat/leak in middleware
我最近发现,当我在我的 Rails 应用程序中遇到错误代码 500 时,我会出现内存膨胀(我 运行 几个应用程序都遇到过相同的问题)。我发现使用 Scout 并且每次遇到 500 错误时(几乎)都可以看到内存泄漏模式。下面是最近的例子:
虽然在图表中似乎 exception_notification 没有太多内存分配,但是 "Middleware" 有。我唯一使用的中间件(据我所知)是异常通知(gem '[exception_notification][2]'
v. 4.2.1)所以我认为它一定是它,只是我的解释是错误的。
根据 Alexis 的评论进行编辑 - I 运行:
Rails.configuration.middleware.each do |m|
puts "use #{m.inspect}"
end;0
给出了以下关于中间件的输出:
use UTF8Cleaner::Middleware
use Rack::Sendfile
use ActionDispatch::Static
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x0055f8e1dd5a60>
use Rack::Timeout
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use Airbrake::Rack::Middleware
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use ExceptionNotification::Rack
use Rakismet::Middleware
use ScoutApm::Middleware
Airbrake 和 ScoutApm 是唯一与错误相关的。
我的 production.rb 包含以下信息:
config.middleware.use ExceptionNotification::Rack, :email => {
:email_prefix => "[MyApp.se Exception] ",
:sender_address => %{"Exception Notifier" <support@myapp.se>},
:exception_recipients => %w{me@myapp.se}
}
# Taken from mailer.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:enable_starttls_auto => false,
:return_response => true,
:raise_delivery_errors => true,
:address => 'smtp.myapp.se',
:port => 587,
:domain => "myapp.se",
:user_name => 'mailer@myapp.se',
:password => ENV['MAILER_PWD'],
:authentication => 'plain'
}
由于上周我一直在进行 Great Memory Bloat Hunt,我已经阅读了该邮件至少曾经引起关注,因此可能与此有关。
为什么会这样?我该如何解决它,或者至少进一步解决它?它可以是任何其他 Rails 默认中间件吗?
您可以使用 ExceptionMailer(whatever).deliver_later
将此任务推迟到后台作业,这将释放一些内存。
IMO 在 rails 中发送通知的更好方法是通过减速板 gem。您可以 运行 一个 errbit 的实例来节省一些钱或注册使用 airbrake 本身。这也有利于让您在接收通知的方式上有更大的灵活性,例如pushover,您将收到完整的堆栈跟踪,您可以根据这些跟踪采取行动,而不必搜索日志。
我最近发现,当我在我的 Rails 应用程序中遇到错误代码 500 时,我会出现内存膨胀(我 运行 几个应用程序都遇到过相同的问题)。我发现使用 Scout 并且每次遇到 500 错误时(几乎)都可以看到内存泄漏模式。下面是最近的例子:
虽然在图表中似乎 exception_notification 没有太多内存分配,但是 "Middleware" 有。我唯一使用的中间件(据我所知)是异常通知(gem '[exception_notification][2]'
v. 4.2.1)所以我认为它一定是它,只是我的解释是错误的。
根据 Alexis 的评论进行编辑 - I 运行:
Rails.configuration.middleware.each do |m|
puts "use #{m.inspect}"
end;0
给出了以下关于中间件的输出:
use UTF8Cleaner::Middleware
use Rack::Sendfile
use ActionDispatch::Static
use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x0055f8e1dd5a60>
use Rack::Timeout
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use Airbrake::Rack::Middleware
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use Rack::Head
use Rack::ConditionalGet
use Rack::ETag
use ExceptionNotification::Rack
use Rakismet::Middleware
use ScoutApm::Middleware
Airbrake 和 ScoutApm 是唯一与错误相关的。
我的 production.rb 包含以下信息:
config.middleware.use ExceptionNotification::Rack, :email => {
:email_prefix => "[MyApp.se Exception] ",
:sender_address => %{"Exception Notifier" <support@myapp.se>},
:exception_recipients => %w{me@myapp.se}
}
# Taken from mailer.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
:enable_starttls_auto => false,
:return_response => true,
:raise_delivery_errors => true,
:address => 'smtp.myapp.se',
:port => 587,
:domain => "myapp.se",
:user_name => 'mailer@myapp.se',
:password => ENV['MAILER_PWD'],
:authentication => 'plain'
}
由于上周我一直在进行 Great Memory Bloat Hunt,我已经阅读了该邮件至少曾经引起关注,因此可能与此有关。
为什么会这样?我该如何解决它,或者至少进一步解决它?它可以是任何其他 Rails 默认中间件吗?
您可以使用 ExceptionMailer(whatever).deliver_later
将此任务推迟到后台作业,这将释放一些内存。
IMO 在 rails 中发送通知的更好方法是通过减速板 gem。您可以 运行 一个 errbit 的实例来节省一些钱或注册使用 airbrake 本身。这也有利于让您在接收通知的方式上有更大的灵活性,例如pushover,您将收到完整的堆栈跟踪,您可以根据这些跟踪采取行动,而不必搜索日志。