【问题标题】:Net::HTTP – Flush or CloseNet::HTTP – 刷新或关闭
【发布时间】:2016-12-06 22:26:53
【问题描述】:

我为支付 API 编写了一个消费者。我的代码只是发出一个 POST 请求并从 API 获得响应。我已经用 Net::HTTP 实现了,这里是相关的代码行:

http = Net::HTTP.new(uri.host, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(params)
response = http.request(request)

这已经工作了多年,但是,最近当 API 处于压力之下时,一些请求已经超时。 API 维护者提出了这样的解释:

我们在刷新 HTTP 响应后将数据同步传递给 RabbitMQ。显然,一些 HTTP 库在程序继续在消费者端之前等待连接关闭,我们认为这正在发生。请重新配置您的消费者不要等待关闭,而是在刷新响应后立即继续。

我不确定 Net::HTTP 是如何实现的,以及它是否真的在刷新响应时等待关闭。文档没有说任何关于它的信息,也没有设置来控制任何这些。更糟糕的是,我真的不知道如何模拟这个。

非常欢迎任何想法!

【问题讨论】:

    标签: ruby net-http ruby-2.3


    【解决方案1】:

    我想下面的实验(使用 Ruby 2.3)应该会给出答案,我把它贴在这里以防其他人将来偶然发现这个问题。

    server.rb:

    require 'socket'
    
    server = TCPServer.new('localhost', 2345)
    loop do
      socket = server.accept
      request = socket.gets
      STDERR.puts request
      response = "Hello World at #{Time.now}!\n"
      socket.print "HTTP/1.1 200 OK\r\n" +
                   "Content-Type: text/plain\r\n" +
                   "Content-Length: #{response.bytesize}\r\n" +
                   "Connection: close\r\n"
      socket.print "\r\n"
      socket.print response
      socket.flush
      sleep 10
      socket.close
    end
    

    client.rb:

    require 'net/http'
    
    http = Net::HTTP.new('localhost', 2345)
    request = Net::HTTP::Post.new('/')
    response = http.request(request)
    puts response.body
    

    运行服务器,客户端将发送一个请求并退出。它会立即执行此操作,因此刷新足以让客户端代码继续。在服务器等待的 10 秒内重新启动客户端,导致客户端挂起,直到 10 秒完全过去,然后打印 Hello World 并再次立即退出。

    换句话说:这样一个简单的Net::HTTP 客户端不会等待连接关闭,而是在服务器刷新后继续执行它的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 2017-08-12
      • 1970-01-01
      • 2013-04-05
      • 2011-01-07
      • 1970-01-01
      相关资源
      最近更新 更多