三. 线上部署的时候: 推荐使用 linux 平台或者 BSD 平台 原因: 因为tornado的高性能, 不是依赖于开启多个进程或者线程, 即便在单进程下保持高效, 是依赖于linux的epoll和BSD的Kqueue特别的高效 ps: 面试题: select poll epoll的区别? (*********************************) 1. 单个进程打开的文件描述符(fd文件句柄) select : 1024 poll : 稍微比select好一些, 没有限制 epoll : 没有限制 (1个g内存, 监听10W个端口) 2. 监听socket的方式: select : 轮询, 一个一个的检查, 看有没有活跃, 当线性增加socket的时候, 轮询的速度就会非常的耗时 poll : 对select稍微进行了优化, 只是修改了文件描述符,监听方式不变 epoll : 会将连接的socket注册到epoll中, 相当于socket的花名册, 如果有一个socket活跃了, 会回调一个函数, 通知epoll,赶紧过来处理 3. 内存空间拷贝方式: select : 需要将数据从内核态拷到用户态, 这个过程比较耗时 poll : 同上 epoll : 内存态数据和用户态数据时共享的 参考博客: https://www.cnblogs.com/jeakeven/p/5435916.html
四. 开始第一个tornado程序: ### tornado web 基础库 import tornado.web ### tornado IO 高效核心库, 里面封装了 linux 的epoll模块 import tornado.ioloop ''' 类似Django中的视图, CBV模式 ''' class IndexHandler(tornado.web.RequestHandler): ### 只能接受get请求 def get(self, *args, **kwargs): print('get......') ### django中的HttpResponse self.write('hello world!') ### 只能post请求 def post(self, *args, **kwargs): pass if __name__ == '__main__': ### Application 是 web 的一个核心库, 会实例化一个app实例 ### app 中会创建一个socket, 并且绑定一个端口 app = tornado.web.Application([ (r'/', IndexHandler), ]) ### 绑定一个端口, 并没有开始监听 app.listen(8001) ''' IOLoop.current() : 返回一个 IoLoop的实例 IOLoop.current().start() : 开始监听这个8001端口 ''' tornado.ioloop.IOLoop.current().start() 执行流程: 1. 绑定一个端口 2. 启动服务并开始监听 3. 客户端来了一个请求后 : 127.0.0.1:8001/ 4. 将请求转发给路由, 进行匹配 5. 然后寻找相对应的视图进行处理, 处理完成之后, 返回数据
五. HttpServer tornado.httpserver 实例化httperver, 并绑定端口 httpServer = tornado.httpserver.HTTPServer(app) httpServer.listen(8001) # 相当于 : app.listen(8001) 起多个进程: httpServer = tornado.httpserver.HTTPServer(app) httpServer.bind(8001) httpServer.start(num) : 取值: num > 0 : num=5: 开启5个进程 num < 0 : 取值根据电脑的cpu核数进行取值 num : 默认是1 但是不建议大家使用上述的方式: 1. 如果想改其中一个进程相关的代码, 需要将所有的进程全部停止掉 2. 监控不方便 (8000 -- 8005) 基于上面的原因, 推荐大家使用 app.listen(8000) 如果想要起多个端口进行监控, 做法: 起多个客户端, 然后运行服务端的相关代码
六. options: tornado.options: 常见的方法和属性: 方法 : tornado.options.define() 参数: name : 定义的变量名 default : 变量对应的默认值 , 如果不同过命令行或者配置文件传入这个变量对应的值的话, 就使用默认值 type: 类型 变量的类型 mutiple: 默认是False, 表示可以给变量传入多个值 属性: options 作用: 在define中定义的所有变量, options都可以通过.来获得 实例: define("port", default=8000, type=int, help='端口号') define('names', default=[], type=str, multiple=True) 需要加上 : tornado.options.parse_command_line() tornado.options.parse_config_file(path) : 会将config文件中的配置读入到options中 存在问题: 1. 不支持 Python 的语法格式 2. 不支持字典格式 推荐: 普通config.py: 将文件当成一个包 使用 代码: options = { "port" : 8003, "host" : '127.0.0.1', } 用的时候: import config port = config.options.port
七. 路由: a.获取get请求的参数值: self.get_query_argument() b.获取body请求的参数值: self.get_body_argument() c.在执行get/post请求之前, 都会执行 initialize() 方法 def initialize(self, height): self.height = height print('this is initialize') (r'/info/', InfoHandler, {"height":180}), d. 反转解析url: tornado.web.url(r'/index/', IndexHandler, name='index'), url = self.reverse_url("index")