ruby - licencia - node js español
Concurrencia de Ruby: E/S sin bloqueo frente a subprocesos (1)
Vea cómo su "Tiempo por solicitud" es exactamente igual al "Tiempo total tomado para las pruebas". Este es un artefacto aritmético de informe debido a que su recuento de solicitudes (-n) es igual a su nivel de concurrencia (-c). El tiempo medio es el tiempo total * concurrencia / num-solicitudes. Entonces la media reportada cuando -n == -c será el tiempo de la solicitud más larga. Debe realizar sus ejecuciones ab con -n> -c por varios factores para obtener medidas razonables.
Parece que está utilizando una versión anterior de ab porque una versión relativamente actual informa resultados mucho más detallados de forma predeterminada. Ejecutándose directamente contra google, muestro un tiempo total similar == tiempo medio cuando -n == -c, y obtengo números más razonables cuando -n> -c. Realmente desea ver el req / seg, la media de todas las solicitudes simultáneas y el desglose final del nivel de servicio para obtener una mejor comprensión.
$ ab -c50 -n50 http://google.com/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking google.com (be patient).....done
Server Software: gws
Server Hostname: google.com
Server Port: 80
Document Path: /
Document Length: 219 bytes
Concurrency Level: 50
Time taken for tests: 0.023 seconds <<== note same as below
Complete requests: 50
Failed requests: 0
Write errors: 0
Non-2xx responses: 50
Total transferred: 27000 bytes
HTML transferred: 10950 bytes
Requests per second: 2220.05 [#/sec] (mean)
Time per request: 22.522 [ms] (mean) <<== note same as above
Time per request: 0.450 [ms] (mean, across all concurrent requests)
Transfer rate: 1170.73 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 2 0.6 3 3
Processing: 8 9 2.1 9 19
Waiting: 8 9 2.1 9 19
Total: 11 12 2.1 11 22
WARNING: The median and mean for the initial connection time are not within a normal deviation
These results are probably not that reliable.
Percentage of the requests served within a certain time (ms)
50% 11
66% 12
75% 12
80% 12
90% 12
95% 12
98% 22
99% 22
100% 22 (longest request) <<== note same as total and mean above
$ ab -c50 -n500 http://google.com/
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking google.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Finished 500 requests
Server Software: gws
Server Hostname: google.com
Server Port: 80
Document Path: /
Document Length: 219 bytes
Concurrency Level: 50
Time taken for tests: 0.110 seconds
Complete requests: 500
Failed requests: 0
Write errors: 0
Non-2xx responses: 500
Total transferred: 270000 bytes
HTML transferred: 109500 bytes
Requests per second: 4554.31 [#/sec] (mean)
Time per request: 10.979 [ms] (mean)
Time per request: 0.220 [ms] (mean, across all concurrent requests)
Transfer rate: 2401.69 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 1 0.7 1 3
Processing: 8 9 0.7 9 13
Waiting: 8 9 0.7 9 13
Total: 9 10 1.3 10 16
Percentage of the requests served within a certain time (ms)
50% 10
66% 11
75% 11
80% 12
90% 12
95% 13
98% 14
99% 15
100% 16 (longest request)
Estoy jugando con la concurrencia en Ruby (1.9.3-p0), y he creado una tarea proxy muy simple, con una gran cantidad de E / S. Primero, probé el enfoque sin bloqueo:
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
Hmm, pensé que debía estar haciendo algo mal. ¿Un tiempo de solicitud promedio de 5.6s para una tarea en la que estamos principalmente esperando E / S? Probé con otro:
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
Hmm, un poco mejor, pero no es lo que yo llamaría un éxito. Finalmente, probé una implementación enhebrada:
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
Eso fue realmente, realmente sorprendente. ¿Me estoy perdiendo de algo? ¿Por qué EM está funcionando tan mal aquí? ¿Hay algún ajuste que deba hacer? Intenté varias combinaciones (unicornio, varias configuraciones de arcoiris, etc.), pero ninguna de ellas se acercó siquiera al enhebrado simple y antiguo de bloqueo de E / S.
Ideas, comentarios y, obviamente, sugerencias para una mejor implementación son bienvenidos.