Successfully reported this slideshow.
Your SlideShare is downloading. ×

Woo: Writing a fast web server @ ELS2015

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 63 Ad

More Related Content

Slideshows for you (20)

Viewers also liked (20)

Advertisement

Similar to Woo: Writing a fast web server @ ELS2015 (20)

Recently uploaded (20)

Advertisement

Woo: Writing a fast web server @ ELS2015

  1. 1. Woo: Writing a fast web server 8th European Lisp Symposium @ London, UK April 21, 2015 Eitaro Fukamachi Somewrite Co., Ltd.
  2. 2. I’m Eitaro Fukamachi @nitro_idiot fukamachi
  3. 3. My Products • Clack • Caveman2 • CL-DBI • quickdocs.org • datafly • SxQL ...and 25 other libraries
  4. 4. We’re hiring!
  5. 5. Woo
  6. 6. • HTTP server written in Common Lisp • HTTP/0.9, HTTP/1.x • Clack compliant Woo
  7. 7. Clack? • Abstraction layer of HTTP servers Web server Application Web server Web server Application Application
  8. 8. Clack? • Abstraction layer of HTTP servers Web server Application Web server Web server Application Application Clack
  9. 9. ex) Caveman2 • built on top of Clack Web serverWeb server Web server Caveman2
 (Web framework) Clack
  10. 10. ex) RESTAS (without Clack) • directly built on top of Hunchentoot Web server Depends on Hunchentoot. Can’t switch the backend!! Supports only Hunchentoot Web server Web server RESTAS
 (Web framework)
  11. 11. Clack-compliant (woo:run (lambda (env) ‘(200 (:content-type “text/plain”) (“Hello, World”)))) (clack:clackup (lambda (env) ‘(200 (:content-type “text/plain”) (“Hello, World”))) :server :woo) Run with Clack
  12. 12. Fast https://github.com/fukamachi/woo#benchmarks
  13. 13. Fast — in the real worldreq/sec 0 33 65 98 130 Node.js Woo 127.18 76.73 1.6 times faster!
  14. 14. Let me tell why I had to write a fast HTTP server.
  15. 15. Wookie is slower than Node.js • Wookie is 2 times slower than Node.js
  16. 16. Wookie is slower than Node.js • Wookie is 2 times slower than Node.js IS COMMON LISP SLOW???
  17. 17. Wookie is slower than Node.js • Wookie is 2 times slower than Node.js IS COMMON LISP SLOW??? NO WAY!
  18. 18. So, I decided to write a faster one.
  19. 19. How could it be fast?
  20. 20. 3 difficulties in writing an HTTP servers
  21. 21. 3 difficulties in HTTP server • Network I/O is the largest bottleneck • Need to handle a vast amount of requests at once • Need to handle various HTTP clients
 (fast / slow / unstable)
  22. 22. 3 tactics (no silver bullet) 1. Better architecture 2. Fast HTTP parsing 3. The libev event library
  23. 23. Tactic 1: Better architecture
  24. 24. 2 architectures: Prefork vs Event-driven
  25. 25. Prefork Worker process Worker process Worker process master process Requests accept connections Responses • Simple • Fast for little simultaneous connections • ex) Hunchentoot, Unicorn, Apache
  26. 26. Prefork Worker process Worker process Worker process master process Requests accept connections Responses • Slow client can cause performance issue. • like Mobile users • Slowloris attack blocking! ・・・ Problem
  27. 27. Event-driven • Handle many clients at the same time • Asnyc ACCEPT/ READ/WRITE • ex) Woo, Wookie, Tornado, nginxServer process (single-threaded) Event loop
  28. 28. Event-driven • Single-threaded Problem Server process (single-threaded) Event loop
  29. 29. Woo took another way: Multithreaded event-driven
  30. 30. Multithreaded event-driven Server process Event loop listen on the same file descriptor Server process Event loop Server process Event loop
  31. 31. Tactic 2: Fast HTTP parsing
  32. 32. HTTP parsing can be a bottleneck • Wookie's largest bottleneck is HTTP parsing • http-parse (uses regular expression) • fast-http (byte by byte parser) • 6000 times faster than http-parse
  33. 33. A brief introduction of HTTP
  34. 34. HTTP request look like… GET /media HTTP/1.1↵ Host: somewrite.jp↵ Connection: keep-alive↵ Accept: */*↵ ↵
  35. 35. HTTP request look like… GET /media HTTP/1.1↵ Host: somewrite.jp↵ Connection: keep-alive↵ Accept: */*↵ ↵ First Line Headers Body (empty, in this case)
  36. 36. HTTP request look like… GET /media HTTP/1.1↵ Host: somewrite.jp↵ Connection: keep-alive↵ Accept: */*↵ ↵ CR + LF CRLF * 2 at the end of headers
  37. 37. HTTP is… • Text-based protocol. (not binary) • Lines terminated with CRLF • Very lenient. • Ignore multiple spaces • Allow continuous header values
  38. 38. And, there’s another difficulty.
  39. 39. HTTP messages are sent over a network.
  40. 40. Which means, we need to think about long & incomplete HTTP messages.
  41. 41. There’s 2 ways to resolve this problem.
  42. 42. 1. Stateful (http-parser)
  43. 43. http-parser (used in Node.js) • https://github.com/joyent/http-parser • Written in C • Ported from Nginx’s HTTP parser • Written as Node.js’s HTTP parser • Stateful
  44. 44. http-parser (used in Node.js) for (p=data; p != data + len; p++) { … switch (parser->state) { case s_dead: … case s_start_req_or_res: … case s_res_or_resp_H: … } }
  45. 45. http-parser (used in Node.js) for (p=data; p != data + len; p++) { … switch (parser->state) { case s_dead: … case s_start_req_or_res: … case s_res_or_resp_H: … } } Process char by char Do something for each state
  46. 46. http-parser (used in Node.js) for (p=data; p != data + len; p++) { … switch (parser->state) { case s_dead: … case s_start_req_or_res: … case s_res_or_resp_H: … } } Process char by char Do something for each state Executed for every char!!
  47. 47. 2. Stateless (PicoHTTPParser)
  48. 48. PicoHTTPParser (used in H2O) • https://github.com/h2o/picohttpparser • Written in C • Stateless
  49. 49. PicoHTTPParser (used in H2O) • https://github.com/h2o/picohttpparser • Written in C • Stateless • Reparse when the data is incomplete • Most HTTP request is small
  50. 50. And fast-http is…
  51. 51. fast-http is in the middle • Stateful • Track state for every line, not every char • 1.25 times faster than C http-parser.
  52. 52. Tactic 3: The libev event library
  53. 53. libev • Wrapper of epoll, kqueue, POSIX select, poll • Thin • Fast
  54. 54. libev • Wrapper of epoll, kqueue, POSIX select, poll • Thin • Fast • Poor Windows support • Windows isn’t popular for running an HTTP server
  55. 55. Goal
  56. 56. Goal: What is fast enough? • The initial goal was “Beating Node.js” • Done • Being the fastest HTTP server in Common Lisp • Done
  57. 57. Got a great Pull Request
  58. 58. See Also • Clack: clacklisp.org • fast-http: github.com/fukamachi/fast-http • libev • Woo: github.com/fukamachi/woo
  59. 59. You may be interested in • Dexador: github.com/fukamachi/dexador • HTTP client library built on top of fast-http and usocket.
  60. 60. Thanks.
  61. 61. EITARO FUKAMACHI 8arrow.org @nitro_idiot fukamachi

×