7

私はかなり大きなRailsアプリを持っています。これは、別のサーバー上のmemcachedをキャッシュストアとして使用します。

問題は、本番環境でランダムにエラーが発生することです。これは、memcachedが誤ったオブジェクトを返していることを示しているようです。

例:

この例では、 Rails.cacheを使用してモデルをキャッシュするモデルcurrent_site上のメソッドにアクセスするヘルパーメソッドです。Site

ActionView::TemplateError in ListingsController#edit
undefined method `settings' for #<String:0xb565f8a0>

On line #12 of app/views/layouts/site.html.erb

    9:         <meta name="robots" content="noodp, all" />
    10:         <meta name="distribution" content="Global" />
    11: 
    12:         <% unless current_site.settings[:google_webmaster_verification_code].blank? %>
    13:         <meta name="verify-v1" content="<%= current_site.settings[:google_webmaster_verification_code] %>" />
    14:         <% end %>
    15: 

とは対照的に....

ActionView::TemplateError in ApplicationController#not_found
undefined method `settings' for #<Category:0xd5c6c34>

On line #12 of app/views/layouts/site.html.erb

    9:         <meta name="robots" content="noodp, all" />
    10:         <meta name="distribution" content="Global" />
    11: 
    12:         <% unless current_site.settings[:google_webmaster_verification_code].blank? %>
    13:         <meta name="verify-v1" content="<%= current_site.settings[:google_webmaster_verification_code] %>" />
    14:         <% end %>
    15: 

Site両方がモデルを返す必要があるとき!

奇妙な動作をするキャッシュの別の例:

ActionView::TemplateError in AccountsController#show
can't convert Category into String

On line #141 of app/views/layouts/site.html.erb

    138:                    <li<%=  class="first" if i == 0 %>><%= link_to top_level_category.title, top_level_category.path %></li><% end %>
    139:                </ul>
    140:            <% end %>
    141:            <% cache bottom_pages do %>
    142:                <ul><% Page.top_level.active.show_in_navigation.find(:all, :include => :slugs).each_with_index do |top_level_page, i| %>
    143:                    <li<%=  class="first" if i == 0 %>><%= link_to top_level_page.title, top_level_page.path %></li><% end %>
    144:                </ul>

誰かが以前にこのようなことに遭遇したことがありますか?誰もがこの再現不可能な問題を診断することを考えています!?memcachedクライアントgemを切り替えてみましたが、これは奇妙なバグかもしれないと思いましたが、効果はありませんでした。ありがとう。

4

5 に答える 5

10

これは、PassengerがMemcachedサーバーへの接続を共有していることが原因でした。http://www.modrails.com/documentation/Users%20guide.html#_example_1_memcached_connection_sharing_harmfulを確認してください。

修正は、Passenger'sRailsのスポーンをに変更することでしたconservative

于 2009-04-13T20:05:22.113 に答える
1

役立つかもしれないいくつかのこと:

  • インストルメンテーション/ロギングを追加しcurrent_siteて、何が返されるかを正確に確認します。
  • memcacheでキーをどのように指定していますか?誤って、2つの異なるオブジェクトの2つの異なる場所で同じキーを使用している可能性があります。
  • memcached-tool host:port dump > /tmp/keysmemcacheに実際に何があるかを確認するために使用します。
  • memcachedはファイアウォールの背後にあり、パブリックIPに公開されていませんよね?
于 2009-04-09T17:43:26.980 に答える
1

私もこの問題を抱えており、キャッシュプロバイダーによるアンマーシャル操作の前に、すべてのクラス/モデルにrequire_dependencyを追加することで解決しました。オプション:config.cache_classがtrueに設定されているため、実稼働環境ではこれは必要ないかもしれませんが、テストおよび開発ではfalseです。

実際、Memcache(私が使用しているキャッシュプロバイダー)は、アンマーシャルを実行するための参照クラスを見つけられず、このエラーが発生します。

この投稿では、この問題に対するもう少し良い解決策があります:http: //kballcodes.com/2009/09/05/rails-memcached-a-better-solution-to-the-undefined-classmodule-problem/

よろしく!

于 2010-11-17T22:57:46.480 に答える
0

はい、私はこれを経験しました。私と一緒にいたのは、私がやっていてRails.cache.fetch(key)、鍵が空白だったからです。

Railsコンソールで次のように遊んでみました。

Rails.cache.read validkey  # Get back the proper data
Rails.cache.fetch('') { 'abc' } # Error in rails log: 'MemCacheError ():'
Rails.cache.read validkey # Get back nil
Rails.cache.read validkey # May get back proper data
于 2009-11-19T20:02:00.767 に答える
0

他の誰かが来た場合に備えて、これにコメントを追加します... kballcodes.comのURLは無効になります(ただし、archive.orgからアクセスできます)。そのブログ投稿のコメントで、誰かが、最初に「未定義のクラス/モジュール」エラーをスローした場合に、マーシャルに問題のオブジェクトのロードを試行させる方法を説明しました。以下にそのコードを含め、コードサンプルの下に元の作成者を参照しました。

これをRAILS_ROOT/config /initializers/フォルダーの初期化ファイルに追加します。

# 
# Marshal.load is a C-method built into Ruby; because it's so low-level, it
# bypasses the full classloading chain in Ruby, in particular the #const_missing
# hook that Rails uses to auto-load classes as they're referenced. This monkey
# patch catches the generated exceptions, parses the message to determine the
# offending constant name, loads the constant, and tries again.
#
# This solution is adapted from here:
# http://kballcodes.com/2009/09/05/rails-memcached-a-better-solution-to-the-undefined-classmodule-problem/
#
class <<Marshal
  def load_with_rails_classloader(*args)
    begin
      load_without_rails_classloader(*args)
    rescue ArgumentError, NameError => e
      if e.message =~ %r(undefined class/module)
        const = e.message.split(' ').last
        const.constantize
        retry
      else
        raise(e)
      end
    end
  end

  alias_method_chain :load, :rails_classloader
end

これに対するすべての功績は、このコードをパスティとして作成し、上記の死んだ記事にコメントしたMattBrownにあります

于 2012-02-14T02:47:48.217 に答える