Tornado模块

Tornado

一个轻量级的Web框架

简介

1.Tornado在设计之初就考虑到了性能因素,旨在解决C10K问题,这样的设计使得其成为一个拥有非常高性能的框架。
此外,它还拥有处理安全性、用户验证、社交网络以及与外部服务(如数据库和网站API等)进行交互的工具

2.Tornado主要解决高并发问题,在处理高并发上,它采用异步的方式,通常能支持高于10K的并发

 

tornado安装

1 pip install tornado

 

简单实用代码示例

# -*- coding: utf-8 -*-
__author__ = 'CQ'

import textwrap
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import torndb
import os
from Tornado import databases_share  # 自定义功能更强大的SQL操作

from tornado.options import define, options

define("port", default=8888, help="run on the given port", type=int)


def use_database():
    """
        使用tornado原生的SQL模块
    :return:
    """
    db = torndb.Connection(host="127.0.0.1", database="test", user="root", password="123456")
    a = db.get('select * from node where id=5 ')   # get 只能返回一行数据,且是字典格式,返回多行将报错
    print(a)

    b = db.query('select * from node')   # query 返回是列表格式的数据,能够返回多条,且每个列表项是一个字典
    print(b)

    exec_str = "insert into user(name,age,gender) values ('%s','%s','%s')" % ("张三", "58", "")
    res = db.execute(exec_str)
    print(res)


class ReverseHandler(tornado.web.RequestHandler):

    def get(self, input):
        self.write(input[::-1] + '\n')

    def head(self):
        self.set_status(200)  # 返回指定状态码


class WrapHandler(tornado.web.RequestHandler):

    def post(self):
        text = self.get_argument('text')
        width = self.get_argument('width', 40)
        self.write(textwrap.fill(text, int(width)) + '\n')

    def write_error(self, status_code, **kwargs):
        self.write("Gosh darnit, user! You caused a {0} error.\n".format(
            status_code))


if __name__ == "__main__":
    tornado.options.parse_command_line()
    SETTINGS = dict(
        template_path=os.path.join(os.path.dirname(__file__), "templates"),
        static_path=os.path.join(os.path.dirname(__file__), "static"),
    )
    urls = [
        (r"/reverse/(\w+)", ReverseHandler),
        (r"/wrap", WrapHandler)
    ]
    app = tornado.web.Application(
        handlers=urls,
        **SETTINGS,
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

 

使用自定制SQL操作模块

# -*- coding: utf-8 -*-
__author__ = 'CQ'

import pymysql
import logging


logger = logging.getLogger(__name__)


class MysqlServer(object):
    """
        Tornado通用连接数据库类
        用pymysql替代tornado使得操作数据库更加灵活,定制化
    """

    def __init__(self, db_config):
        try:
            self._db_config = db_config
            self._conn = self.__get_conn()
            self._cursor = self._conn.curson()
        except Exception:
            self.close()
            logger.exception(u"数据库连接失败")

    def __get_conn(self):
        connection = pymysql.connect(host=self._db_config['HOST'],
                                     port=self._db_config['PORT'],
                                     user=self._db_config['USERNAME'],
                                     password=self._db_config['PASSWORD'],
                                     db=self._db_config['DB_NAME'],
                                     charset=self._db_config['CHAR_SET'],
                                     )
        connection.ping(True)
        return connection

    def ensure_cursor(self):
        if not self._cursor:
            if not self._conn:
                self._conn = self.__get_conn()
            self._cursor = self._conn.cursor()

    def run_sql(self, sql):
        """
            执行完SQL语句需要返回结果
        :param sql:
        :return:
        """
        self.ensure_cursor()
        self._cursor.execute(sql)
        # commit只对innodb生效,不加commit的话,修改数据库记录的操作不会生效。
        # 如果是myisam引擎的话,不需要commit即可生效
        self._conn.commit()
        return self._cursor.fetchall()

    def execute_sql(self, sql):
        """
            执行SQL语句无返回值
        :param sql:
        :return:
        """
        self.ensure_cursor()
        self._cursor.execute(sql)
        self._conn.commit()

    def run_sql_fetchone(self, sql):
        """
            执行SQL返回一条结果
        :param sql:
        :return:
        """
        self.ensure_cursor()
        self._cursor.execute(sql)
        return self._cursor.fetchone()

    def close(self):
        if self._cursor:
            self._cursor.close()
        if self._conn:
            self._conn.close()
        logger.info(u"关闭数据库连接")


def test():
    settings = {
        'HOST': "127.0.0.1",
        'PORT': "3306",
        'USERNAME': "root",
        'PASSWORD': "123456",
        'DB_NAME': "test",
        'CHAR_SET': "utf8",
    }
    db = MysqlServer(settings)
    sql = "select distinct `node_name` from tb_node"
    ret = db.run_sql(sql)
    db.close()
    return ret


if __name__ == "__main__":
    print(test())

 

tornado安全相关

1. 使用Cookie正确的用户登陆到网站,保证编写的后台管理程序不被非法访问

2. tornado的cookie使用加密签名来验证cookie的值有没有被服务器软件以外的人修改

3. 因为恶意脚本并不知道安全密钥,所以不能再应用不知情的情况下修改cookie,从而达到安全认证的目的

 

使用cookie做简单用户验证

# -*- coding: utf-8 -*-
__author__ = 'CQ'

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient

import os
import json


from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)


class BaseHandler(tornado.web.RequestHandler):

    def get_current_user(self):
        return self.get_secure_cookie("username")  # 将用户cookie解密在把值返回


class LoginHandler(BaseHandler):

    def get(self):
        self.render('login.html')

    def post(self):
        self.set_secure_cookie("username", self.get_argument("username"))
        self.redirect("/")


class WelcomeHandler(BaseHandler):
    @tornado.web.authenticated  # tornado Web自身提供,没有登录时,自动跳转到登录界面,做身份验证用的
    def get(self):
        self.render("welcome.html", username=self.current_user)


class LogoutHandler(BaseHandler):

    def get(self):
        self.clear_cookie("username")
        self.redirect("/")


if __name__ == "__main__":
    settings = {
        "template_path": os.path.join(os.path.dirname(__file__), "templates"),
        # cookie不会以明文存储在客户端,而是用此字符串加密cookie,然后才存储在客户端
        "cookie_secret": "AQAAALudVkKt/AYA0bLPykwXoIBRVYTO",
        # 当用户没有登录时,tornado会自动跳转的登录URL请求用户登录
        "login_url": "/login"
    }
    urls = [
        (r'/', WelcomeHandler),
        (r'/login', LoginHandler),
        (r'/test', WelcomeHandler),
        (r'/logout', LogoutHandler)
    ]

    app = tornado.web.Application(
        handlers=urls,
        **settings,
    )
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

 

 

项目部署方式

1 fastcgi方式
2 http方法

 

 

posted @ 2018-01-31 02:20  前路~  阅读(358)  评论(0编辑  收藏  举报