大量のコネクションをさばく サーバーの作り方 -...
Transcript of 大量のコネクションをさばく サーバーの作り方 -...
![Page 2: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/2.jpg)
2
未だに
「Haskellって実用的なの?」
と訊く人がいますが…
![Page 3: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/3.jpg)
3
Simon PEYTON JONES
によると
![Page 4: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/4.jpg)
4
Haskell は世界で最も素晴らしい命令型言語だ
![Page 5: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/5.jpg)
5
知ってました?
![Page 6: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/6.jpg)
6
素晴らしい命令型言語である証拠に
今日は
大量のコネクションをさばくサーバーを
Haskell で作るお話をします
![Page 7: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/7.jpg)
7
今日の目標
1万本のコネクションをさばく
![Page 8: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/8.jpg)
8
17行で作るエコーサーバー import Control.Concurrent import Network import System.IO
main :: IO () main = do sock <- listenOn (Service "2000") dispatch sock
dispatch :: Socket -> IO () dispatch sock = do (hdl,_,_) <- accept sock forkIO (server hdl) -- スレッドを作成 dispatch sock
server :: Handle -> IO () server hdl = do cs <- hGetLine hdl hPutStrLn hdl cs hClose hdl
![Page 9: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/9.jpg)
9
夢のようなスレッドプログラミングスレッドmain
スレッドスレッド TCPプロセス
![Page 10: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/10.jpg)
10
しかしkqueue() や epoll() の時代に
Haskell スレッドはselect()
で実装されている
![Page 11: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/11.jpg)
11
select() なのでコネクションを1024以上受け付けるとエラーになるスレッドmain
スレッドスレッドスレッド TCPスレッドプロセス
![Page 12: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/12.jpg)
12
なんとかしないと!
![Page 13: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/13.jpg)
13
大量のコネクションをさばくための3ステップ
1) コネクションの数を制限2) 黙り込んだ相手のコネクションを切る
3) プロセスを prefork する
![Page 14: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/14.jpg)
14
1) コネクションの数を制限 スレッド間の共有変数 Mvarスレッド
main
スレッドスレッドスレッドMvar
TCPプロセス main スレッドは子の生成時に Mvar の値を増やす 子スレッドは終了時に Mvar の値を減らす forkIO (server hdl) ‘finally‘ (decMvar mvar)
main スレッドは上限に達したら一定期間寝る
![Page 15: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/15.jpg)
15
上限を 1000 とすると
1000本のコネクションを安心してさばけるようになった
![Page 16: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/16.jpg)
16
2) 黙り込んだ相手のコネクションを切る 相手が黙ると読み込みはブロックする hGetLine :: Handle -> IO String
Timeout コンビネーター timeout :: Int -> IO a -> IO (Maybe a)
読み込めたら → Just 文字列 タイムアウトしたら → NothingスレッドスレッドスレッドスレッドMvar
TCPプロセスTimeout!
![Page 17: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/17.jpg)
17
いじわるなクライアントがいても
1000本のまともなコネクションをさばけるようになった
![Page 18: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/18.jpg)
18
3) プロセスを prefork する 普通は accept() の後に fork() するが… accept の前に forkProcess する main :: IO () main = do sock <- listenOn (Service "2000") replicateM_ 10 $ forkProcess (dispatch sock) mySleep -- threadDelay をループ dispatch :: Socket -> IO () dispatch sock = do (hdl,_,_) <- accept sock forkIO (server hdl) -- スレッドを作成 dispatch sock
![Page 19: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/19.jpg)
19
プロセスを10個 prefork すると親プロセス 子プロセス10×1000本のコネクションをさばけるようになった
![Page 20: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/20.jpg)
20
目標達成!
![Page 21: 大量のコネクションをさばく サーバーの作り方 - Mewkazu/material/2009-server.pdf · 2014. 6. 17. · 1 大量のコネクションをさばく サーバーの作り方](https://reader035.fdocuments.net/reader035/viewer/2022081407/6055e9f873ff6b7883668963/html5/thumbnails/21.jpg)
21
最後に
Web サーバーのデモとはいえないデモ