rhebok 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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