मैं रूबी (1.9.3-पी 0) में समेकन के साथ खेल रहा हूं, और एक बहुत ही सरल, I/O-भारी प्रॉक्सी कार्य बनाया है। सबसे पहले, मैंने गैर-अवरुद्ध दृष्टिकोण की कोशिश की:रूबी समरूपता: गैर-अवरुद्ध I/O बनाम धागे
require 'rack'
require 'rack/fiber_pool'
require 'em-http'
require 'em-synchrony'
require 'em-synchrony/em-http'
proxy = lambda {|*|
result = EM::Synchrony.sync EventMachine::HttpRequest.new('http://google.com').get
[200, {}, [result.response]]
}
use Rack::FiberPool, :size => 1000
run proxy
=begin
$ thin -p 3000 -e production -R rack-synchrony.ru start
>> Thin web server (v1.3.1 codename Triple Espresso)
$ ab -c100 -n100 http://localhost:3000/
Concurrency Level: 100
Time taken for tests: 5.602 seconds
HTML transferred: 21900 bytes
Requests per second: 17.85 [#/sec] (mean)
Time per request: 5602.174 [ms] (mean)
=end
हम्म, मैंने सोचा कि मुझे कुछ गलत करना होगा। एक कार्य के लिए 5.6 का औसत अनुरोध समय जहां हम अधिकतर I/O की प्रतीक्षा कर रहे हैं? मैंने एक और कोशिश की:
require 'sinatra'
require 'sinatra/synchrony'
require 'em-synchrony/em-http'
get '/' do
EM::HttpRequest.new("http://google.com").get.response
end
=begin
$ ruby sinatra-synchrony.rb -p 3000 -e production
== Sinatra/1.3.1 has taken the stage on 3000 for production with backup from Thin
>> Thin web server (v1.3.1 codename Triple Espresso)
$ ab -c100 -n100 http://localhost:3000/
Concurrency Level: 100
Time taken for tests: 5.476 seconds
HTML transferred: 21900 bytes
Requests per second: 18.26 [#/sec] (mean)
Time per request: 5475.756 [ms] (mean)
=end
हम्म, थोड़ा बेहतर, लेकिन मैं सफलता नहीं कहूंगा। आखिरकार, मैंने थ्रेडेड कार्यान्वयन की कोशिश की:
require 'rack'
require 'excon'
proxy = lambda {|*|
result = Excon.get('http://google.com')
[200, {}, [result.body]]
}
run proxy
=begin
$ thin -p 3000 -e production -R rack-threaded.ru --threaded --no-epoll start
>> Thin web server (v1.3.1 codename Triple Espresso)
$ ab -c100 -n100 http://localhost:3000/
Concurrency Level: 100
Time taken for tests: 2.014 seconds
HTML transferred: 21900 bytes
Requests per second: 49.65 [#/sec] (mean)
Time per request: 2014.005 [ms] (mean)
=end
वास्तव में, वास्तव में आश्चर्यजनक था। क्या मुझसे कोई चूक हो रही है? ईएम इतनी बुरी तरह प्रदर्शन क्यों कर रहा है? क्या मुझे कुछ ट्यूनिंग करने की ज़रूरत है? मैंने विभिन्न संयोजनों (यूनिकॉर्न, कई इंद्रधनुष विन्यास, इत्यादि) की कोशिश की, लेकिन उनमें से कोई भी सरल, पुराने I/O-blocking थ्रेडिंग के करीब भी नहीं आया।
विचार, टिप्पणियां और - जाहिर है - बेहतर कार्यान्वयन के लिए सुझावों का बहुत स्वागत है।
आप परीक्षण के लिए एक दूर के सर्वर का उपयोग नहीं करना चाहिए, विलंबता भिन्न हो सकते हैं। आपको कम फाइबर के साथ एसिंक टेस्ट फिर से प्रयास करना चाहिए, 20 फाइबर के साथ मुझे 300 एमएस/अनुरोध बनाम 1s/1000 सटीक एबी लाइन का उपयोग करके 1000 फाइबर के साथ अनुरोध मिलता है। आपका थ्रेडेड सर्वर डिफ़ॉल्ट इवेंटमैचिन थ्रेड पूल का उपयोग कर रहा है जो डिफ़ॉल्ट रूप से 20 धागे हैं। – Schmurfy
सुनिश्चित नहीं है, फाइबर पूल आकार को 20 तक सेट करना वास्तव में मेरे बॉक्स पर प्रदर्शन को कम करता है। – BSM
शायद 20 नहीं, लेकिन 1000 वास्तव में उच्च है, मैंने स्थानीय सर्वर के साथ परीक्षण किया ताकि प्रतिक्रिया समय वास्तव में कम हो। – Schmurfy