bossan dentoo
TRANSCRIPT
![Page 1: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/1.jpg)
Webサーバ・bossanを書いた話
@shitsyndrome /kubo39@github
![Page 2: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/2.jpg)
bossan
![Page 3: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/3.jpg)
話すこと
● bossan とはなにか● なんで作ったか● 基本構成● I/O戦略● セキュリティ● パフォーマンス
![Page 4: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/4.jpg)
What's bossan?
● Ruby's rack web server● 高速● HTTP1.1サポート● Linux のみサポート
![Page 5: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/5.jpg)
なんで作ったか
● Cの勉強● 就職活動の一環● 既存のrackサーバに不満
- パフォーマンス
- Eventmachineに依存しすぎ● ゴリゴリなにか書きたかった!
![Page 6: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/6.jpg)
基本構成
● シングルプロセス、シングルスレッド● イベントドリブン(I/O多重化)● 機能は最小限に、パフォーマンス重視
![Page 7: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/7.jpg)
I/O戦略
● readは全部読み込むまでread callback仕掛ける● writeはwritevを使用
- writevについては後述
- writeはまとめて書き出す
![Page 8: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/8.jpg)
一般的なI/O特性
● read(2) / write(2)
fdが読み込み/書き込み完了するまで
他のfdをブロック
=> 「I/Oブロッキング」
![Page 9: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/9.jpg)
ネットワーク x I/O
● ブロックすると、一人のレスポンス/リクエストが
終わるまで他は待たされる
=> 単位時間当たりの処理能力低下
● 一般的に1:NなサーバはマルチスレッドやIO多重化で実装
![Page 10: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/10.jpg)
I/O多重化
● I/O可能になったfdを通知する仕組み
- 順番が入れ替わったりすることもある● 実装はいろいろ
select,poll,epoll(linux),kqueue(bsd),..
● Bossanはepollのみサポート
![Page 11: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/11.jpg)
picoev
● イベントループを扱うためのライブラリ● 前述したepollを使いやすい形で提供
- 本来はkqueueやpollなどの下のレイヤーの差 異を隠蔽して使うためのもの
- 素のepoll扱うのはめんどい
![Page 12: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/12.jpg)
Asynchronous I/O(おまけ)
● 非同期にI/Oを行う
fdのread/write自体が非同期● 通知時にはすでにread/writeは完了
- readの場合はバッファにデータが入ってる● 実装が複雑
- APIがクソ
- bossanでは使ってません
![Page 13: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/13.jpg)
セキュリティ
● Max content length の設定
- クソでかいデータきたら困る
- 本体が16M越えたら413返す● 遅いリクエストはばっさりclose
- slowloris対策● Long Header DoS対策
- http-parserで対処
![Page 14: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/14.jpg)
http-parser
● パース処理は重い → Cでかかれたもの使用● node.jsの作者のもの使用● コールバックスタイル
- バッファ切れる度に呼び出し● ヘッダを全部読み込む前にパース開始
- Long header DoS対策
![Page 15: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/15.jpg)
パフォーマンス
● ほとんどCで実装
- Rubyは遅い
- いかにRubyのコード減らすか● 単純にCで書いてもそこまででない
- システムコール減らす : writev● ソケットオプション
- TCP_NODELAY, TCP_CORK● タイムキャッシュ
![Page 16: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/16.jpg)
Rubyのコード減らす
● Rubyは遅い
- オブジェクトの生成コストが高い● 例:文字列
RubyのStringは生成の度にmemcpy()走る
- 可能な限りCの文字列使用
- staticな値で使いまわす
![Page 17: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/17.jpg)
システムコール減らす
● システムコールは遅い
- OSのコンテキストスイッチが発生
- Linuxはマルチスレッドなので相互排他必要
● writev: 複数のバッファからの書き込みを同時に
- 自前でバッファ連結する手間省く
- カーネル内でatomicに連結
![Page 18: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/18.jpg)
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](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/19.jpg)
タイムキャッシュ
● Dateヘッダ用に● HTTPの世界は秒オーダーでいい
- 時間を毎回引かない(gettimeofday発生)
- 1秒間はキャッシュした値を使いまわす● nginxのtime cacheを参考
![Page 20: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/20.jpg)
ベンチマーク
● 条件(なるべく同一に)
Content-Type: text/plain
本文: “hello, world!”
ログ出力なし
apache bench : ab -c 25 -n 100000● nginxのみデフォルト設定
![Page 21: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/21.jpg)
ベンチマーク
● 比較用サーバ
- thin : Ruby,シングルスレッド+イベントループ
- goliath : Ruby, シングルスレッド+イベントルー プ+軽量スレッド(fiber)
- nginx: C, prefork+イベントループ
- node.js : js, シングルスレッド+イベントループ
![Page 22: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/22.jpg)
ベンチマーク
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://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/23.jpg)
コード
● https://github.com/kubo39/bossan
![Page 24: Bossan dentoo](https://reader033.vdocuments.site/reader033/viewer/2022060111/556612e6d8b42a06318b4d73/html5/thumbnails/24.jpg)
なにかあれば