Tornado框架入门教程_tornado菜鸟教程_Python 学习者的博客-CSDN博客


本站和网页 https://blog.csdn.net/sinat_38682860/article/details/80509864 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

Tornado框架入门教程_tornado菜鸟教程_Python 学习者的博客-CSDN博客
Tornado框架入门教程
Python 学习者
于 2018-05-30 14:42:48 发布
22028
收藏
44
分类专栏:
python
文章标签:
python
Tornado
原文链接:https://zhuanlan.zhihu.com/p/37382503
版权
python
专栏收录该内容
1472 篇文章
257 订阅
订阅专栏
Tornado在知乎广为使用,当你用Chrome打开网页版本的知乎,使用开发者工具仔细观察Network里面的请求,就会发现有一个特别的状态码为101的请求,它是用浏览器的websocket技术和后端服务器建立了长连接用来接收服务器主动推送过来的通知消息。这里的后端服务器使用的就是tornado服务器。Tornado服务器除了可以提供websocket服务外,还可以提供长连接服务,HTTP短链接服务,UDP服务等。Tornado服务器由facebook开源,在掌阅的后端也广为使用。
这样一个强大的Tornado框架,究竟该如何使用,本文将带领读者循序渐进深入学习tornado作为web服务器的基础使用。
Hello, World
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
这是官方提供了Hello, World实例,执行python hello.py,打开浏览器访问http://localhost:8888/就可以看到服务器的正常输出Hello, world。
一个普通的tornado web服务器通常由四大组件组成。
ioloop实例,它是全局的tornado事件循环,是服务器的引擎核心,示例中tornado.ioloop.IOLoop.current()就是默认的tornado ioloop实例。app实例,它代表着一个完成的后端app,它会挂接一个服务端套接字端口对外提供服务。一个ioloop实例里面可以有多个app实例,示例中只有1个,实际上可以允许多个,不过一般几乎不会使用多个。handler类,它代表着业务逻辑,我们进行服务端开发时就是编写一堆一堆的handler用来服务客户端请求。路由表,它将指定的url规则和handler挂接起来,形成一个路由映射表。当请求到来时,根据请求的访问url查询路由映射表来找到相应的业务handler。
这四大组件的关系是,一个ioloop包含多个app(管理多个服务端口),一个app包含一个路由表,一个路由表包含多个handler。ioloop是服务的引擎核心,它是发动机,负责接收和响应客户端请求,负责驱动业务handler的运行,负责服务器内部定时任务的执行。
当一个请求到来时,ioloop读取这个请求解包成一个http请求对象,找到该套接字上对应app的路由表,通过请求对象的url查询路由表中挂接的handler,然后执行handler。handler方法执行后一般会返回一个对象,ioloop负责将对象包装成http响应对象序列化发送给客户端。
同一个ioloop实例运行在一个单线程环境下。
阶乘服务
下面我们编写一个正常的web服务器,它将提供阶乘服务。也就是帮我们计算n!的值。服务器会提供阶乘的缓存,已经计算过的就存起来,下次就不用重新计算了。使用Python的好处就是,我们不用当心阶乘的计算结果会溢出,Python的整数可以无限大。
# fact.py
import tornado.ioloop
import tornado.web
class FactorialService(object): # 定义一个阶乘服务对象
def __init__(self):
self.cache = {} # 用字典记录已经计算过的阶乘
def calc(self, n):
if n in self.cache: # 如果有直接返回
return self.cache[n]
s = 1
for i in range(1, n):
s *= i
self.cache[n] = s # 缓存起来
return s
class FactorialHandler(tornado.web.RequestHandler):
service = FactorialService() # new出阶乘服务对象
def get(self):
n = int(self.get_argument("n")) # 获取url的参数值
self.write(str(self.service.calc(n))) # 使用阶乘服务
def make_app():
return tornado.web.Application([
(r"/fact", FactorialHandler), # 注册路由
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
执行python fact.py ,打开浏览器,键入http://localhost:8888/fact?n=50,可以看到浏览器输出了608281864034267560872252163321295376887552831379210240000000000,如果我们不提供n参数,访问http://localhost:8888/fact,可以看到浏览器输出了400: Bad Request,告诉你请求错误,也就是参数少了一个。
使用Redis -- 上面的例子是将缓存存在本地内存中,如果换一个端口再其一个阶乘服务,通过这个新端口去访问的话,对于每个n,它都需要重新计算一遍,因为本地内存是无法跨进程跨机器共享的。
所以这个例子,我们将使用Redis来缓存计算结果,这样就可以完全避免重复计算。另外我们将不在返回纯文本,而是返回一个json,同时在响应里增加字段来说名本次计算来源于缓存还是事实计算出来的。另外我们提供默认参数,如果客户端没有提供n,那就默认n=1。
import json
import redis
import tornado.ioloop
import tornado.web
class FactorialService(object):
def __init__(self):
self.cache = redis.StrictRedis("localhost", 6379) # 缓存换成redis了
self.key = "factorials"
def calc(self, n):
s = self.cache.hget(self.key, str(n)) # 用hash结构保存计算结果
if s:
return int(s), True
s = 1
for i in range(1, n):
s *= i
self.cache.hset(self.key, str(n), str(s)) # 保存结果
return s, False
class FactorialHandler(tornado.web.RequestHandler):
service = FactorialService()
def get(self):
n = int(self.get_argument("n") or 1) # 参数默认值
fact, cached = self.service.calc(n)
result = {
"n": n,
"fact": fact,
"cached": cached
self.set_header("Content-Type", "application/json; charset=UTF-8")
self.write(json.dumps(result))
def make_app():
return tornado.web.Application([
(r"/fact", FactorialHandler),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
当我们再次访问http://localhost:8888/fact?n=50,可以看到浏览器输出如下{"cached": false, "fact": 608281864034267560872252163321295376887552831379210240000000000, "n": 50} ,再刷新一下,浏览器输出{"cached": true, "fact": 608281864034267560872252163321295376887552831379210240000000000, "n": 50},可以看到cached字段由true编程了false,表明缓存确实已经保存了计算的结果。我们重启一下进程, 再次访问这个连接,观察浏览器输出,可以发现结果的cached依旧等于true。说明缓存结果不再是存在本地内存中了。
圆周率计算服务 -- 接下来我们再增加一个服务,计算圆周率,圆周率的计算公式有很多种,我们用它最简单的。
我们在服务里提供一个参数n,作为圆周率的精度指标,n越大,圆周率计算越准确,同样我们也将计算结果缓存到Redis服务器中,避免重复计算。
# pi.py
import json
import math
import redis
import tornado.ioloop
import tornado.web
class FactorialService(object):
def __init__(self, cache):
self.cache = cache
self.key = "factorials"
def calc(self, n):
s = self.cache.hget(self.key, str(n))
if s:
return int(s), True
s = 1
for i in range(1, n):
s *= i
self.cache.hset(self.key, str(n), str(s))
return s, False
class PiService(object):
def __init__(self, cache):
self.cache = cache
self.key = "pis"
def calc(self, n):
s = self.cache.hget(self.key, str(n))
if s:
return float(s), True
s = 0.0
for i in range(n):
s += 1.0/(2*i+1)/(2*i+1)
s = math.sqrt(s*8)
self.cache.hset(self.key, str(n), str(s))
return s, False
class FactorialHandler(tornado.web.RequestHandler):
def initialize(self, factorial):
self.factorial = factorial
def get(self):
n = int(self.get_argument("n") or 1)
fact, cached = self.factorial.calc(n)
result = {
"n": n,
"fact": fact,
"cached": cached
self.set_header("Content-Type", "application/json; charset=UTF-8")
self.write(json.dumps(result))
class PiHandler(tornado.web.RequestHandler):
def initialize(self, pi):
self.pi = pi
def get(self):
n = int(self.get_argument("n") or 1)
pi, cached = self.pi.calc(n)
result = {
"n": n,
"pi": pi,
"cached": cached
self.set_header("Content-Type", "application/json; charset=UTF-8")
self.write(json.dumps(result))
def make_app():
cache = redis.StrictRedis("localhost", 6379)
factorial = FactorialService(cache)
pi = PiService(cache)
return tornado.web.Application([
(r"/fact", FactorialHandler, {"factorial": factorial}),
(r"/pi", PiHandler, {"pi": pi}),
])
if __name__ == "__main__":
app = make_app()
app.listen(8888)
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},这个值已经非常接近圆周率了。
更多Python视频、源码、资料加群531509025免费获取
转载至:https://zhuanlan.zhihu.com/p/37382503
向“C知道”追问
Python 学习者
关注
关注
19
点赞
44
收藏
觉得还不错?
一键收藏
知道了
评论
Tornado框架入门教程
Tornado在知乎广为使用,当你用Chrome打开网页版本的知乎,使用开发者工具仔细观察Network里面的请求,就会发现有一个特别的状态码为101的请求,它是用浏览器的websocket技术和后端服务器建立了长连接用来接收服务器主动推送过来的通知消息。这里的后端服务器使用的就是tornado服务器。Tornado服务器除了可以提供websocket服务外,还可以提供长连接服务,HTTP短链接服...
复制链接
扫一扫
专栏目录
千锋教育 tornado网课笔记
02-11
千锋教育 python基础教程,tornado网课笔记(思维导图)
tornado-redis:简单的异步 Tornado-redis 连接器
06-11
龙卷风-redis
简单的异步 Tornado-redis 连接器
去做:
处理与 ioloop.WRITE 的连接
处理第二次和更多读取操作
4 条评论
您还未登录,请先
登录
后发表或查看评论
Python中的Web框架有哪些?
2301_78263023的博客
06-07
658
Flask:Flask是一个轻量级的Web框架,它提供了基础架构和灵活性,允许你以自己的方式构建Web应用程序。Django:Django是最流行的Python Web框架之一,它提供了完整的Web应用程序开发工具集,包括ORM、Forms、Admin后台、缓存等。CherryPy:CherryPy是一个Python Web框架,它提供了丰富的功能,包括路由、模板、插件等,同时也是一个高效、可靠的Web服务器。Bottle:Bottle是一个小型的Web框架,它设计简单并且易于使用和扩展。
试玩python的web框架 flask、fastapi、tornado、django
最新发布
MJ的博客
07-14
1712
IDEA连接远程解释器,本地代码编辑无法代码提示。
tornado-redis入门
y355356475的博客
07-20
585
tornado-redis github 地址:https://github.com/leporo/tornado-redis
介绍
tornado-redis 包,一个 tornado 可用的异步 redis client。但已不在维护。
tornado-redis连接数据库
1.普通连接(未使用连接池池)
import tornadoredis
c = tornadoredis.Client(host="127.0.0.1",port=6379)
# 测试是否连接成功,写一个key,并查看red
实习手册七(Python基于Tornado框架的接口响应服务)使用Redis来缓存数据
weixin_58292326的博客
07-29
356
在Tornado中使用redis来进行数据的缓存
tornado-redis的使用
weixin_43620243的博客
01-29
1844
因为tornado-redis比较旧了,所以配套的tornado也得比较旧,最高版本是tornado 4.5.3,5.x.x上以的版本会出现以下错误:
ERROR:tornado.application:Uncaught exception GET / (127.0.0.1)
HTTPServerRequest(protocol='http', host='127.0.0.1:8888', met...
tornado
用代码描述我眼中的世界!
04-23
1万+
引言回想Django的部署方式以Django为代表的python web应用部署时采用wsgi协议与服务器对接(被服务器托管),而这类服务器通常都是基于多线程的,也就是说每一个网络请求服务器都会有一个对应的线程来用web应用(如Django)进行处理。考虑两类应用场景用户量大,高并发如秒杀抢购、双十一某宝购物、春节抢火车票大量的HTTP持久连接使用同一个TCP连接来发送和接收多个HTTP请求/应答...
tornado基本使用一
weixin_30809173的博客
07-12
117
一、tornado web程序编写思路
1. 创建web应用实例对象,第一个初始化参数为路由映射列表
2. 定义实现路由映射列表中的handler类
3. 创建服务器实例, 绑定服务器端口
4. 启动当前线程的IOLoop
二、tornado.web
1.RequestHandler:封装了对应一个请求的所有信息和方法,write(响应信息)就是写响应信息的一个方法;...
tornado基本使用
yutu75的博客
01-18
1356
Tornado
文档:https://tornado-zh-cn.readthedocs.io/zh_CN/latest/
github:https://github.com/tornadoweb/tornado
介绍
Tornado是使用Python开发的全栈式(full-stack)Web框架和异步网络库,最早由4名Google前软件工程师(布雷特·泰勒)2007创办的Friendfeed(一个社交聚合网站)开发而来的。通过使用非阻塞IO,Tornado可以处理数以万计的开放连接,是long polli
python tornado 集成redis消息订阅的异步任务之后tornado主程序无法启动
zoeou的博客
04-26
336
当使用redis消息订阅的异步任务之后,tornado 主程序无法启动
使用CacheQueue3才能解决问题,具体原因后面再细看源码,
CacheQueue1
import redis
import logging
class CacheQueue(object):
def __init__(self, host, port, cache_update_path):
...
搭建Tornado Https服务器之前言介绍(1)
江湖人称王某人的程序员
02-14
251
一、简单的介绍
我是一名新手,没有系统学习的背景,这次搭建过程是循序渐进的过程,我们从最简单的一步一步开始去搭建Api服务器,包括涉及到Mysql数据库、Postgresql数据库、ORM模式、Https服务器、Postman工具使用、Http服务器、Nginx反向代理和负载均衡、Jwt权限验证等等。同时还会带着学习使用腾讯云短信和七牛云的对象存储辅助我们去做一下高级的操作。
...
python 3.8 module docs秒退_解决Python3.8运行tornado项目报NotImplementedError错误
weixin_39524882的博客
12-10
269
今天拉了一个使用了tornado的项目在本地跑,按照源码作者的步骤配置完,运行,直接报错了,要求环境Python3.6+,我装的是Python3.8,理论上应该直接正常运行的,报错信息:Traceback (most recent call last):File "ice_server.py", line 150, in RunServer.run_server(port=p, host=h)Fi...
Python菜鸟入门基础篇,零基础小白必看
m0_70486148的博客
04-17
243
Python迅猛发展背后的一个主要驱动力是它学习起来相当容易,使用起来功能强大。对于初学者来说,像C/C++这样有难度的编程语言,不熟悉语法的人都会敬而远之,所以Python显得非常有吸引力。
【Tornado】Tornado入门教程
HNUJSY
04-12
5681
Tornado
特点:
非阻塞式和基于Linux的Epoll(UNIX为kqueue)的异步网络IO
异步非阻塞IO处理方式,单进程单线程异步IO的网络模型,可以编写异步非阻塞的程序
非常适合开发长轮询、WebSocket和需要与每个用户建立持久连接的应用
既是WebServer也是WebFramework
结构:
Web 框架 (包括用来创建 Web 应用程序的 RequestHandler 类, 还有很多其它支持的类).
HTTP 客户端和服务器的实现 (HTTPServer 和 AsyncHT
tornado 异步客户端tornado-redis的使用
郭小郭的专栏
03-30
8694
tornado 可用的异步 redis 客户端,使用很方便。
下面的例子介绍了怎么使用管道设置值和读取值的简单操作#coding:utf-8
import tornadoredis
import tornado.httpserver
import tornado.web
import tornado.ioloop
import tornado.gen#设置连接池
CONNECTION_POOL
Python Tornado 中文教程
05-14
FriendFeed使用了一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器。其应用程序使用的 Web 框架看起来有些像 web.py 或者 Google 的 webapp, 不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。
Tornado 就是我们在 FriendFeed 的 Web 服务器及其常用工具的开源版本。Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。(关于如何扩容 服务器,以处理数以千计的客户端的连接的问题,请参阅 The C10K problem )
一个tornado项目的大体结构
热门推荐
一名普通码农的菜地
11-03
1万+
主要结构下面进行解释。App目录职责app用于存放程序需要运行的逻辑。
如下:
common里面是通用的函数及方法。
business用于存放业务逻辑
dal专门用于数据库读写
db是数据库操作辅助类
modules用于存放tornado的handler,即页面控制器。
viewhelper是用于页面的一些辅助方法,譬如,页面上面需要裁剪字符串,需要获取通用页脚的文章数据,需要获取
tornado websocket+redis订阅推送的实现
零渡的博客
02-22
1402
整整踏了一周的坑,终于算是填上了,说到底还是tornado的框架不太成熟,而且各版本还存在很大的差异,先说我的环境
python==3.7
tornado==4.1
用到tornado-redis,非常好用的一个包
from __future__ import print_function
import json
import tornado.httpserver
import ...
帮我用python 的tornado写一个mmorpg的服务端基础框架
03-11
好的,我可以回答这个问题。使用 Python 的 Tornado 框架可以很好地搭建 MMORPG 的服务端基础框架。需要注意的是,MMORPG 的服务端需要处理大量的并发请求,因此需要使用异步编程模型来提高性能。同时,还需要考虑数据存储、安全性等方面的问题。如果您需要更详细的信息,可以参考 Tornado 官方文档或者相关的教程。
“相关推荐”对你有帮助么?
非常没帮助
没帮助
一般
有帮助
非常有帮助
提交
Python 学习者
CSDN认证博客专家
CSDN认证企业博客
码龄6年
暂无认证
761
原创
8705
周排名
331
总排名
958万+
访问
等级
7万+
积分
7249
粉丝
6970
获赞
997
评论
3万+
收藏
私信
关注
热门文章
吐血总结!50道Python面试题集锦(附答案)
314065
Python Flask Web 框架入门
177707
python自测100题
113976
python读写、创建文件、文件夹等等
111067
Python中的lambda函数
106922
分类专栏
python
1472篇
程序员
22篇
机器学习
12篇
29篇
框架
9篇
深度学习
3篇
爬虫
18篇
最新评论
python线程互斥锁递归锁死锁
yuanymnl:
第一个代码我在vscode上运行是0啊,这个是不是环境的问题?python3.11 的解释器好像都是0。
python两种获取剪贴板内容的方法
十四不高兴了:
这格式写的真的好,小白不建议学
python 字符串操作list[::-1]的几种用法
eric20100:
4.不对吧
list = 'abcdef'
print(list[1:0:-1])
#输出
fedcb
3个方式教你终止python代码运行
m0_73542339:
siprit
Python的re模块,正则表达式用法详解,正则表达式中括号的用法
辅助杀手:
码住了
您愿意向朋友推荐“博客详情页”吗?
强烈不推荐
不推荐
一般般
推荐
强烈推荐
提交
最新文章
一个简单爬虫案例,用正则采集小说网站
推荐一个好用的Python词云展示库-wordcloud
python中几个有趣的函数和推导式
2023年13篇
2022年25篇
2021年426篇
2020年838篇
2019年1639篇
2018年411篇
2017年19篇
目录
目录
分类专栏
python
1472篇
程序员
22篇
机器学习
12篇
29篇
框架
9篇
深度学习
3篇
爬虫
18篇
目录
评论 4
被折叠的 条评论
为什么被折叠?
到【灌水乐园】发言
查看更多评论
添加红包
祝福语
请填写红包祝福语或标题
红包数量
红包个数最小为10个
红包总金额
红包金额最低5元
余额支付
当前余额3.43元
前往充值 >
需支付:10.00元
取消
确定
下一步
知道了
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝
规则
hope_wisdom 发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额
抵扣说明:
1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。
余额充值