Working with TCP Socketsを読みました。
これまでネットワークプログラミングの基礎みたいなことをあまり考えたことなかったので、結構勉強になりました。
次のようなことが勉強になりました。
- serverやclientが通信を行うときにどのようなlifecycleをたどるのか
- bind, listen, connectなど
- 通信を効率的に行うために、kernelがどのようなことをするか
- buffer層みたいなところで何をするか
- サイズ指定のreadを実行した時にkernelはどのような領域を確保するか
- 普通にnetcatとかlsofが便利とか
- Network Architecture Patternsの基本形とか
基本的なことを簡単に解説するという感じだったので、webサーバとかnginxのproxyとか普通に使ってるけど、仕組みちゃんとは分かってないなーという感じの人は勉強になりそうでした。
以下はメモ書きです。
メモ書き
server lifecycle
- create
- bind : portを取得
- listen : 接続待ちソケットとする、接続キューの最大長とかも指定する
- accept : コネクション受付開始、1つくるまでブロッキング
- close : コネクション閉じる、fdを閉じたり
netcatとかlsofとかちゃんと使ってなかったけど便利
client lifecycle
- create, bind, connect, close
client側はephemeral rangeのportを勝手に使ってくれるのでbind呼ぶ必要ない
Exchanging Data
Sockets Can Read
- closeかshutdown送ると結果的にEOFが送られる
Sockets Can Write
Buffering
- writeが終わった時点ではkernelに渡ったことだけしか保証されていない
- buffer層が良い感じにパフォーマンスを考慮して送ってくれている
- なので基本的にはwriteに食わせるデータ量をどのくらいにすればいいか(多いか少ないか)気にしなくてもいい
- すごい大きな量をbufferに入れるとメモリを圧迫するので気をつけるくらい
- readで長さ指定するとkernelがその分のメモリ割り当てをする。そのため大きすぎる長さをreadに指定するとリソースを無駄に食う
Socket Options
Non-blocking IO
- nonblock IOしたあと、読み込み書き込み可能になるまでを知るにはIO.selectを使う
Multiplexing Connections
- IO.selectはfile descriptorが読み書き可能であるかを教えてくれる
- select(2)は上限1024だけど、代わりにpollとかepollを使える
Framing Messages
- どうやってメッセージを構成するか
- 一行ごとにする
- 拡張するとHTTP的な感じ
- content lengthを先に送る方法
Timeouts
DNS Lookups
Urgent Data
- 緊急のデータは他のデータより先に読み出したりすることが出来る
- sendする方とrecvする方両方が緊急のデータに対応しておかないといけない
- 1byteしか送れない制限ある
Network Architecture Patterns
Serial
- 直列
- connect -> handle -> disconnect -> ...
- とにかくsimpleだけど、並列でないので遅い通信とかがあっただけでブロックする
Process per connection
- 1つアクセスが来たらforkして実行
- 非常にシンプルでわかりやすいが、プロセス数の上限を決められない
Thread per connection
- processよりリソースの点で軽量
Preforking
- 起動時に決められた数だけforkして、親はacceptせずに、子にacceptさせる
- 上限決められるし、load balancingとかをkernelに任せられる
- forkし過ぎるとメモリ周りで問題を抱える
Thread Pool
Evented (Reactor)
Hybrids
- とにかく様々なproductは色々な最適化はなされているけど、コアの部分はこれまで出てきたパターンの組み合わせで出来ている
- Serial, Process per connection, Thread per connection, Preforking, Thread Pool, Evented (Reactor)
- nginxはprefork、かつ子プロセスがEvented pattern