Tornado 是一款高性能的 Web 服务器框架,是由 python 语言实现。

Tornado 本身是单线程的异步网络程序,它默认启动时,会根据 CPU 数量运行多个实例;充分利用 CPU 多核的优势。

Tornado 底层使用epoll系统调用,即使是在一台普通的机器上,Tornado 每秒也可以处理上千个请求,是一个高性能的 python 理想框架。

1. 安装

查看当前环境是否安装,如果有输出则已经安装 tornado,否则需要安装 tornado;目前最新的版本为 5.1.1。

$pip freeze | grep tornado
tornado==5.1
tornado-crontab==0.4.0

安装 tornado

$pip install tornado==5.1.1

也可到pypi 下载合适的版本解压安装。

2. Hello World

Talk is cheap. Show me the code.

新建文件 tornado_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()

运行,开启 tornado; 并利用 curl 或者浏览器访问本地的 8888 端口即可。

$python tornado_hello.py

$curl http://localhost:8888/
hello world

3. 了解 tornado

  • RequestHandler

    对 HTTP 请求的封装,提供了抽象的方法 "GET", "HEAD", "POST", "DELETE", "PATCH", "PUT", "OPTIONS",应用只需要根据需要覆盖 get/head/post/delete/patch/put/options 即可支持 HTTP 的请求方法。
    以上代码只实现了 GET 方法,当请求没有提供的方法时, tornado 会返回“405: Method Not Allowed”。
    线程安全,所有的方法都是非线程安全的,应当考虑重入问题!

  • tornado.ioloop

    tornado 的核心 io 循环模块,封装了 Linux 的 epoll 和 BSD 的 kqueue,tornado 高性能的基石;

  • Application

    tornado 应用,主要处理路由与 handler 的映射;
    以上 app.listen() 创建了一个 HTTPServer,监听端口 8888;最终的 start 启动该服务器;
    如下图为 listen 的代码:
    WeChatScreenshot_20181206190257png

tornado 编写 HTTP 应用接口思路

1. 定义应用的 handler 类,即实现的功能。

2. 创建 web 应用实例对象,第一个初始化参数为路由映射列表。

3. 创建服务器实例,绑定服务器端口。

4. 启动当前线程的 IOLoop。

4. tornado 多进程

以上代码只是创建单个进程,查看系统只有一个 tornado_test 的进程;

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()
    http_server = tornado.httpserver.HTTPServer(app)
     http_server.bind(8888)
     http_server.start(None)
    tornado.ioloop.IOLoop.current().start()

http_server.start(num_processes=1) 方法指定开启几个进程,参数 num_processes 默认值为 1,即默认仅开启一个进程;如果 num_processes 为 None 或者 <=0,则自动根据机器硬件的 cpu 核芯数创建同等数目的子进程;如果 num_processes>0,则创建 num_processes 个子进程。
本例子中,传入参数为 None,CPU 核数是 2,发现创建了三个进程,如下

root@VM-0-15-ubuntu:/root/test# ps -elf | grep tornado_hello
0 S root 12034 22710 0 80 0 - 14142 wait 19:08 pts/0 00:00:00 python tornado_hello.py
1 S root 12035 12034 0 80 0 - 14142 ep_pol 19:08 pts/0 00:00:00 python tornado_hello.py
1 S root 12036 12034 0 80 0 - 14142 ep_pol 19:08 pts/0 00:00:00 python tornado_hello.py
0 S root 12307 22710 0 80 0 - 3307 pipe_w 19:11 pts/0 00:00:00 grep --color=auto tornado_hello

因此这种模式 tornado 是一个主进程控制两个子进程,两个子进程处于 ep_pol 状态;
从输出看两个自己成是实际的 worker,主进程是管理进程;

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:PipeSoloSymWide 等,欢迎大家加入,贡献开源。

    3301 引用 • 3946 回帖 • 653 关注
  • Tornado
    1 引用
  • web框架
    1 引用
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    226 引用 • 360 回帖 • 907 关注
感谢    关注    收藏    赞同    反对    举报    分享