由于从Redis切换到Heroku Redis,我们的Ruby on Rails应用程序中的Redis代码每天几次都会收到“OpenSSL::SSL::SSLError:SSL_read:sslv3 Alert bad record mac”错误。

有什么想法吗?

最佳答案

我在Ruby on Rails应用程序中通过重试这些错误来解决此问题。到目前为止,似乎已经摆脱了错误。我们过去每天只有大约5天的时间,而自从引入此解决方法以来,过去一天一直没有。

config/initializers/redis_heroku_error_handling.rb中:

# Hack to retry errors on Heroku Redis: https://stackoverflow.com/questions/50228454/why-am-i-getting-opensslsslsslerror-ssl-read-sslv3-alert-bad-record-mac

raise "Ensure this hack still works!" if Redis::VERSION != "3.3.5"

module RedisHerokuErrorHandlingHack
  def call(command)
    attempts_left = 3

    begin
      super
    rescue OpenSSL::SSL::SSLError => e
      raise unless e.message.include?("SSL_read: sslv3 alert bad record mac")

      attempts_left -= 1
      raise unless attempts_left > 0

      retry
    end
  end
end

class Redis::Client
  prepend RedisHerokuErrorHandlingHack
end

spec/initializers/redis_heroku_error_handling_spec.rb中:
require "rails_helper"

describe RedisHerokuErrorHandlingHack do
  it "retries 'bad record mac' errors" do
    exception = OpenSSL::SSL::SSLError.new("SSL_read: sslv3 alert bad record mac")
    fail_then_maybe_succeed(exception: exception, fail_times: 2)

    expect($redis.get("hello")).to eq("success response")
  end

  it "fails if a few retries didn't help" do
    exception = OpenSSL::SSL::SSLError.new("SSL_read: sslv3 alert bad record mac")
    fail_then_maybe_succeed(exception: exception, fail_times: 3)

    expect { $redis.get("hello") }.to raise_error(/bad record mac/)
  end

  it "does not retry other errors" do
    fail_then_maybe_succeed(exception: "Boom", fail_times: 2)

    expect { $redis.get("hello") }.to raise_error("Boom")
  end

  private

  def fail_then_maybe_succeed(exception:, fail_times:)
    attempt_count = 0

    allow_any_instance_of(Redis::Client).to receive(:process) do |*args|
      attempt_count += 1

      if attempt_count <= fail_times
        raise exception
      else
        "success response"
      end
    end
  end
end

关于heroku - 为什么我会间歇性地从Heroku Redis获得 “OpenSSL::SSL::SSLError: SSL_read: sslv3 alert bad record mac”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50228454/

10-12 13:09