Python开发【Tornado】:异步Web服务

异步Web服务

前言:

  到目前为止,我们已经看到了许多使Tornado成为一个Web应用强有力框架的功能。它的简单性、易用性和便捷性使其有足够的理由成为许多Web项目的不错的选择。然而,Tornado受到最多关注的功能是其异步取得和提供内容的能力,它有着很好的理由:它使得处理非阻塞请求更容易,最终导致更高效的处理以及更好的可扩展性。在本章中,我们将看到Tornado异步请求的基础,以及一些推送技术,这种技术可以使你使用更少的资源来提供更多的请求以编写更简单的Web应用。

  大部分Web应用(包括我们之前的例子)都是阻塞性质的,也就是说当一个请求被处理时,这个进程就会被挂起直至请求完成。在大多数情况下,Tornado处理的Web请求完成得足够快使得这个问题并不需要被关注。然而,对于那些需要一些时间来完成的操作(像大数据库的请求或外部API),这意味着应用程序被有效的锁定直至处理结束,很明显这在可扩展性上出现了问题。

  不过,Tornado给了我们更好的方法来处理这种情况。应用程序在等待第一个处理完成的过程中,让I/O循环打开以便服务于其他客户端,直到处理完成时启动一个请求并给予反馈,而不再是等待请求完成的过程中挂起进程。

  我们将展示这个应用的三个不同版本:首先,是一个使用同步HTTP请求的版本,然后是一个使用带有回调函数的Tornado异步HTTP客户端版本。最后,我们将展示如何使用Tornado 2.1版本新增的gen模块来使异步HTTP请求更加清晰和易实现。

1、同步

记住我们在顶部导入了Tornado的httpclient模块:我们将使用这个模块的HTTPClient类来执行HTTP请求。之后,我们将使用这个模块的AsyncHTTPClient

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)

class IndexHandler(tornado.web.RequestHandler):

    def get(self):
        client = tornado.httpclient.HTTPClient()
        response = client.fetch("http://www.cnblogs.com/lianzhilei")    # 访问url,并返回response
        self.write("""
                <div style="text-align: center">
                    <div style="font-size: 72px">Time Cost</div>
                    <div style="font-size: 72px">%s</div>
                </div>"""%(response.request_time) )                      # 访问开销

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

这个程序的结构现在对你而言应该已经很熟悉了:我们有一个RequestHandler类和一个处理到应用根路径请求的IndexHandler。在IndexHandlerget方法中,实例化了一个Tornado的HTTPClient类,然后调用结果对象的fetch方法,fetch方法会返回一个HTTPResponse对象,fetch方法返回的HTTPResponse对象允许你访问HTTP响应的任何部分

到目前为止,我们已经编写了 一个请求API并向浏览器返回结果的简单Tornado应用。尽管应用程序本身响应相当快,但是向API发送请求到获得返回的搜索数据之间有相当大的滞后。在同步(到目前为止,我们假定为单线程)应用,这意味着同时只能提供一个请求。所以,如果你的应用涉及一个2秒的API请求,你将每间隔一秒才能提供(最多!)一个请求。这并不是你所称的高可扩展性应用,即便扩展到多线程和/或多服务器 。

为了更具体的看出这个问题,我们对刚编写的例子进行基准测试。你可以使用任何基准测试工具来验证这个应用的性能,不过在这个例子中我们使用优秀的Siege utility工具进行测试。它可以这样使用:

[[email protected] siege-4.0.2]# siege http://192.168.1.210:8000/ -c100 -t3s
** SIEGE 4.0.2
** Preparing 100 concurrent users for battle.
The server is now under siege...
HTTP/1.1 200     0.09 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.19 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.27 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.34 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.44 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.54 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.62 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.72 secs:     207 bytes ==> GET  /
HTTP/1.1 200     0.79 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.87 secs:     208 bytes ==> GET  /
HTTP/1.1 200     0.95 secs:     208 bytes ==> GET  /
HTTP/1.1 200     1.02 secs:     207 bytes ==> GET  /
HTTP/1.1 200     1.10 secs:     208 bytes ==> GET  /
HTTP/1.1 200     1.17 secs:     207 bytes ==> GET  /
HTTP/1.1 200     1.29 secs:     207 bytes ==> GET  /
HTTP/1.1 200     1.36 secs:     207 bytes ==> GET  /
HTTP/1.1 200     1.44 secs:     208 bytes ==> GET  /
HTTP/1.1 200     1.56 secs:     207 bytes ==> GET  /
HTTP/1.1 200     1.64 secs:     208 bytes ==> GET  /
HTTP/1.1 200     1.79 secs:     207 bytes ==> GET  /
HTTP/1.1 200     1.92 secs:     207 bytes ==> GET  /
HTTP/1.1 200     2.08 secs:     207 bytes ==> GET  /
HTTP/1.1 200     2.23 secs:     207 bytes ==> GET  /
HTTP/1.1 200     2.34 secs:     207 bytes ==> GET  /
HTTP/1.1 200     2.42 secs:     208 bytes ==> GET  /
HTTP/1.1 200     2.52 secs:     208 bytes ==> GET  /
HTTP/1.1 200     2.67 secs:     207 bytes ==> GET  /
HTTP/1.1 200     2.86 secs:     207 bytes ==> GET  /
HTTP/1.1 200     2.94 secs:     208 bytes ==> GET  /

Lifting the server siege...
Transactions:		          29 hits
Availability:		      100.00 %
Elapsed time:		        2.99 secs
Data transferred:	        0.01 MB
Response time:		        1.39 secs
Transaction rate:	        9.70 trans/sec
Throughput:		        0.00 MB/sec
Concurrency:		       13.43
Successful transactions:          29
Failed transactions:	           0
Longest transaction:	        2.94
Shortest transaction:	        0.00

  

时间: 2024-08-11 07:32:41

Python开发【Tornado】:异步Web服务的相关文章

《Introduction to Tornado》中文翻译计划——第五章:异步Web服务

http://www.pythoner.com/294.html 本文为<Introduction to Tornado>中文翻译,将在https://github.com/alioth310/itt2zh上面持续更新,本文内容可能不是最新状态,请在GitHub上获得最新版本. 本文也可在http://demo.pythoner.com/itt2zh上进行格式化的预览. 第五章:异步Web服务 到目前为止,我们已经看到了许多使Tornado成为一个Web应用强有力框架的功能.它的简单性.易用性

第五章:异步Web服务

到目前为止,我们已经看到了许多使Tornado成为一个Web应用强有力框架的功能.它的简单性.易用性和便捷性使其有足够的理由成为许多Web项目的不错的选择.然而,Tornado受到最多关注的功能是其异步取得和提供内容的能力,它有着很好的理由:它使得处理非阻塞请求更容易,最终导致更高效的处理以及更好的可扩展性.在本章中,我们将看到Tornado异步请求的基础,以及一些推送技术,这种技术可以使你使用更少的资源来提供更多的请求以编写更简单的Web应用. 5.1 异步Web请求 大部分Web应用(包括我

tornado异步web请求

1.为什么要使用异步web服务使用异步非阻塞请求,并发处理更高效. 2.同步与异步请求比较同步请求时,web服务器进程是阻塞的,也就是说当一个请求被处理时,服务器进程会被挂起直至请求完成. 异步请求时,web服务器进程在等待请求处理过程中,让I/O循环打开,以便服务于其他请求,请求处理完成后继续执行回调函数或生成器,而不再是等待请求过程中挂起进程.整个过程是异步的. 3.同步与异步请求示例同步请求: class IndexHandler(tornado.web.RequestHandler):

如何设计一个异步Web服务——接口部分

需求比较简单,提供一个异步Web服务供使用者调用.比如说,某应用程序需要批量地给图片加lomo效果.由于加lomo效果这个操作非常消耗CPU资源,所以我们需要把这个加lomo效果的程序逻辑放到一台单独的服务器上去运行,以免影响应用本身所在服务器的性能. 这篇先讲讲服务的接口部分,侧重于理清应用和服务之间的调用关系,有时间的话,后面再写一篇关于服务内部任务分派资源调度的随笔. 根据这个需求,我们可以很快设计出一套流程: Application通过向service的addTask接口post任务相关

asyncio创建协程解析——分析廖雪峰的Python教程之创建WEB服务(转)

第一步,搭建开发环境 所需第三方库: aiohttp,异步 Web 开发框架:jinja2,前端模板引擎:aiomysql,异步 mysql 数据库驱动 所需内置库: logging,系统日志:asyncio,异步IO:os,系统接口:json,json 编码解码模块:time,系统时间模块:datetime,日期模块 接下来仅对用到的功能进行讲解 第二步,构建 Web 框架 主要思路: 理解 asyncio.aiohttp 基本应用 使用 asyncio 异步 IO 模块创建服务协程,监听相应

Python 最简单的web服务

python -m SimpleHTTPServer  8321   1.python 没有指定目录的参数 想启动目录 就cd到该目录下 2.在目录下创建一个index.html 3.启动web服务,(端口被占用会报错的)    

从开发的角度比较 ASP.NET Web 服务与 WCF

Windows Communication Foundation (WCF) 具有一个 ASP.NET 兼容模式选项,用户使用此选项可以对 WCF 应用程序进行编程和配置,使其像 ASP.NET Web 服务一样,并且还可以模仿这些服务的行为.以下各部分基于使用这两种技术开发应用程序的要求来比较 ASP.NET Web 服务和 WCF. 数据表示形式 一般情况下,使用 ASP.NET 开发 Web 服务首先要定义服务要使用的任意复杂数据类型.ASP.NET 依赖于 XmlSerializer 将

Python Web 服务开发者: 第 1 部分

Python Web 服务开发者: 第 1 部分 Python Web 服务世界 Python 的座右铭一向是“装备齐全”,这是指在安装该语言时会附带一大套标准库和功能程序.本文概述了在 Python 中开发 Web 服务时可以使用的工具和功能程序.这些工具和功能程序包括内置的 Python 功能和第三方开放源代码的工具 0 评论: Mike Olson([email protected])Fourthought, Inc. Uche Ogbuji([email protected])Fourt

服务器端异步 Web 方法

何时采用异步 Web 方法 在确定是否适合在您的应用程序中采用异步 Web 方法时,有几个问题需要考虑.首先,调用的 BeginXXX 函数必须返回一个 IAsyncResult 接口.IAsyncResult 是从多个异步 I/O 操作返回的,这些操作包括访问数据流.进行 Microsoft® Windows® 套接字调用.执行文件 I/O.与其他硬件设备交互.调用异步方法,当然也包括调用其他 Web 服务.您可以从这些异步操作中得到 IAsyncResult,以便从 BeginXXX 函数返