Your SlideShare is downloading. ×
Nginx + Tornado = 17k req/s
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Nginx + Tornado = 17k req/s

9,013
views

Published on

Lightning Tech Talk during PythonBrasil[7] at Globo.com stand

Lightning Tech Talk during PythonBrasil[7] at Globo.com stand

Published in: Technology

1 Comment
25 Likes
Statistics
Notes
No Downloads
Views
Total Views
9,013
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
54
Comments
1
Likes
25
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript

    • 1. globo Tornado + Nginx = 17k req/s.com
    • 2. two servers, one goal
    • 3. ‣ huge potential userbase ‣ live sports events1.000.000 ‣ ‣ changing business model unknown user behavior ‣ “beta” - small investment ‣ gotta keep it simple!
    • 4. “Its time for web servers to handle ten thousand clients simultaneously,dont you think? After all, the web is a big place now.”
    • 5. as simple as you need - as robust as you want nginx nginx tornado mongo frontend backend filer filesystem
    • 6. ‣ “there’s a lot of caching” ‣ scores, current transmissions etc. are updated quickly ‣ out of bounds to the general public - closed beta‣ authentication and authorization from separate systems ‣ just checking if cookies exist on the frontend
    • 7. import tornado.ioloop import tornado.web‣ plain Python class MainHandler(tornado.web.RequestHandler):     def get(self):‣ good looking Python         self.write("Hello, world")‣ sweet! application = tornado.web.Application([     (r"/", MainHandler), ])‣ fast! if __name__ == "__main__": ‣ ab req/s: 2987.96     application.listen(8888)     tornado.ioloop.IOLoop.instance().start()
    • 8. import json import tornado.ioloop import tornado.web import tornado.httpclient search = http://search.twitter.com/search.json?‣ non-blocking web server q=pythonbrasil&result_type=mixed&count=1 class MainHandler(tornado.web.RequestHandler):‣ so please don’t block it!     def get(self):         self.write("Hello blocking Twitter!n")         http_client = tornado.httpclient.HTTPClient()‣ the blocking way...         response = http_client.fetch(search)         last_tweet = json.loads(response.body)[results][0][text]         self.write(last_tweet) ‣ ab req/s: 0.81 application = tornado.web.Application([     (r"/", MainHandler), (over our poor local wi-fi) ]) if __name__ == "__main__":     application.listen(8888)     tornado.ioloop.IOLoop.instance().start()
    • 9. import json import tornado.ioloop import tornado.web import tornado.httpclient from tornado.web import asynchronous search = http://search.twitter.com/search.json? q=pythonbrasil&result_type=mixed&count=1‣ the non-blocking way... class MainHandler(tornado.web.RequestHandler): ‣ ab req/s: 7.25     @asynchronous     def get(self):         self.write("Hello blocking Twitter!n") (over our poor local wi-fi)         http_client = tornado.httpclient.AsyncHTTPClient()         response = http_client.fetch(search, self.handle_response)     def handle_response(self, response):         last_tweet = json.loads(response.body)[results][0][text]         self.finish(last_tweet) application = tornado.web.Application([     (r"/", MainHandler), ]) if __name__ == "__main__":     application.listen(8888)     tornado.ioloop.IOLoop.instance().start()
    • 10. import tornado.ioloop import tornado.web from db import users class HomeHandler(tornado.web.RequestHandler):     def get(self):         if signed_in == self.get_secure_cookie(access):             self.write(Hello to your world!)         else:             self. write(Hello, world!)‣ secure cookies class SigninHandler(tornado.web.RequestHandler):     def post(self):         if self.get_attribute(login) in users: ‣ not persisted             self.set_secure_cookie(access, signed_in, expires_days=None)         self.redirect(/) ‣ served from any class SignoutHandler(tornado.web.RequestHandler):     def get(self): instance         self.clear_cookie(access)         self.redirect(/) application = tornado.web.Application([     (r"/", HomeHandler), (r"/signin", SigninHandler),     (r"/signout", SignoutHandler), ], **{     cookie_secret: i_should_be_reading_that_from_env }) if __name__ == "__main__":     application.listen(8888)     tornado.ioloop.IOLoop.instance().start()
    • 11. ‣ what else? ‣ templates extensions ‣ semi-standardized project structure ‣ pre-rendered data for frequently updated data - scores
    • 12. ‣ most URLs are served as fast as nginx can ‣ on a single 24 processors17.000 server our load tests got us to 17k req/s served by Tornado ‣ few pages with heavy DB access served less than 4k req/s
    • 13. Valeu!Danilo Moret - Globo.com / Webmedia / Vídeos 3moret@corp.globo.com - http://moret.pro.br/ - @moret1979