在python里面,有许多web framework。对于我来说,因为很长一段时间都在使用tornado,所以有了一些心得体会。虽然现在我的工作重点已经转向go了,但是我觉得还是有必要记录一下tornado的相关东西,毕竟我的高性能网络库 libtnet 就是参考tornado来设计的。
在这里,要说明一下,tornado采用的是2.4版本。
tornado是一个典型的prefork + io event loop的web server架构,
从图上可以看出,tornado的架构是很简单清晰的。
通过上面的分析,直到tornado的架构是很简单明了的,所以自然我们也能够通过简短的一些代码就能搭建起自己的http server。以一个hello world开始:
import tornado.web
import tornado.httpserver
import tornado.ioloop
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write('Hello World')
application = tornado.web.Application([
(r"/", MainHandler),
])
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8080)
tornado.ioloop.IOLoop.instance().start()
流程很简单,如下:
当ioloop start之后,服务器就启动了,后续就是一个http server最基本的流程处理了。
从上面例子可以看出,搭建一个http server很简单,所以我们重点只需要考虑的是如何处理不同的url http请求,这也就是RequestHandler需要做的事情。
我们在创建Application的时候,会指定不同的url pattern需要处理的handler。如下:
import tornado.web
import tornado.httpserver
import tornado.ioloop
class Index1Handler(tornado.web.RequestHandler):
def get(self):
self.write('Index1')
class Index2Handler(tornado.web.RequestHandler):
def get(self, data):
self.write('Index2')
self.write(data)
application = tornado.web.Application([
(r"/index1", Index1Handler),
(r"/index2/(\w+)", Index2Handler),
])
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(8080)
tornado.ioloop.IOLoop.instance().start()
在上面的例子中,我们有两个handler,分别处理url path为index1和index2的情况,对于index2来说,我们看到,它后面还需要匹配一个单词。我们通过curl访问如下:
$ curl http://127.0.0.1:8080/index1
index1
$ curl http://127.0.0.1:8080/index2/abc
index2abc
RequestHandler支持任何http mthod,包括get,post,head和delete,也就是说,tornado天生支持restful编程模型。
class MainHandler(tornado.web.RequestHandler):
def get(self):
pass
def post(self):
pass
def head(self):
pass
def delete(self):
pass
从上面可以看到,我们只需要在handler里面实现自己的get,post,head和delete函数就可以了,这点再次说明tornado的简洁与强大。
这里,只是简单了介绍了一下tornado,后续将会从template,asynchronous,security等分别介绍一下。希望通过这个能让自己对tornado的理解更加深刻,同时也为后续使用其他python web framework做参考。