标签:sed port inf bsp 实例 cpu 局限 默认 pre
Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架。
特点:
Tornado框架和服务器一起组成一个WSGI的全栈替代品。单独在WSGI容器中使用tornado网络框架或者tornaod http服务器,有一定的局限性,为了最大化的利用tornado的性能,推荐同时使用tornaod的网络框架和HTTP服务器。
Django
Django是走大而全的方向,注重的是高效开发,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。
Django提供的方便,也意味着Django内置的ORM跟框架内的其他模块耦合程度高,应用程序必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的便利。
session功能
后台管理
ORM
Tornado
Tornado走的是少而精的方向,注重的是性能优越,它最出名的是异步非阻塞的设计方式。
HTTP服务器
异步编程
WebSockets
新建一个"hello.py"文件,代码如下:
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
tornado的基础web框架模块
(1)RequestHandler
封装了对应一个请求的所有信息和方法,write(响应信息)就是写响应信息的一个方法;对应每一种http请求方式(get、post等),把对应的处理逻辑写进同名的成员方法中(如对应get请求方式,就将对应的处理逻辑写在get()方法中),当没有对应请求方式的成员方法时,会返回“405: Method Not Allowed”错误。
(2)Application
Tornado Web框架的核心应用类,是与服务器对接的接口,里面保存了路由信息表,其初始化接收的第一个参数就是一个路由信息映射元组的列表;其listen(端口)方法用来创建一个http服务器实例,并绑定到给定端口(注意:此时服务器并未开启监听)。
tornado的核心io循环模块,封装了Linux的epoll和BSD的kqueue,tornado高性能的基石。 以Linux的epoll为例,其原理如下图:
(3)IOLoop.current()
(4)IOLoop.start()
启动IOLoop实例的I/O循环,同时服务器监听被打开。
上面我们说tornado.web.Application.listen()(示例代码中的app.listen(8888))的方法中,创建了一个http服务器示例并绑定到给定端口,注意此时还没有监听,那么具体它是怎么实现的呢?看下面代码
import tornado.ioloop import tornado.web import tornado.httpserver # 新引入模块 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) # ----------------修改的地方--------------------- http_server = tornado.httpserver.HTTPServer(app) http_server.bind(8888)
http_server.start(1) # 1 表示开启一个进程
# -------------------------------------- tornado.ioloop.IOLoop.current().start()
在这一步,我们引入了tornado.httpserver模块,顾名思义,它就是tornado的HTTP服务器实现。
我们创建了一个HTTP服务器实例http_server,因为服务器要服务于我们刚刚建立的web应用,将接收到的客户端请求通过web应用中的路由映射表引导到对应的handler中,所以在构建http_server对象的时候需要传出web应用对象app。http_server.listen(8888)将服务器绑定到8888端口。
实际上一版代码中app.listen(8888)正是对这一过程的简写。
我们刚刚实现的都是单进程。 如果想开启多进程 http_server.start(num_processes=1)方法指定开启几个进程,参数num_processes默认值为1,即默认仅开启一个进程;如果num_processes为None或者<=0,则自动根据机器硬件的cpu核芯数创建同等数目的子进程;如果num_processes>0,则创建num_processes个子进程。 虽然tornado给我们提供了一次开启多个进程的方法,但是由于: 每个子进程都会从父进程中复制一份IOLoop实例,如过在创建子进程前我们的代码动了IOLoop实例,那么会影响到每一个子进程,势必会干扰到子进程IOLoop的工作; 所有进程是由一个命令一次开启的,也就无法做到在不停服务的情况下更新代码; 所有进程共享同一个端口,想要分别单独监控每一个进程就很困难。 不建议使用这种多进程的方式,而是手动开启多个进程,并且绑定不同的端口。
在前面的示例中我们都是将服务端口的参数写死在程序中,很不灵活。
tornado为我们提供了一个便捷的工具,tornado.options模块——全局参数定义、存储、转换。
用来定义options选项变量的方法,定义的变量可以在全局的tornado.options.options中获取使用,传入参数:
全局的options对象,所有定义的选项变量都会作为该对象的属性。
转换命令行参数,并将转换后的值对应的设置到全局options对象相关属性上。追加命令行参数的方式是--myoption=myvalue
新建opt.py,我们用代码来看一下如何使用:
import tornado.ioloop import tornado.web import tornado.httpserver import tornado.options # 新导入的options模块 tornado.options.define("port", default=8000, type=int, help="run server on the given port.") # 定义服务器监听端口选项 class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") def make_app(): return tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": tornado.options.parse_command_line() # 获取命令行参数 app = make_app() http_server = tornado.httpserver.HTTPServer(app) http_server.listen(tornado.options.options.port) tornado.ioloop.IOLoop.current().start()
执行如下命令开启程序:
python opt.py --port=9000
我们可以像 Django 中的 setting.py 一样,定义一个我们自己的配置文件,然后导入到当前文件目录。
通常的做法是在使用配置文件的时候,通常会新建一个python文件(如config.py),然后在里面直接定义python类型的变量(可以是字典类型);在需要配置文件参数的地方,将config.py作为模块导入,并使用其中的变量参数。
如config.py文件:
# conding:utf-8 # Redis配置 redis_options = { ‘redis_host‘:‘127.0.0.1‘, ‘redis_port‘:6379, ‘redis_pass‘:‘‘, } # Tornado app配置 settings = { ‘template_path‘: os.path.join(os.path.dirname(__file__), ‘templates‘), ‘static_path‘: os.path.join(os.path.dirname(__file__), ‘statics‘), ‘cookie_secret‘:‘0Q1AKOKTQHqaa+N80XhYW7KCGskOUE2snCW06UIxXgI=‘, ‘xsrf_cookies‘:False, ‘login_url‘:‘/login‘, ‘debug‘:True, } # 日志 log_path = os.path.join(os.path.dirname(__file__), ‘logs/log‘)
使用config.py的模块中导入config,如下:
# conding:utf-8 import tornado.web import config if __name__ = "__main__": app = tornado.web.Application([], **config.settings) ...
前面的学习中,我们在创建tornado.web.Application的对象时,传入了第一个参数——路由映射列表。实际上Application类的构造函数还接收很多关于tornado web应用的配置参数,在后面的学习中我们用到的地方会为大家介绍。
我们先来学习一个参数:
debug,设置tornado是否工作在调试模式,默认为False即工作在生产模式。当设置debug=True 后,tornado会工作在调试/开发模式,在此种模式下,tornado为方便我们开发而提供了几种特性:
使用debug参数的方法:
import tornado.web app = tornado.web.Application([], debug=True)
先前我们在构建路由映射列表的时候,使用的是二元元组,如:
[(r"/", IndexHandler),]
对于这个映射列表中的路由,实际上还可以传入多个信息,如:
[ (r"/", Indexhandler), (r"/cpp", ItcastHandler, {"subject":"c++"}), url(r"/python", ItcastHandler, {"subject":"python"}, name="python_url") ]
对于路由中的字典,会传入到对应的RequestHandler的initialize()方法中:
from tornado.web import RequestHandler class ItcastHandler(RequestHandler): def initialize(self, subject): self.subject = subject def get(self): self.write(self.subject)
对于路由中的name字段,注意此时不能再使用元组,而应使用tornado.web.url来构建。name是给该路由起一个名字,可以通过调用RequestHandler.reverse_url(name)来获取该名子对应的url。
import tornado.web import tornado.ioloop import tornado.httpserver import tornado.options from tornado.options import options, define from tornado.web import url, RequestHandler define("port", default=8888, type=int, help="run server on the given port.") class IndexHandler(RequestHandler): def get(self): python_url = self.reverse_url("python_url") self.write(‘<a href="%s">hello world</a>‘ % python_url) class ItcastHandler(RequestHandler): def initialize(self, subject): self.subject = subject def get(self): self.write(self.subject) def make_app(): return tornado.web.Application([ (r"/", Indexhandler), (r"/java", ItcastHandler, {"subject":"java"}), url(r"/python", ItcastHandler, {"subject":"python"}, name="python_url") ], debug=True) if __name__ == "__main__": tornado.options.parse_command_line() app = make_app() http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.current().start()
标签:sed port inf bsp 实例 cpu 局限 默认 pre
原文地址:https://www.cnblogs.com/linyuhong/p/10257726.html