天天看點

初學Tornado架構以及和Django的對比

django和tornado差別

* 性能

 * 多線程或者多程序

 *  django使用的是( 多線程或者多程序)

 *  tornado使用的是協程(微線程),協程性能非常高(沒有線程這種上下文建立,切換的開銷)yield

* 功能

 * django 大而全(什麼都有)(定制太困難了)

            背景(admin) 

            orm(對象關系映射類庫)

            session

 * tornado 小而精 (輕量級)什麼也沒有 

 * tornado 單線程異步分阻塞(node.js)

 * tornado适用場景

            高并發,長連接配接

### tornado單線程異步分阻塞 ###

* 代碼

            # 處理網絡請求的    

            class IndexHandler(tornado.web.RequestHandler):

                # get請求

                def get(self):

                    # 輸出響應體

                    self.write('hello world')

                #Application 其實是一個設定的容器

                app = tornado.web.Application([

                        (r'/',IndexHandler)

                    ])

                # 綁定端口(調用了HttpServer)

                app.listen(8000)

                # 死循環(從epoll中獲得需要操作的socket)

                tornado.ioloop.IOLoop.instance().start()

* epoll

 * 用戶端socket的儲存的容器 

### 步驟 ###

* 清理類(RequestHandler)

* Application對象 (很多設定)

* app.listen(8000) 綁定端口,建立伺服器

* ioLoop.start(不斷的從epoll中讀取要處理的用戶端socket)

### 為什麼tornado能處理高并發,長連接配接 ###

* 長連接配接(epoll容器存儲起來了)    

* 高并發(使用的是協程,沒有線程建立和線程上下文切換開銷)        

                    def printa():

                        while True:

                        yield 'a'    

                    def printb():

                        while True:

                        yield 'b'

                    while True:

                        pirnta()

                        printb()

                    abababababab

### tornado特性 ###

* 單線程

* 異步(協程)

* 非阻塞

###  查詢參數 ###

* get/post

 * get  get_query_argument  get_query_arguments 

 * post get_body_argument get_body_arguments

 * 縮寫 get_argument  get_arguments(通用的)

 * 捕獲  

class TimeHandler(tornado.web.RequestHandler):
    def get(self,year,month,day):
        self.write('time'+year+month+day)
app = tornado.web.Application([
     (r'/time/(?P<month>\d+)/(?P<year>\d+)/(?P<day>\d+)',TimeHandler),具名捕獲
     (r'/time/(\d+)/(\d+)/(\d+)',TimeHandler),
])                 
 * self.write(響應體)            
* file,大檔案                     

### 查詢I(Input) ###

* get_argument 獲得get/post參數

* 捕獲/具名捕獲

* self.request.files 上傳多個檔案

* self.request.headers 請求頭

* self.request.remote_ip 獲得用戶端ip

class FileHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        if 'img' in self.request.files:
            imgfile=self.request.files['img']
            filename=imgfile[0]['filename']
            filebody=imgfile[0]['body']
            if not os.path.exists(MEDIA_ROOT):
                os.makedirs(MEDIA_ROOT)
            with open(os.path.join(MEDIA_ROOT,filename),'wb') as fw:
                fw.write(filebody)
        self.write('上傳成功')      
class IPBlock(object):
    def __init__(self,get_response):
        self.get_response = get_response
    def __call__(self, handler=None,*args, **kwargs):
        BLACK_IP=['127.0.0.1']
        if  handler.request.remote_ip in BLACK_IP:
            handler.write('禁止通路')
            return
        return self.get_response(handler)


class RemoteIPHandler(tornado.web.RequestHandler):
    # @IPBlock
    def get(self, *args, **kwargs):
        self.write(u'您的ip是:'+self.request.remote_ip)

    #get = IPBlock(get)
    # IPBLOCK(get)(self,)      

###  輸出O(Output) ###

* write () 響應體

* add_header()添加響應頭  

self.add_header('name','張三')      

* set_status 設定狀态碼

* 自定義重定向

        class RedirctHandler(tornado.web.RequestHandler):

            def get(self, *args, **kwargs):

                # self.set_status(404,'照比到了')

                self.set_status(302,'FOUND')

                self.add_header('LOCATION','http://www.bjsxt.com')

 * 重定向(302,301)self.redirct(位址)

 * 301 永久重定向,         

 * set_cookie 

class CookieHandle(tornado.web.RequestHandler):
    def get(self,*args,**kwargs):
        print(self.get_cookie('sessionid','找不到'))
        import uuid
        import datetime
        self.set_cookie('sessionid',str(uuid.uuid4()),expires=datetime.datetime.utcnow()+ datetime.timedelta(minutes=30),path='/coo')
        self.write('cookie')      

 * get_cookie

### 生命周期 ###    

* initialize--》prepare-->get/post-->on_finish    

* initialize和on_finish是一對,如果說initialize初始化工作,on_finish是清理功能。

* url中 (r'/',Handler,字典,name)    #字典是給Handler中的initialize方法的

              name的使用

class UserHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        print '使用者沒有登入到重定向login',self.reverse_url('lol')
        self.redirect(self.reverse_url('lol'))      
app = tornado.web.Application([
    (r'/user',UserHandler),
    URLSpec(r'/login',LoginHandler,name='lol'),
])      

* write_error 出錯之後,會自動調用

* set_default_headers設定預設響應頭

 *  write_error和set_default_headers 一般寫在父類中,設定通用的響應頭

class DefaultHandler(tornado.web.RequestHandler):
    def set_default_headers(self):
        self.add_header('name','hello')
        self.add_header('age',10)
    def get(self, *args, **kwargs):
        self.write('set_default_headers')      
class CartHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        1/0 會出錯
        self.write('測試錯誤')
    def write_error(self, status_code, **kwargs):
        print status_code,狀态碼
        print kwargs出錯資訊
        self.write('伺服器暫時維護中')      

### url路由 ###

* 元組

* URLSpec

 * 正則,處理類,初始化參數,名字(self.reverse_url('名字'))