1、初识tornado

什么是tornado: 全称为Tomado Web Server是一种Web服务器软件的开源版本。

特点:作为Web框架,是个轻量级的Web框架,类似于另一个Python Web框架爱Web.py,其用于异步非阻塞IO的处理方式;作为Web服务器,Tomado有较为出色的抗负载能力,官方用nginx反向代理的方式部署Tomado 和其他的Python Web应用框架进行对比,结果最大浏览量超过第二名近40%。

使用场景:用户量达,高并发(12306、web游戏服务器);大量的HTTP持久连接,即a)使用同一个TCP连接来发送和接收多个HTTP请求/应答而不是为每一个新的请求/应答打开新的连接的方法b)对于HTTP1.0,可以在其请求头的包(header)中添加Connection:Keep-Alive=  c)对于HTTP1.1,所有的连接默认都是持久连接。

C10K:上面的高并发问题,通常使用C10K这一概念进行描述。C10K---Concurrently handling ten thousand connections,即并发10000个连接。对于单台服务器而言,根本无法承担,而采用多台服务器分布式又意味着高昂的成本。

性能:Tomado再设计之初就考虑到了性能因素,旨在解决C10K问题,这样的设计使得其称为一个拥有非常高性能的解决方案(服务器与框架的集合体)。

 

Django和tornado的对比:

 

 

 

2、tornado的安装

Tornado应该运行在类Unix平台,在线上部署时为了最佳的性能和扩展性。进退间linux和DSB(因为充分利用Linux的epoll工具和BSD的kqueue工具,是Tornado不依靠多进程/多线程而达到高性能的原因)。

对于MAC OS系统,虽然也是衍生自BSD并且支持kqueue,但是其网络性能通常不太给力,因此只推荐开发使用。

对于Windows,Tornado官方并没有提供配置支持,但是也可以运行起来,不过仅推荐在开发中使用。

 

3、第一个tornado程序

[代码3-1]

 1 import tornado.web
 2 import tornado.ioloop
 3 
 4 # 类比于Django中的视图,即一个业务处理类
 5 class IndexHandler(tornado.web.RequestHandler):
 6     # 只能处理get请求
 7     def get(self, *args, **kwargs):
 8         # write对应http请求的方法,给浏览器响应信息
 9         self.write("test tornado")
10 
11 
12 if __name__ == '__main__':
13     # 实例化一个app对象
14     # Applicaiton:是tornado web框架的核心应用类,是与服务器对应的接口
15     # 里面保存了路由映射表,有一个listen方法,是用来创建一个http服务器的实例
16     # 并绑定了端口(监听端口),注意此时并没有开启监听
17     app = tornado.web.Application([
18         (r"/", IndexHandler)
19     ]
20     )
21     app.listen(8000)
22     # IOLoop.current():返回当前线程的IOLoop实例
23     # IOLoop.start():启动IOLoop实例的I/O循环,同时开启了监听
24     tornado.ioloop.IOLoop.current().start()

 

[代码3-2]

 1 import tornado.web
 2 import tornado.ioloop
 3 import tornado.httpserver
 4 
 5 # 类比于Django中的视图,即一个业务处理类
 6 class IndexHandler(tornado.web.RequestHandler):
 7     # 只能处理get请求
 8     def get(self, *args, **kwargs):
 9         # write对应http请求的方法,给浏览器响应信息
10         self.write("test tornado")
11 
12 
13 if __name__ == '__main__':
14     app = tornado.web.Application([
15         (r"/", IndexHandler)
16     ]
17     )
18     httpServer = tornado.httpserver.HTTPServer(app)
19     # 将服务器绑定到指定的端口
20     httpServer.bind(8000)
21     # 参数1表示此时只启动一个进程,默认也是开启一个进程,值大于0,表示创建多个进程,
22     # 值为None或者小于等于0,将开启对应cpu个数的进程
23     httpServer.start(1)
24     tornado.ioloop.IOLoop.current().start()

 

上述两份代码是等同的,代码3-2可以用于创建多进程。

另外需要注意的是:

(1)app.listen()方法只能在单个进程中使用。

(2)虽然tornado给我们提供了一次性启动多个进程的方式[代码3-2],但是由于一些原因,不建议使用上面的方式启动多进程,而是采用手动的方式。具体的原因如下:

每个子进程都会从父进程中复制一份IOLoop的实例,如果在创建子进程前修改了IOLoop,会影响所有的子进程。

所有的子进程douyou一个命令启动的,无法做到在不停止服务的情况下修改代码。

所有进程共享一个端口,想要分别监控很困难。

 

4、tornado的options模块

用来定义options选项变量的方法,定义的变量可以在全局的tornado.options.options中获取使用,主要的传入参数:

  • name 选项变量名,须保证全局唯一性,否则会报“Option 'xxx' already defined in ...”的错误;
  • default 选项变量的默认值,如不传默认为None;
  • type 选项变量的类型,从命令行或配置文件导入参数的时候tornado会根据这个类型转换输入的值,转换不成功时会报错,可以是str、float、int、datetime、timedelta中的某个,若未设置则根据default的值自动推断,若default也未设置,那么不再进行转换。可以通过利用设置type类型字段来过滤不正确的输入。
  • multiple 选项变量的值是否可以为多个,布尔类型,默认值为False,如果multiple为True,那么设置选项变量时值与值之间用英文逗号分隔,而选项变量则是一个list列表(若默认值和输入均未设置,则为空列表[])。
  • help 选项变量的帮助提示信息,在命令行启动tornado时,通过加入命令行参数 --help 可以查看所有选项变量的信息(注意,代码中需要加入tornado.options.parse_command_line())。

tornado.options.options

全局的options对象,所有定义的选项变量都会作为该对象的属性。

tornado.options.parse_command_line()

转换命令行参数,并将转换后的值对应的设置到全局options对象相关属性上。追加命令行参数的方式是--myoption=myvalue

新建opt.py,我们用代码来看一下如何使用:

 1 # coding:utf-8
 2 
 3 import tornado.web
 4 import tornado.ioloop
 5 import tornado.httpserver
 6 import tornado.options # 新导入的options模块
 7 
 8 tornado.options.define("port", default=8000, type=int, help="run server on the given port.") # 定义服务器监听端口选项
 9 tornado.options.define("itcast", default=[], type=str, multiple=True, help="itcast subjects.") # 无意义,演示多值情况
10 
11 class IndexHandler(tornado.web.RequestHandler):
12     """主路由处理类"""
13     def get(self):
14         """对应http的get请求方式"""
15         self.write("Hello Itcast!")
16 
17 if __name__ == "__main__":
18     tornado.options.parse_command_line()
19     print tornado.options.options.itcast # 输出多值选项
20     app = tornado.web.Application([
21         (r"/", IndexHandler),
22     ])
23     http_server = tornado.httpserver.HTTPServer(app)
24     http_server.listen(tornado.options.options.port)
25     tornado.ioloop.IOLoop.current().start()

执行如下命令开启程序:

$ python opt.py --port=9000 --itcast=python,c++,java,php,ios

 

posted on 2020-04-25 11:49  我得去图书馆了  阅读(348)  评论(0编辑  收藏  举报