bossan dentoo

24
Webサーバ・bossanを書いた話 @shitsyndrome / kubo39@github

Upload: kubo39

Post on 28-May-2015

982 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Bossan dentoo

Webサーバ・bossanを書いた話

@shitsyndrome /kubo39@github

Page 2: Bossan dentoo

bossan

Page 3: Bossan dentoo

話すこと

● bossan とはなにか● なんで作ったか● 基本構成● I/O戦略● セキュリティ● パフォーマンス

Page 4: Bossan dentoo

What's bossan?

● Ruby's rack web server● 高速● HTTP1.1サポート● Linux のみサポート

Page 5: Bossan dentoo

なんで作ったか

● Cの勉強● 就職活動の一環● 既存のrackサーバに不満

- パフォーマンス

- Eventmachineに依存しすぎ● ゴリゴリなにか書きたかった!

Page 6: Bossan dentoo

基本構成

● シングルプロセス、シングルスレッド● イベントドリブン(I/O多重化)● 機能は最小限に、パフォーマンス重視

Page 7: Bossan dentoo

I/O戦略

● readは全部読み込むまでread callback仕掛ける● writeはwritevを使用

- writevについては後述

- writeはまとめて書き出す

Page 8: Bossan dentoo

一般的なI/O特性

● read(2) / write(2)

fdが読み込み/書き込み完了するまで

他のfdをブロック

  => 「I/Oブロッキング」

Page 9: Bossan dentoo

ネットワーク x I/O

● ブロックすると、一人のレスポンス/リクエストが

終わるまで他は待たされる

  => 単位時間当たりの処理能力低下

● 一般的に1:NなサーバはマルチスレッドやIO多重化で実装

Page 10: Bossan dentoo

I/O多重化

● I/O可能になったfdを通知する仕組み

- 順番が入れ替わったりすることもある● 実装はいろいろ

select,poll,epoll(linux),kqueue(bsd),..

● Bossanはepollのみサポート

Page 11: Bossan dentoo

picoev

● イベントループを扱うためのライブラリ● 前述したepollを使いやすい形で提供

- 本来はkqueueやpollなどの下のレイヤーの差  異を隠蔽して使うためのもの

- 素のepoll扱うのはめんどい

Page 12: Bossan dentoo

Asynchronous I/O(おまけ)

● 非同期にI/Oを行う

fdのread/write自体が非同期● 通知時にはすでにread/writeは完了

- readの場合はバッファにデータが入ってる● 実装が複雑

- APIがクソ

- bossanでは使ってません

Page 13: Bossan dentoo

セキュリティ

● Max content length の設定

- クソでかいデータきたら困る

- 本体が16M越えたら413返す● 遅いリクエストはばっさりclose

- slowloris対策● Long Header DoS対策

- http-parserで対処

Page 14: Bossan dentoo

http-parser

● パース処理は重い → Cでかかれたもの使用● node.jsの作者のもの使用● コールバックスタイル

- バッファ切れる度に呼び出し● ヘッダを全部読み込む前にパース開始

- Long header DoS対策

Page 15: Bossan dentoo

パフォーマンス

● ほとんどCで実装

- Rubyは遅い

- いかにRubyのコード減らすか● 単純にCで書いてもそこまででない

- システムコール減らす : writev● ソケットオプション

- TCP_NODELAY, TCP_CORK● タイムキャッシュ

Page 16: Bossan dentoo

Rubyのコード減らす

● Rubyは遅い

- オブジェクトの生成コストが高い● 例:文字列

RubyのStringは生成の度にmemcpy()走る

- 可能な限りCの文字列使用

- staticな値で使いまわす

Page 17: Bossan dentoo

システムコール減らす

● システムコールは遅い

- OSのコンテキストスイッチが発生

- Linuxはマルチスレッドなので相互排他必要

● writev: 複数のバッファからの書き込みを同時に

- 自前でバッファ連結する手間省く

- カーネル内でatomicに連結

Page 18: Bossan dentoo

TCP_NODELAY / TCP_CORK

● TCPで小さいバッファで通信してると遅延が

起こりやすい● ソケットオプションで遅延させないようにできる

ー writevと併用することで効果を発揮● 参考URL

https://access.redhat.com/knowledge/docs/ja-JP/Red_Hat_Enterprise_MRG/2/html/Realtime_Reference_Guide/chap-Realtime_Reference_Guide-Sockets.html

Page 19: Bossan dentoo

タイムキャッシュ

● Dateヘッダ用に● HTTPの世界は秒オーダーでいい

- 時間を毎回引かない(gettimeofday発生)

- 1秒間はキャッシュした値を使いまわす● nginxのtime cacheを参考

Page 20: Bossan dentoo

ベンチマーク

● 条件(なるべく同一に)

Content-Type: text/plain

本文: “hello, world!”

ログ出力なし

apache bench : ab -c 25 -n 100000● nginxのみデフォルト設定

Page 21: Bossan dentoo

ベンチマーク

● 比較用サーバ

- thin : Ruby,シングルスレッド+イベントループ

- goliath : Ruby, シングルスレッド+イベントルー      プ+軽量スレッド(fiber)

- nginx: C, prefork+イベントループ

- node.js : js, シングルスレッド+イベントループ

Page 22: Bossan dentoo

ベンチマーク

Bossan(0.1.3) 18453.22 [#/sec]

Thin(1.5.0) 9460.58 [#/sec]

Goliath(1.0.1) 940.56 [#/sec]

Nginx(1.1.19) 20297.02 [#/sec]

Node.js(0.8.15) 10013.64 [#/sec]

Page 23: Bossan dentoo

コード

● https://github.com/kubo39/bossan

Page 24: Bossan dentoo

なにかあれば