当服务器返回503时,为什么Net :: HTTP返回500?

时间:2019-10-03 20:41:02

标签: ruby-on-rails http-error net-http http-status-code-503

(此问题代替了this one,希望能提供更好的信息。)

我有三台服务器,分别称为Alice,Charlie和Harry(Harry是服务器的实际昵称,以免混淆自己)。他们彼此交谈以执行非常复杂的身份验证流程:

  • 客户通过爱丽丝向哈利执行三个请求。
  • 在第三个,哈利打电话给查理。
  • 查理在交通繁忙时很容易超时。如果是这样,Harry向Alice返回带有503标头的Retry-After
  • 哈里 返回一个503,我已经在自己的日志中确认了这一点。
  • 爱丽丝没有收到503,而是500,并且没有标题。
  • 爱丽丝的其他客户(我无法控制)将500与其他错误相同,这是我最终要解决的问题。

一些额外的信息,例如我已经确定的内容:

  • 爱丽丝使用RestClient代理给哈利的电话,后者在幕后使用Net::HTTP
  • 直接使用Net::HTTP可获得相同的结果。
  • 这不是特定于环境的;我在生产和开发中都遇到了这个问题。
  • 我一直在尝试使用Postman模拟Alice,但是还没有运气。查理的交通目前比较安静,我无法强迫或模拟超时,到目前为止,我只得到哈利200的成功回应。
  • 修复Charlie的超时显然是理想的,但我也不控制Charlie的硬件。

关于爱丽丝,我是否可以更改某些内容,以便它可以正确检测到哈利的503

或者,关于Harry的事情是否有可能在将其退回并记录后将其503更改为500

如果可能的话,这是爱丽丝(Alice)的第三个电话的代码,但是对我来说丝毫没有变化;我一直在想RestClientNet::HTTP是否具有我不知道的某些配置。

http_verb = :post
args = [ # actually constructed differently, but this is a reasonable mock up
  'https://api.harry/path?sso_token=token',
  '',
  {
    'content_type' => 'application/json',
    'accept' => '*/*',
    # some other app-specific headers
  }
]

RestClient.send(http_verb, *args) do |response, request, result, &block|
  # `result` is present and has a 500 code at the start of this block if Harry returns a 503.
  @status_code = result.present? ? result.code : :internal_server_error
  cors.merge!( response.headers.slice(:access_control_allow_origin, :access_control_request_method) )
  @body = response.body
end

1 个答案:

答案 0 :(得分:0)

结果证明,这比任何人想象的都更简单,更明显。

在负责返回503的中间件中引发了 separate 错误。与其他任何异常一样,它被渲染为500

引起此问题的原因是,该行应该告诉客户端等待五秒钟,然后重试:

response.headers['Retry-After'] = 5

...某个中间件组件抱怨undefined method 'each' on 5:Fixnum,并且在我们将5更改为字符串时开始工作。