Home >Backend Development >Python Tutorial >如何理解 Tornado ?

如何理解 Tornado ?

WBOY
WBOYOriginal
2016-06-06 16:23:041329browse

tornado 到底是个什么东西呢?

  1. 如果它是个webserver ,那么后端如何搭配Django使用 ,又能否搭配Node.js 或 PHP?
  2. 如果作为web框架,nginx对于她来说意义在哪里? 在实际使用中是否会影响Tornado本身的异步IO设计?
  3. Tornado与node.js 的实现的目的 ,和设计方式上的不同之处在哪里 ( 不谈语言 )?
-----------------------------

补充:以下是看官方说明和 Google 了一番后的理解:
  1. 它可以作为一个裸 webserver 来使用 ,就是说它的后端可以运行 Django、web.py。
  2. 它是一个简单 Python 框架,url 基于正则,有自己的模板实现,但是没有 orm。这部分看起来类似于 web.py。
  3. 非阻塞异步 IO,类似于 node.js。
  4. 它的前端可以放 Nginx ,感觉类似于 Nginx、Apache 之于 Tomcat。

就是说它作为 web 框架比 Django 简单,又支援异步 IO,且更不需要前端的 webserver ?
我已经混乱了, Tornado是 Nginx、Django、Node.js 的结合体?又或是 Nginx * 20% + Django * 40% + Node.js * 40% ?

回复内容:

我来回答一下答主补充的问题:

> 就是说它作为 web 框架比 Django 简单,又支援异步 IO,且更不需要前端的 webserver ?
> 我已经混乱了, Tornado是 Nginx、Django、Node.js 的结合体?又或是 Nginx * 20% + Django * 40% + Node.js * 40% ?


你需要搞清楚几个概念:
1,web server是监听端口,负责HTTP链接管理、数据收发、HTTP协议实现等底层上的处理。
2,Web框架定义的是单个HTTP请求处理的流程。
3,nginx是反向代理服务器,是一个特殊的web server应用,和web server并不是同级的概念。

Tornado既是web server又是web框架,这两者并不矛盾。

举例来说,你写了一个tornado应用之后,直接把tornado端口跑在8000,这个时候,通过localhost:8000/foo就能访问到你的网页。这里分两步,tornado完成了底部IO事件的监听和数据接受等工作,这是tornado完成了其作为web server的使命。然后你通过按照tornado框架定义的流程,在对应的地方写了个get函数,实现了这个页面的具体内容,这是tornado作为web 框架体现了作用。

那么nginx有什么用?

他是个反向代理,反向代理顾名思义,其作用就是将接收到的HTTP请求按照一定的规则转发给后端其他服务器处理。

比如在你的一台机器上跑了三个tornado应用:foo1,foo2,foo3,端口分别为8000,8001,8003,你希望用户可以直接通过80端口来访问这些应用。这个时候你就可以用nginx来达到这个目的了。让nginx跑在80端口,当他接收到请求时,如果是/foo1,就转发给8000端口处理;如果是/foo2,就转发给8001端口处理,foo3类似。


所以,tornado和nginx并没有什么联系。实际上,很多框架都实现了一些简易web server,用于调试。tornado的web server是异步的,以可以处理大量的非活跃长连接著称。所以其web server是他的一个特性feature,在介绍的时候就会提及自己是一个很酷的webserver了。

回到主题,题主你在你机器上装装nginx、用tornado写个hello world就都清楚了。

祝折腾快乐 Tornado既是一个web server,也是web framework。而它作为web server 采用的是asynchronous IO的网络模型,这是一种很高效的模型。

web framework的定义(wiki.python.org/moin/We
A Web framework is a collection of packages or modules which allow developers to write Web applications or services without having to handle such low-level details as protocols, sockets or process/thread management.
Tornado作为web server,提供了web framework的api,可以来直接构建自己的web程序。同时,Tornado支持WSGI ( python.org/dev/peps/pep ),也就是说它可以有能力其它的一些python的框架一起使用,比如django, bottle, flask等。不妨看下bottle在不同server下的性能评测,其中就有tornado( bottlepy.org/page/2009- )。额外说的是,WSGI的框架是不支持异步的,所以如果有异步调用的逻辑的web程序,Tornado也是选择之一。

没有使用过Node.js,但官网说:
Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications.
可以把Node.js理解成基于V8的javascript运行环境或工具包,它属于偏底层的抽象,扩展了javascript写服务端程序的能力。所以基于它也会有不同的web framework。从这个角度来看,Node.js和Tornado其实不在一个层次上。
不过相同的是 Node.js 和 Tornado都采用的的单进程单线程异步IO的网络模型。它们都可以写异步非阻塞的程序,不过我觉得因为javascript的语言特性,Node.js对异步回调非阻塞的风格坚持比Tornado更彻底一点。不过通常多进程时,一个进程的短时间阻塞也是可以接受的。

使用Nginx是因为一些单进程服务无法利用多核CPU,同时也会有单机的限制,所以通常会在多个服务器启动多个进程实例,使用Nginx在前端作为反向代理服务器来分发web请求,同时负载均衡。Nginx是C写的,有更好的并发性,可配置性,对静态文件也有更好的支持。当然这是Nginx的常用情景,其实也可以直接使用Nginx来构建web应用,可以参考OpenResty项目( openresty.org/ )。

其实网络模型、web server、web framework是三个不同层次,它们之间并不冲突,是选择的关系。理解前,不妨先理清概念:) 建议楼主阅读一下这篇论文 C10K problem,虽然有点老了kegel.com/c10k.html

其实,你也可以说nginx是一个framework,不过是针对C的。

裸WebServer表示他支持HTTP协议,既然支持HTTP协议,你前面放啥反向都无所谓,nginx apache squid varnish。或者也可以用wsgi模块,只是采用了特殊的通讯协议。

为什么要在tornado前面放nginx,原因在于,Python虽然有多线程,但是Python的解释器有GIL en.wikipedia.org/wiki/G 这点非常影响了Python和Tornado利用多核的能力,所以只能通过多进程来利用多核。既然多进程,一般就需要在前端放置nginx haproxy做为负载均衡的反向代理,或是使用这些应用服务器的wsgi模块来管理进程的生命周期等等。另外对于静态文件的服务,也是nginx之类的更具有优势。(他们直接把请求转发到tornado的进程中,你根本不用管请求怎么来的,专心写你的程序。)

其他很多脚本语言的框架都有类似问题,比如ruby,而Nodejs更加是连线程都没有了。

Nodejs的核心在于,他使用了JavaScript天生擅长的事件/回调机制来实现异步。
Python对于匿名函数和闭包支持不够好,所以Tornado通过了类来和回调方法来实现异步,这里没有事件的概念。(没深入研究过Tornado,大致是这么了解的)
另外Tornado封装了很多常用的诸如静态文件处理、Router、模板等等,而Nodejs基本上是一个纯粹的协议框架,这些功能都需要自己去写。Nodejs+Express差不多就可以等于Tornado的功能了。

而如果是要做一个中间件或中间层,做一些高级点的协议处理,可能nodejs更加能胜任。
在tornado里面去调用用php或者nodejs所开发的服务,这是没问题的,主要要看架构上如何设计。 tornado是一个异步的http框架,fb最早是拿tornado做feed流上提醒用的,tornado内置了一个asynchttpclient,这个特别适合基于rest web service做网站,使用@gen.coroutine 和yield基本上就可以把异步代码变成同步代码了。tornado代码量不大,特别适合有兴趣的人,自己研究用。

不过tornado问题也不小,做网站的话,最主要的是,tornado是单线程的(虽然可以通过fork来搞多进程),而web后端多用rdbms,特别是mysql主要的driver都是同步阻塞的,也就是说访问数据库会阻塞tornado,所以对做网页的限制比较大。 都是长篇啊。。其实把 epoll 了解了解,然后 tornado 里 ioloop 那里看明白就好了 首先我觉得web server和web框架这两个功能本身并不冲突,因为http server的功能就是连接接入,业务逻辑处理,返回页面。因此tornado, node.js, django, nginx都可以实现这样的功能,只是使用场景的不同,导致他们或归为web server或归为web框架。
首先说说nginx,主要应用场景是反向代理,负责前端连接接入,继而向后请求后端服务。而nginx本身提供一些负载均衡的功能可以加强web服务的负载能力。但同时nginx也可以作为web框架,只是其c语言开发成本较大,所以用的人比较少而已。不过@agentzh 开发的openresty可以用Lua去写nginx的扩展,这也增强了nginx作为web框架处理业务逻辑的能力。
再说说node.js,node的定位并不完全是web server和web框架,它更多的是实现了一套javascript在服务器上的运行时,但由于其本身异步网络的特点,所以作为一个网络服务框架非常合适,可以看到node实现的httpserver实际上非常简单,这也诞生了express这种目标就是web框架的中间件。
django我只有个大概的了解,感觉它的定位是一个web服务的全套解决方案(如rails),提供了orm,抽象后台管理等web服务常用的功能,因此它的目标定位是web框架,但由于是同步的(很多年没关注了,现在改没改不知道),所以比较影响接入能力,所以前面一般要挂个异步反向代理。
而tornado的定位也更像是轻量级web框架,提供异步能力,但对于业务逻辑处理的支持比django要简单,因此和node一样比较适合做服务中间件。
从业务逻辑处理的角度来说,虽然异步处理能力已经有了比较大的提升,但node和tornado都是单进程的,因此一般要启多个实例,前端再用nginx做接入和负载均衡。
所以从架构选型的角度,nginx做前端接入,后面服务逻辑的选择就看需求了,如果只是最基本的web服务,如cms之类的,django比较方便,可以省下很多开发量。而node和tornado做复杂web系统的中间件比较合适…… 大家的回答都有点片面,更多的关注web框架成,其实tornado远远不止这些,且听我慢慢到来
1.高性能的网络库,这可以和gevent,twisted,libevent等做对。提供了异步io支持,超时事件处理,在此基础上提供了tcpserver,httpclient,尤其是curlhttpclient在现有http客户端中肯定排第一。可以用来做爬虫,游戏服务器,据我所知业界已有使用tornado作为游戏服务器

2.web框架,这可以和django,flask对。提供了路由,模板等web框架必备组件。与其他区别是tornado是异步的,天然适合长轮训,这也是friendfeed发明tornado的原因,
当前flask也可以支持,但必须借住gevent等

3.较为完备的http服务器,这点可以和nginx,apache对比,但只支持http1.0,所以使用nginx做前段不仅是为了更好利用多核,也是让其支持http1.1

4.完备的wsgi服务器,这可以和gunicore,gevent wsgi server做对比,也就是说可以让flask运行在tornado之上,让tornado加速flask
5.提供了完备的websocket支持,这让html5的游戏等提供了便利。像知乎长轮训就是使用了websocket,但websocket手机支持的不是很好,前段时间不得不使用定时ajax发送大量请求,期待手机浏览器赶快奋起直追

tornado,你值得拥有 tornado自带了一个web服务器,性能不错,但由于实现简化了很多功能,建议跑在nginx后面

tornado本身又是一个web框架,但是没有预先实现很多功能,只保留比较必要的组件,这个和Django就有点相反的思路。
虽然思路相反,但Django其实也是围绕着一个设计精良的core来实现的,如果单独把这个core抽取出来其实和Tornado的规模和功能都差不多。它的功能丰富(甚至是复杂)只不过是一种“一站式框架”的理念的体现而已。
简单来说,就是它们一个是简约框架,一个是把可能需要的组件都默认配给你的框架。喜欢用哪个看个人爱好。前者的麻烦是遇到某些问题要自己重新实现,后者的麻烦是如果它预置给你的不能满足要求也要自己重新实现,归根到底就是找到一个平衡点,尽量方便开发就可以了。

异步方面个人不推荐node.js,js用在服务端还是很少的,很多组件都不齐全,要成熟还得比较久,用Python可以有很多现有的组件使用。

最后,如果关心性能,请尝试pypy,在Linux下网络IO方面毫不逊色node.js,不过大部分情况下性能问题都不在Python写的东西中,而在数据库。 1. 轻框架,从web.py开始,flask,bottle这些都是轻框架,tornado则是轻框架的代表
2. 高性能异步框架,直接基于ioloop写东西,你就觉得tornado不仅仅是web框架了
3. 队列服务器,我们实现一个两级tornado服务器模型,前面的负责web分配和并发,后面负责单线程高cpu计算,轻松解决了单线程高运算量的block问题

WSGI功能可以忽略不计了

理解了tornado的特性之后,我们发现唯一需要和tornado配合的就是nginx,既可以做负载均衡,又可以挡住静态文件请求。除此以外你还需要个mysql,试试torndb。

使用tornado可以大大的减少web系统中使用的组件数量,用最少的代码量和极其精简的架构实现你的系统。 Tornado 是一个web服务器。django是一个快速web程序编写框架。node.js是一种编程环境。你直接用Tornado 写网站也可以,但是它只有最基本的功能,你写个网站工作量不小,而DJANGO则可以帮助你快速的编写网站程序,而后部署在Tornado 或者其他web服务器上。node.js则是类似PYTHON的一种编程环境,它可以实现很多东西。我认为你要做个网站,真正现实的就是PHP、rails、django,真正重要的快速实现你的想法,性能之类的东西开始并不重要。
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn