rhebok 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 886e07e01529cc5371bbca869048f569ec23c2b1
4
- data.tar.gz: 9af6f543aa8af1c31d5a7844f061321a074460f0
3
+ metadata.gz: 94b3831b8be1282dcfa0b7342ca2dfe00c3fb2d3
4
+ data.tar.gz: 819ab7b0d91cf2a9f0981215f00680119011bb3a
5
5
  SHA512:
6
- metadata.gz: 0b9e5c8124a08ed80d565e886af090515613cf438a8d74595e7ef0b3f0f5b1b25aeba0c2aa58d7da3452727cf73b06466b740c619a8fc2b93b21064009e4363f
7
- data.tar.gz: fcecc2575e1fc790b8a04670c4a1b28d3f8e372a6892acde185f59a06ac17be00917b9caab1467988f54ed3d6701350b5dff7cb75687e8f60ef1a2e69a6d81bd
6
+ metadata.gz: 097bc9a4d73e9ae73c15ceb1d5ceabccbabba2e387b5e2e01ca54c7eba2df37b7c3b37add98965cb658e8254e722bebb76397dcb5cf352ace91153725d03a0b1
7
+ data.tar.gz: e5bce935a42a8bafd266dca86ad8ab65440d2a66cb20ab151db0ed61cb785e945fef76b9880c5001fd6d7c8ed4b8cb29c1a01d74d719bc45421db8d849b38933
data/Changes CHANGED
@@ -1,3 +1,7 @@
1
+ 0.2.2 2015-01-07T22:41:52Z
2
+
3
+ - support SO_REUSEPORT
4
+
1
5
  0.2.1 2014-12-27T01:26:47Z
2
6
 
3
7
  - fix segfault. header includes "\n"
data/README.md CHANGED
@@ -4,11 +4,11 @@ Rhebok is High Performance Rack Handler/Web Server. 2x performance when compared
4
4
 
5
5
  Rhebok supports following features.
6
6
 
7
- - ultra fast HTTP processing using picohttpparser
7
+ - ultra fast HTTP processing using [picohttpparser](https://github.com/h2o/picohttpparser)
8
8
  - uses accept4(2) if OS support
9
9
  - uses writev(2) for output responses
10
- - prefork and graceful shutdown using prefork_engine
11
- - hot deploy using start_server
10
+ - prefork and graceful shutdown using [prefork_engine](https://rubygems.org/gems/prefork_engine)
11
+ - hot deploy using [start_server](https://metacpan.org/release/Server-Starter) ([here](https://github.com/lestrrat/go-server-starter) is golang version by lestrrat-san)
12
12
  - only supports HTTP/1.0. But does not support Keepalive.
13
13
  - supports OobGC
14
14
 
@@ -18,7 +18,7 @@ This server is suitable for running HTTP application servers behind a reverse pr
18
18
 
19
19
  Add this line to your application's Gemfile:
20
20
 
21
- ```ruby
21
+ ```
22
22
  gem 'rhebok'
23
23
  ```
24
24
 
@@ -77,7 +77,11 @@ path to listen using unix socket
77
77
 
78
78
  ### BackLog
79
79
 
80
- specifies a listen backlog parameter
80
+ specifies a listen backlog parameter (default: 5)
81
+
82
+ ### ReusePort
83
+
84
+ enable SO_REUSEPORT for TCP socket
81
85
 
82
86
  ### MaxWorkers
83
87
 
@@ -145,6 +149,8 @@ Supported options in config file are below.
145
149
 
146
150
  ### backlog
147
151
 
152
+ ### reuseport
153
+
148
154
  ### max_workers
149
155
 
150
156
  ### timeout
@@ -185,6 +191,12 @@ proc object. This block will be called by a worker process after forking
185
191
 
186
192
  Rhebok and Unicorn "Hello World" Benchmark (behind nginx reverse proxy)
187
193
 
194
+ ![image](https://s3-ap-northeast-1.amazonaws.com/softwarearchives/rhebok_unicorn_bench.png)
195
+
196
+ *"nginx static file" represents req/sec when delivering 13 bytes static files from nginx*
197
+
198
+ Application code is [here](https://github.com/kazeburo/rhebok_bench_app).
199
+
188
200
  ruby version
189
201
 
190
202
  $ ruby -v
@@ -215,37 +227,49 @@ nginx.conf
215
227
  }
216
228
  }
217
229
 
218
- config.ru
219
-
220
- class HelloApp
221
- def call(env)
222
- [
223
- 200,
224
- { 'Content-Type' => 'text/html' },
225
- ['hello world ']
226
- ]
227
- end
228
- end
229
- run HelloApp.new
230
-
231
230
  ### Rhebok
232
231
 
233
232
  command to run
234
233
 
235
- $ start_server --path /path/to/app.sock -- rackup -s Rhebok \
236
- -O MaxWorkers=8 -O MaxRequestPerChild=0 -E production config.ru
234
+ $ start_server --backlog=16384 --path /dev/shm/app.sock -- \
235
+ bundle exec --keep-file-descriptors rackup -s Rhebok \
236
+ -O MaxWorkers=8 -O MaxRequestPerChild=0 -E production config.ru
237
+
238
+ #### Hello World/Rack Application
239
+
240
+ $ ./wrk -t 4 -c 500 -d 30 http://localhost/
241
+ Running 30s test @ http://localhost/
242
+ 4 threads and 500 connections
243
+ Thread Stats Avg Stdev Max +/- Stdev
244
+ Latency 1.74ms 661.27us 38.69ms 91.19%
245
+ Req/Sec 72.69k 9.42k 114.33k 79.43%
246
+ 8206118 requests in 30.00s, 1.34GB read
247
+ Requests/sec: 273544.70
248
+ Transfer/sec: 45.90MB
249
+
250
+ #### Sinatra
251
+
252
+ $ ./wrk -t 4 -c 500 -d 30 http://localhost/
253
+ Running 30s test @ http://localhost/
254
+ 4 threads and 500 connections
255
+ Thread Stats Avg Stdev Max +/- Stdev
256
+ Latency 16.39ms 418.08us 22.25ms 78.25%
257
+ Req/Sec 7.73k 230.81 8.38k 70.81%
258
+ 912104 requests in 30.00s, 273.09MB read
259
+ Requests/sec: 30404.28
260
+ Transfer/sec: 9.10MB
237
261
 
238
- result
262
+ #### Rails
239
263
 
240
264
  $ ./wrk -t 4 -c 500 -d 30 http://localhost/
241
265
  Running 30s test @ http://localhost/
242
266
  4 threads and 500 connections
243
267
  Thread Stats Avg Stdev Max +/- Stdev
244
- Latency 1.85ms 2.94ms 816.72ms 99.24%
245
- Req/Sec 70.14k 9.13k 110.33k 76.74%
246
- 7885663 requests in 30.00s, 1.29GB read
247
- Requests/sec: 262864.06
248
- Transfer/sec: 44.11MB
268
+ Latency 101.13ms 2.57ms 139.04ms 96.88%
269
+ Req/Sec 1.24k 27.11 1.29k 82.98%
270
+ 148169 requests in 30.00s, 178.18MB read
271
+ Requests/sec: 4938.93
272
+ Transfer/sec: 5.94MB
249
273
 
250
274
  ### Unicorn
251
275
 
@@ -258,24 +282,47 @@ unicorn.rb
258
282
 
259
283
  command to run
260
284
 
261
- $ unicorn -E production -c unicorn.rb config.ru
262
-
263
- result
285
+ $ bundle exec unicorn -c unicorn.rb -E production config.ru
286
+
287
+ #### Hello World/Rack Application
288
+
289
+ $ ./wrk -t 4 -c 500 -d 30 http://localhost/
290
+ Running 30s test @ http://localhost/
291
+ 4 threads and 500 connections
292
+ Thread Stats Avg Stdev Max +/- Stdev
293
+ Latency 3.50ms 518.60us 30.28ms 90.35%
294
+ Req/Sec 37.99k 4.10k 56.56k 72.14%
295
+ 4294095 requests in 30.00s, 786.07MB read
296
+ Requests/sec: 143140.20
297
+ Transfer/sec: 26.20MB
298
+
299
+ #### Sinatra
300
+
301
+ $ ./wrk -t 4 -c 500 -d 30 http://localhost/
302
+ Running 30s test @ http://localhost/
303
+ 4 threads and 500 connections
304
+ Thread Stats Avg Stdev Max +/- Stdev
305
+ Latency 19.31ms 1.09ms 65.92ms 89.94%
306
+ Req/Sec 6.55k 312.92 7.24k 73.41%
307
+ 775712 requests in 30.00s, 244.09MB read
308
+ Requests/sec: 25857.85
309
+ Transfer/sec: 8.14MB
310
+
311
+ #### Rails
264
312
 
265
313
  $ ./wrk -t 4 -c 500 -d 30 http://localhost/
266
314
  Running 30s test @ http://localhost/
267
315
  4 threads and 500 connections
268
316
  Thread Stats Avg Stdev Max +/- Stdev
269
- Latency 3.57ms 0.95ms 206.42ms 94.66%
270
- Req/Sec 35.62k 3.79k 56.69k 77.38%
271
- 4122935 requests in 30.00s, 754.74MB read
272
- Socket errors: connect 0, read 0, write 0, timeout 47
273
- Requests/sec: 137435.52
274
- Transfer/sec: 25.16MB
317
+ Latency 105.70ms 4.70ms 151.11ms 93.50%
318
+ Req/Sec 1.19k 44.16 1.25k 89.13%
319
+ 141846 requests in 30.00s, 172.74MB read
320
+ Requests/sec: 4728.11
321
+ Transfer/sec: 5.76MB
275
322
 
276
323
  ### Server Environment
277
324
 
278
- I used EC2 for benchmarking. Instance type if c3.8xlarge(32cores). A benchmark tool and web servers were executed at same hosts.
325
+ I used EC2 for benchmarking. Instance type if c3.8xlarge(32cores). A benchmark tool and web servers were executed at same hosts. Before benchmark, increase somaxconn and nfiles.
279
326
 
280
327
  ## See Also
281
328
 
@@ -36,9 +36,10 @@ module Rack
36
36
  :OobGC => false,
37
37
  :MaxGCPerRequest => 5,
38
38
  :MinGCPerRequest => nil,
39
- :BackLog => nil,
39
+ :BackLog => 5,
40
40
  :BeforeFork => nil,
41
41
  :AfterFork => nil,
42
+ :ReusePort => false,
42
43
  }
43
44
  NULLIO = StringIO.new("").set_encoding('BINARY')
44
45
 
@@ -59,6 +60,10 @@ module Rack
59
60
  if options[:OobGC].instance_of?(String)
60
61
  options[:OobGC] = options[:OobGC].match(/^(true|yes|1)$/i) ? true : false
61
62
  end
63
+ if options[:ReusePort].instance_of?(String)
64
+ options[:ReusePort] = options[:ReusePort].match(/^(true|yes|1)$/i) ? true : false
65
+ end
66
+
62
67
  @options = DEFAULT_OPTIONS.merge(options)
63
68
  if @options[:ConfigFile] != nil
64
69
  puts "loading from config_file:#{options[:ConfigFile]}"
@@ -80,7 +85,7 @@ module Rack
80
85
  else
81
86
  @options[:Port] = hostport
82
87
  end
83
- @server = TCPServer.for_fd(fd.to_i)
88
+ @server = Socket.for_fd(fd.to_i)
84
89
  @_is_tcp = true if !@server.local_address.unix?
85
90
  end
86
91
 
@@ -97,21 +102,26 @@ module Rack
97
102
  end
98
103
  puts "Rhebok starts Listening on :unix:#{@options[:Path]} Pid:#{$$}"
99
104
  oldmask = ::File.umask(0)
100
- @server = UNIXServer.open(@options[:Path])
105
+ @server = Socket.new(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
106
+ @server.bind(Addrinfo.unix(@options[:Path]))
101
107
  ::File.umask(oldmask)
102
108
  @_is_tcp = false
103
109
  @options[:Host] = "0.0.0.0"
104
110
  @options[:Port] = 0
105
111
  else
106
112
  puts "Rhebok starts Listening on #{@options[:Host]}:#{@options[:Port]} Pid:#{$$}"
107
- @server = TCPServer.open(@options[:Host], @options[:Port])
108
- @server.setsockopt(:SOCKET, :REUSEADDR, 1)
113
+ addrinfo = Addrinfo.tcp(@options[:Host], @options[:Port])
114
+ @server = Socket.new(defined?(Socket::AF_INET6) && addrinfo.afamily == Socket::AF_INET6 ?
115
+ Socket::AF_INET6 : Socket::AF_INET, Socket::SOCK_STREAM, 0)
116
+ @server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
117
+ if @options[:ReusePort]
118
+ @server.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1);
119
+ end
120
+ @server.bind(addrinfo)
109
121
  @_is_tcp = true
110
122
  end
111
- if @options[:BackLog] != nil
112
- @server.listen(@options[:BackLog].to_i)
113
- end
114
- end
123
+ @server.listen(@options[:BackLog].to_i)
124
+ end # @server == nil
115
125
 
116
126
  if RUBY_PLATFORM.match(/linux/) && @_is_tcp == true
117
127
  begin
@@ -119,6 +129,11 @@ module Rack
119
129
  @_using_defer_accept = true
120
130
  end
121
131
  end
132
+
133
+ if @server.respond_to?("autoclose=")
134
+ @server.autoclose = false
135
+ end
136
+
122
137
  end
123
138
 
124
139
  def run_worker(app)
@@ -64,6 +64,10 @@ class Rhebok
64
64
  @config[:AfterFork] = block
65
65
  end
66
66
 
67
+ def reuseport(&block)
68
+ @config[:ReusePort] = block
69
+ end
70
+
67
71
  def retrieve
68
72
  @config
69
73
  end
@@ -1,3 +1,3 @@
1
1
  class Rhebok
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhebok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Nagano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-26 00:00:00.000000000 Z
11
+ date: 2015-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  version: '0'
140
140
  requirements: []
141
141
  rubyforge_project:
142
- rubygems_version: 2.2.2
142
+ rubygems_version: 2.4.5
143
143
  signing_key:
144
144
  specification_version: 4
145
145
  summary: High Performance Preforked Rack Handler