关于Tornado的入门看这篇文章,写的非常好:

https://zhuanlan.zhihu.com/p/37382503

Tornado 是一个Python web框架和异步网络库,使用非阻塞网络I/O。

Tornado可以被分为4个主要的部分:

  • web框架
  • HTTP的客户端和服务端实现
  • 异步网络库
  • 协程库

WSGI是Web Server Gateway Interface的缩写。

实时web功能需要为每个用户提供一个多数时间被闲置的长连接, 在传统的同步web服务器中,这意味着要为每个用户提供一个线程, 当然每个线程的开销都是很昂贵的.

为了尽量减少并发连接造成的开销,Tornado使用了一种单线程事件循环的方式. 这就意味着所有的应用代码都应该是异步非阻塞的, 因为在同一时间只有一个操作是有效的.

知乎和掌阅的后端应该采用了这个框架。

下面提供快速帮助回忆的代码:(阶乘服务和圆周率计算服务)

  1. # pi.py
  2. import json
  3. import math
  4. import redis
  5. import tornado.ioloop
  6. import tornado.web
  7.  
  8. class FactorialService(object):
  9.  
  10. def __init__(self, cache):
  11. self.cache = cache
  12. self.key = "factorials"
  13.  
  14. def calc(self, n):
  15. s = self.cache.hget(self.key, str(n))
  16. if s:
  17. return int(s), True
  18. s = 1
  19. for i in range(1, n):
  20. s *= i
  21. self.cache.hset(self.key, str(n), str(s))
  22. return s, False
  23.  
  24. class PiService(object):
  25.  
  26. def __init__(self, cache):
  27. self.cache = cache
  28. self.key = "pis"
  29.  
  30. def calc(self, n):
  31. s = self.cache.hget(self.key, str(n))
  32. if s:
  33. return float(s), True
  34. s = 0.0
  35. for i in range(n):
  36. s += 1.0/(2*i+1)/(2*i+1)
  37. s = math.sqrt(s*8)
  38. self.cache.hset(self.key, str(n), str(s))
  39. return s, False
  40.  
  41. class FactorialHandler(tornado.web.RequestHandler):
  42.  
  43. def initialize(self, factorial):
  44. self.factorial = factorial
  45.  
  46. def get(self):
  47. n = int(self.get_argument("n") or 1)
  48. fact, cached = self.factorial.calc(n)
  49. result = {
  50. "n": n,
  51. "fact": fact,
  52. "cached": cached
  53. }
  54. self.set_header("Content-Type", "application/json; charset=UTF-8")
  55. self.write(json.dumps(result))
  56.  
  57. class PiHandler(tornado.web.RequestHandler):
  58.  
  59. def initialize(self, pi):
  60. self.pi = pi
  61.  
  62. def get(self):
  63. n = int(self.get_argument("n") or 1)
  64. pi, cached = self.pi.calc(n)
  65. result = {
  66. "n": n,
  67. "pi": pi,
  68. "cached": cached
  69. }
  70. self.set_header("Content-Type", "application/json; charset=UTF-8")
  71. self.write(json.dumps(result))
  72.  
  73. def make_app():
  74. cache = redis.StrictRedis("localhost", 6379)
  75. factorial = FactorialService(cache)
  76. pi = PiService(cache)
  77. return tornado.web.Application([
  78. (r"/fact", FactorialHandler, {"factorial": factorial}),
  79. (r"/pi", PiHandler, {"pi": pi}),
  80. ])
  81.  
  82. if __name__ == "__main__":
  83. app = make_app()
  84. app.listen(8888)
  85. tornado.ioloop.IOLoop.current().start()

因为两个Handler都需要用到redis,所以我们将redis单独抽出来,通过参数传递进去。另外Handler可以通过initialize函数传递参数,在注册路由的时候提供一个字典就可以传递任意参数了,字典的key要和参数名称对应。我们运行python pi.py,打开浏览器访问http://localhost:8888/pi?n=200,可以看到浏览器输出{"cached": false, "pi": 3.1412743276, "n": 1000},这个值已经非常接近圆周率了。

下面来自知乎:(写的非常好)

https://zhuanlan.zhihu.com/p/37382503

Tornado:Hello, World

  1. import tornado.ioloop
  2. import tornado.web
  3.  
  4. class MainHandler(tornado.web.RequestHandler):
  5. def get(self):
  6. self.write("Hello, world")
  7.  
  8. def make_app():
  9. return tornado.web.Application([
  10. (r"/", MainHandler),
  11. ])
  12.  
  13. if __name__ == "__main__":
  14. app = make_app()
  15. app.listen(8888)
  16. tornado.ioloop.IOLoop.current().start()

这是官方提供了Hello, World实例,执行python hello.py,打开浏览器访问http://localhost:8888/就可以看到服务器的正常输出Hello, world

一个普通的tornado web服务器通常由四大组件组成。

  1. ioloop实例,它是全局的tornado事件循环,是服务器的引擎核心,示例中tornado.ioloop.IOLoop.current()就是默认的tornado ioloop实例。
  2. app实例,它代表着一个完成的后端app,它会挂接一个服务端套接字端口对外提供服务。一个ioloop实例里面可以有多个app实例,示例中只有1个,实际上可以允许多个,不过一般几乎不会使用多个。
  3. handler类,它代表着业务逻辑,我们进行服务端开发时就是编写一堆一堆的handler用来服务客户端请求。
  4. 路由表,它将指定的url规则和handler挂接起来,形成一个路由映射表。当请求到来时,根据请求的访问url查询路由映射表来找到相应的业务handler。

这四大组件的关系是,一个ioloop包含多个app(管理多个服务端口),一个app包含一个路由表,一个路由表包含多个handler。ioloop是服务的引擎核心,它是发动机,负责接收和响应客户端请求,负责驱动业务handler的运行,负责服务器内部定时任务的执行

当一个请求到来时,ioloop读取这个请求解包成一个http请求对象,找到该套接字上对应app的路由表,通过请求对象的url查询路由表中挂接的handler,然后执行handler。handler方法执行后一般会返回一个对象,ioloop负责将对象包装成http响应对象序列化发送给客户端。

同一个ioloop实例运行在一个单线程环境下。

关于ioloop:

tornado.ioloop — Main event loop
An I/O event loop for non-blocking sockets.(非阻塞套接字接口)
IOLoop is a wrapper around the asyncio event loop. (异步事件循环)

参考:

https://tornado-zh.readthedocs.io/zh/latest/guide/async.html

https://zhuanlan.zhihu.com/p/37382503

https://www.tornadoweb.org/en/stable/ioloop.html

关于Python Web框架——Tornado的更多相关文章

  1. Python Web框架 tornado 异步原理

    Python Web框架 tornado 异步原理 参考:http://www.jb51.net/article/64747.htm 待整理

  2. Python web框架 Tornado异步非阻塞

    Python web框架 Tornado异步非阻塞   异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案: ...

  3. 异步非阻塞IO的Python Web框架--Tornado

    Tornado的全称是Torado Web Server,从名字上就可知它可用作Web服务器,但同时它也是一个Python Web的开发框架.最初是在FriendFeed公司的网站上使用,FaceBo ...

  4. Python web框架——Tornado

    Tornado是一个Python Web框架和异步网络库,最初由FriendFeed开发.通过使用非阻塞网络I / O,Tornado可以扩展到数万个开放连接,使其成为需要长时间连接每个用户的长轮询, ...

  5. Python Web框架Tornado的异步处理代码演示样例

    1. What is Tornado Tornado是一个轻量级但高性能的Python web框架,与还有一个流行的Python web框架Django相比.tornado不提供操作数据库的ORM接口 ...

  6. Python web框架 Tornado(三)自定义session组件

    我们在学习Django框架的过程中,内部封装了session组件,以方便于我们使用进行验证.但是Tornado框架是没有session的,所以如果想使用session的话,就需要我们自己定制相对应的组 ...

  7. Python web框架 Tornado(一)基础学习

    概述 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...

  8. Python web框架 Tornado(二)异步非阻塞

    异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案:多线程,多进程 异步非阻塞(存在IO请求): Torna ...

  9. Django,Flask,Tornado三大框架对比,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Django 与 Tornado 各自的优缺点Django优点: 大和全(重量级框架)自带orm,template,view 需要的功能也可以去找第三方的app注重高效开发全自动化的管理后台(只需要使 ...

随机推荐

  1. 系统分析与设计结对项目——WordCount

    结对项目完成WordCount 合作者:201631062507  201631062526(学号) 代码地址:https://gitee.com/WordCountMC/WordCountTeam ...

  2. SQL的左连接与右链接

    1.准备工作 Oracle  外连接(OUTER JOIN)包括以下: 左外连接(左边的表不加限制) 右外连接(右边的表不加限制) 全外连接(左右两表都不加限制) 对应SQL:LEFT/RIGHT/F ...

  3. 8、组件注册-@Import-给容器中快速导入一个组件

    8.组件注册-@Import-给容器中快速导入一个组件 8.1 给容器中注册组建的方式 包扫描+组建标注注解(@Controller.@Service.@Repository.@Component)[ ...

  4. linux下解决安装jdk后‘环境变量’不生效的问题

    1.是否需要配置环境变量,主要看java -version 显示的版本是否为你期望的版本: (1)不需要配置环境变量的情况 使用java -version查看,版本显示正好是你刚刚安装的版本,这一般为 ...

  5. JVM相关面试

    来源:老码农 ,lingsui.github.io/2018/03/30/JVM面试题/   1.你知道哪些或者你们线上使⽤什么GC策略?它有什么优势,适⽤于什么场景? 参考 触发JVM进行Full ...

  6. Python—“helloworld”

    接触一门计算机新语言,第一件事就是要准备好一个编译器用来打代码. 网上很多环境搭建的方法,具体参照https://www.runoob.com/python/python-install.html 由 ...

  7. web软件测试基础系统测试简化理论

    系统测试点主要如下 1.系统测试基础-2.测试对象与测试级别-3.系统测试类型-4.系统测试方法-5.系统测试之软件测试质量. 1.系统测试:是尽可能彻底地检查出程序中的错误,提高软件系统的可靠性. ...

  8. NSString的导出

    字符串的导出,写到某个文件中去 void stringExport(){ NSString *str=@"123456"; //if file not exist will not ...

  9. iTerm2 半透明颜色主题与字体配置

    下载iTerm2https://www.iterm2.com/ 安装. 下载这个主题https://raw.githubusercontent.com/mbadolato/iTerm2-Color-S ...

  10. Ubuntu14.04 gzip failed file too large

    使用gzip解压一个oracle rman备份集时报错:File too large.gizp -d cosp_db_full.tar.gzgzip: cosp_db_full.tar:File to ...