Tornado是一个python Web框架和异步网络库,通过使用非阻塞网络I/O,Tornado可以扩展数以万计连接,非常适合长时间轮询。webSockets和其他需要与每个用户建立长期连接的应用程序。Tprnado走的说少而精的方向,注重的是性能优越 它最出名的说异步非阻塞的设计方式
I/O;分两类: 磁盘的读写 网络I/O
Tornado的特点: HTTP服务器 异步编程 Websockets
Tornado默认的是单进程
epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。
注重高效开发
全自动化的管理后台(只需要使用起ORM,做简单的定义,就能自动生成数据库结构,全功能的管理后台)
session功能
注重性能优越 速度快
解决高并发
异步非阻塞
websockets 长连接
内嵌了HTTP服务器
单线程的异步网络程序,默认启动时根据cpu数量运行多个实例,利用cpu多核的优势
IO 多路复用除了select,还有两种方式,poll和epoll,在windows下只支持select,而在linux中,这三个都有.epoll是性能最好的,select唯一的优点是多平台可以用,缺点是效率很差.poll是epoll和select的中间过渡,与select相比.poll可以监听的数量没有限制.epoll没有最大连接上限.另外监听机制也完全发生变化.select的机制是轮询(每个数据都检查一遍,即使找到有变化的也要继续检查),epoll的机制是用回调函数,哪个函数有变化,那个就调用这个回调函数.
多个客户端的连接才有IO多路复用.
select会轮询每个socket对象,如果socket对象是就绪状态就执行这个socket ,但是select会轮询每个socket,会浪费效率
epoll也会去询问,只会轮询一次,询问的时候给每一个socket对象绑定一个回调函数,如果socket对象是就绪状态,会就通知epoll,epoll在去调用这个socket函数.
// 引入需要的模块包
import tornado.web // tornado的基础web框架模块
import tornado.ioloop //ioloop内部是一个单线程多协程的模式 tornado的核心IO循环模块,封装了Liunx的epoll和BSD的kqueue,说tornado高效的基础。
//定义处理类
class IndexHandler(tornado.web.RequstHandler):
//get方法只能接收GET方式处理
def get(self,*args,**kwargs): // 对应http请求的方法,给浏览器响应信息
self.write(‘hello world’) // 向前端浏览器返回一串字符串
//设置路由
app = tornado.web.Application([ //application说tornado web框架的核心应用类,是与服务器对应的接口
(r’/’,IndexHandler)
])
//绑定端口号
app.listen(8000)
IOLoop.current(): 返回当前线程的IOLoop实例对象
IOLoop.start() : 启动IOLoop实例的I/O循环,同时开启了监听
tornado.ioloop.IOLoop.current().start() tornado.ioloop.IOLoop().instance().start() //两种写法是一样的
1 在程序启动阶段 第一步,获取配置文件,然后生成url映射(即:一个url对应一个XXRequestHandler,从而让XXRequstHandler来处理指定url发送的请求);第二步,创建服务器socket对象并添加到epoll中,第三步,创建无限循环取监听epoll
2 在接收并处理请求阶段第一步,接收客户端socket发送的请求(socket.accept),第二步,从请求中获取请求头信息,再然后根据请求头中的请求url去匹配某个XXRequstHandler,第三步,匹配成功的XXRequestHandler处理请求,第四步,将处理后的请求发送给客户端,第五步,关闭客户端socket.
self.get_argument() //获取参数
self.get_query_argment() //回去参数
self.write() 向浏览器返回一串字符串
app.listen(8000) 监听端口号 只能在单线程模式中使用.
app=tornado.web.Application([ (r’^ /’,IndexHandler ) ]) 这里是路由的匹配
tornado.ioloop.IOLoop.current().start() 开启程序
导入 tornado.httpserver模块
httpServer = tornado.httpserver.HTTPServer(app) 创建服务器对象并让对象与app进行关联
httpServer.bind(8000) 将服务器绑定得到指定的端口
httpServer.start(100) // 默认开启的是1个进程,如果想开启多个就写多个线程,写几个就启动几个线程, 如果值为None或小于0,默认开启对应硬件的cpu核数的线程
tornado.ioloop.IOLoop.current().start()虽然tornado给我们提供了一次启动多个进程的方式,但是由于一些问题,不建议使用上面的方式启动多线程,而是手动启动多个线程,并且还能绑定多个端口. 存在的问题有:
1 每个子进程都会从父进程中复制一份IOLoop的实例,如果在创建子进程前修改了IOLoop,会影响到所有的子进程
2 所有的进程都是由一个命令启动的,无法做到在不停止服务的情况在修改代码.
3 所有进程共享一个端口,想要分别监控很困难
tornado为我们提供了tornado.options模块,这个个模块的作用: 全局参数的定义 ,存储 转换.
基础方法与属性: tornado.options功能: 用来定义options选项变量的方法
tornado参数说明: name:选项变量名,必须保证其唯一性,否则会报’Option ‘xxx’ already define in …’
default: 设置选项变量的默认值,默认为None
type: 设置选项变量的类型,从命令行或配置文件导入参数时tornado会根据类型转换输入的值,转换不成会报错.可以str float int deatetime timedelta 如果没有设置type,会根据default的值进行转换.,如果default没有设置,就不进行转换
multiple: 设置选项变量是否可以为多个值,默认为False
tornado.options.options: 全局的options对象,所有定义的选项都会作为该对象的属性.
.获取参数的方法: tornado.optins.parse_command_line():作用:可以将命令行的参数转换到 tornado.options.options.port
命令行启动: python server04.py --port=9000 --list=good,nice,handsome,cool
不建议使用这个方式
tornado.options.parse_config_file(path) 从配置文件导入
需要创建一个名为config的普通文件
该配置文件只是一个普通config文件.书写格式仍然需要安装python的语法要求,不支持字典类型
需要创建一个名为config.py的普通文件.
options = {
‘port’:8080,
‘list’:[‘good’,‘nice’,‘handsome’]
}
当我们在代码中使用parse_command_line() 或者parse_config_file(path)方法时,tornado会默认开启logging模块功能,向终端输入一些打印信息
如果是配置文件在__name__=='main’的第一行tornado.options.options.logging=None 关闭日志