关于Python Web框架——Tornado
2020-12-13 16:11
标签:协程库 客户 uid gateway ret 部分 content sqrt tor 关于Tornado的入门看这篇文章,写的非常好: https://zhuanlan.zhihu.com/p/37382503 Tornado 是一个Python web框架和异步网络库,使用非阻塞网络I/O。 Tornado可以被分为4个主要的部分: WSGI是Web Server Gateway Interface的缩写。 实时web功能需要为每个用户提供一个多数时间被闲置的长连接, 在传统的同步web服务器中,这意味着要为每个用户提供一个线程, 当然每个线程的开销都是很昂贵的. 为了尽量减少并发连接造成的开销,Tornado使用了一种单线程事件循环的方式. 这就意味着所有的应用代码都应该是异步非阻塞的, 因为在同一时间只有一个操作是有效的. 知乎和掌阅的后端应该采用了这个框架。 下面提供快速帮助回忆的代码:(圆周率计算服务)
因为两个Handler都需要用到redis,所以我们将redis单独抽出来,通过参数传递进去。另外Handler可以通过initialize函数传递参数,在注册路由的时候提供一个字典就可以传递任意参数了,字典的key要和参数名称对应。我们运行 下面来自知乎:(写的非常好) https://zhuanlan.zhihu.com/p/37382503 这是官方提供了Hello, World实例,执行 一个普通的tornado web服务器通常由四大组件组成。 这四大组件的关系是,一个ioloop包含多个app(管理多个服务端口),一个app包含一个路由表,一个路由表包含多个handler。ioloop是服务的引擎核心,它是发动机,负责接收和响应客户端请求,负责驱动业务handler的运行,负责服务器内部定时任务的执行。 当一个请求到来时,ioloop读取这个请求解包成一个http请求对象,找到该套接字上对应app的路由表,通过请求对象的url查询路由表中挂接的handler,然后执行handler。handler方法执行后一般会返回一个对象,ioloop负责将对象包装成http响应对象序列化发送给客户端。 同一个ioloop实例运行在一个单线程环境下。 关于ioloop: tornado.ioloop — Main 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 标签:协程库 客户 uid gateway ret 部分 content sqrt tor 原文地址:https://www.cnblogs.com/Flash-ylf/p/11618578.html
# 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()
python pi.py
,打开浏览器访问http://localhost:8888/pi?n=200
,可以看到浏览器输出{"cached": false, "pi": 3.1412743276, "n": 1000}
,这个值已经非常接近圆周率了。Tornado: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()
python hello.py
,打开浏览器访问http://localhost:8888/就可以看到服务器的正常输出Hello, world
。
tornado.ioloop.IOLoop.current()
就是默认的tornado ioloop实例。
An I/O event loop for non-blocking sockets.(非阻塞套接字接口)
IOLoop is a wrapper around the asyncio event loop. (异步事件循环)