美文网首页
Tornado学习

Tornado学习

作者: 锦绣拾年 | 来源:发表于2020-07-21 22:22 被阅读0次

    Tornado

    (学习时对网上信息的总结,木有原创)
    部分来自https://www.w3cschool.cn/python_tornado/

    引言

    1.强大的、可扩展的web服务器。

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

    【以下这些论述让我想起来epoll/poll】

    异步服务器在这一场景中的应用相对较新,但他们正是被设计用来减轻基于线程的服务器的限制的。当负载增加时,诸如Node.js,lighttpd和Tornodo这样的服务器使用协作的多任务的方式进行优雅的扩展。也就是说,如果当前请求正在等待来自其他资源的数据(比如数据库查询或HTTP请求)时,一个异步服务器可以明确地控制以挂起请求。异步服务器用来恢复暂停的操作的一个常见模式是当合适的数据准备好时调用回调函数。

    一个普通的tornado web服务器通常由[[四大组件]]组成。
    ioloop实例,它是全局的tornado事件循环,是服务器的引擎核心,示例中tornado.ioloop.IOLoop.current()就是默认的tornado ioloop实例。
    app实例,它代表着一个完成的后端app,它会挂接一个服务端套接字端口对外提供服务。一个ioloop实例里面可以有多个app实例,示例中只有1个,实际上可以允许多个,不过一般几乎不会使用多个。
    handler类,它代表着业务逻辑,我们进行服务端开发时就是编写一堆一堆的handler用来服务客户端请求。
    路由表,它将指定的url规则和handler挂接起来,形成一个路由映射表。当请求到来时,根据请求的访问url查询路由映射表来找到相应的业务handler。

    from abc import ABC
    
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    
    from tornado.options import define, options
    import platform
    
    if platform.system() == "Windows":
        import asyncio
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    
    define("port", default=8000, help="run on given port", type=int)
    
    class IndexHandler(tornado.web.RequestHandler):#handler类,它代表着业务逻辑,我们进行服务端开发时就是编写一堆一堆的handler用来服务客户端请求。
        def get(self):
            greeting = self.get_argument("greeting", "Hello")
            self.write(greeting + ',friendly user!')
    #这是Tornado的请求处理函数类。当处理一个请求时,Tornado将这个类实例化,并调用与HTTP请求方法所对应的方法。在这个例子中,我们只定义了一个get方法,也就是说这个处理函数将对HTTP的GET请求作出响应。我们稍后将看到实现不止一个HTTP方法的处理函数
    
    if __name__ == "__main__":
        tornado.options.parse_command_line()
        app = tornado.web.Application(handlers=[(r"/", IndexHandler)])#app 一个完成的后端,对外提供服务
        #这里的参数handlers非常重要,值得我们更加深入的研究。它应该是一个元组组成的列表,其中每个元组的第一个元素是一个用于匹配的正则表达式,第二个元素是一个RequestHanlder类。在hello.py中,我们只指定了一个正则表达式-RequestHanlder对,但你可以按你的需要指定任意多个。
        
        '''
        ↑这是真正使得Tornado运转起来的语句。首先,我们使用Tornado的options模块来解析命令行。然后我们创建了一个Tornado的Application类的实例。传递给Application类init方法的最重要的参数是handlers。它告诉Tornado应该用哪个类来响应请求。
        '''
        http_server = tornado.httpserver.HTTPServer(app)
        http_server.listen(options.port)  # 监听 port
        tornado.ioloop.IOLoop.instance().start()
        
        '''
        从这里开始的代码将会被反复使用:一旦Application对象被创建,我们可以将其传递给Tornado的HTTPServer对象,然后使用我们在命令行指定的端口进行监听(通过options对象取出。)最后,在程序准备好接收HTTP请求后,我们创建一个Tornado的IOLoop的实例。
        '''
        #路由表,它将指定的url规则和handler挂接起来,形成一个路由映射表。当请求到来时,根据请求的访问url查询路由映射表来找到相应的业务handler。
        #ioloop实例,它是全局的tornado事件循环,是服务器的引擎核心,示例中tornado.ioloop.IOLoop.current()就是默认的tornado ioloop实例。
    #app实例,它代表着一个完成的后端app,它会挂接一个服务端套接字端口对外提供服务。一个ioloop实例里面可以有多个app实例,示例中只有1个,实际上可以允许多个,不过一般几乎不会使用多个。
    '''
    编写一个Tornado应用中最多的工作是定义类继承Tornado的RequestHandler类。在这个例子中,我们创建了一个简单的应用,在给定的端口监听请求,并在根目录("/")响应请求。
    你可以在命令行里尝试运行这个程序以测试输出:
    '''
    

    关于多进程

        print('port', tornado.options.options.port)
        # 将服务器绑定到指定端口
        httpserver.bind(tornado.options.options.port)
        # 可以开启多进程,单进程&多进程
        # httpserver.start(num_processes=1) 指定开多少个进程
        # 默认仅仅开一个进程
        # 如果num_processes为None或者<=0,则自动根据机器硬件的cpu核芯数创建同等数目的子进程;
        # num_processes>0,则创建num_processes个子进程。
        httpserver.start(1)
        tornado.ioloop.IOLoop.current().start()
        # 不建议使用这种多进程的方式,而是手动开启多个进程,并且绑定不同的端口。
        """
            关于多进程
            虽然tornado给我们提供了一次开启多个进程的方法,但是由于:
            
            每个子进程都会从父进程中复制一份IOLoop实例,如过在创建子进程前我们的代码动了IOLoop实例,那么会影响到每一个子进程,势必会干扰到子进程IOLoop的工作;
            所有进程是由一个命令一次开启的,也就无法做到在不停服务的情况下更新代码;
            所有进程共享同一个端口,想要分别单独监控每一个进程就很困难。
        """
    

    相关文章

      网友评论

          本文标题:Tornado学习

          本文链接:https://www.haomeiwen.com/subject/crrgkktx.html