2016-08-01 28 views
1

我已經爲支付API編寫了一個消費者。我的代碼只是發出一個POST請求,並從API獲取響應。我實現了與網:: HTTP,這裏的代碼中的相關行: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是如何實現的,它是否真的在響應被刷新時等待關閉。文檔沒有提及任何內容,也沒有設置來控制這些。更糟糕的是,我真的不知道如何模擬這個。

任何想法都非常歡迎!

回答

0

我想下面的實驗(用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客戶端不會等待連接關閉,而是在服務器刷新後繼續執行它的代碼。