<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【網(wǎng)站構(gòu)建】Python高性能架構(gòu)Tornado

          共 9904字,需瀏覽 20分鐘

           ·

          2021-06-27 11:29

          Start:關(guān)注本公眾號(hào)后,可直接聯(lián)系后臺(tái)獲取排版美化的詳細(xì)文檔!

          Hints:本篇文章所編纂的資料均來(lái)自網(wǎng)絡(luò),特此感謝參與奉獻(xiàn)的有關(guān)人員。


          • Tornado的簡(jiǎn)單概述:

          Tornado是一個(gè)基于PythonWeb服務(wù)框架和異步網(wǎng)絡(luò)庫(kù)。Tornado 是一個(gè)基于PythonWeb服務(wù)框架和異步網(wǎng)絡(luò)庫(kù)。由facebook開(kāi)源出來(lái)的超高并發(fā)框架,利用異步協(xié)程機(jī)制,實(shí)現(xiàn)比多線(xiàn)程更高的性能爆發(fā),絕對(duì)是高并發(fā)類(lèi)網(wǎng)站的首選,知乎網(wǎng)就是用這個(gè)框架開(kāi)發(fā)的,性能超高。

           

          • Tornado的應(yīng)用場(chǎng)景:

          -1用戶(hù)量大,高并發(fā)

          如秒殺搶購(gòu)、雙十一某寶購(gòu)物、春節(jié)搶火車(chē)票

          -2大量的HTTP持久連接

          使用同一個(gè)TCP連接來(lái)發(fā)送和接收多個(gè)HTTP請(qǐng)求/應(yīng)答,而不是為每一個(gè)新的請(qǐng)求/應(yīng)答打開(kāi)新的連接的方法。對(duì)于HTTP 1.0,可以在請(qǐng)求的包頭(Header)中添加Connection: Keep-Alive。對(duì)于HTTP 1.1,所有的連接默認(rèn)都是持久連接。

           

          • Tornado的主要構(gòu)成:

          -Web 框架 (包括用來(lái)創(chuàng)建 Web 應(yīng)用程序的 RequestHandler類(lèi), 還有很多其它支持的類(lèi)).

          -HTTP 客戶(hù)端和服務(wù)器的實(shí)現(xiàn) (HTTPServer AsyncHTTPClient).

          -異步網(wǎng)絡(luò)庫(kù) (IOLoop IOStream),對(duì) HTTP 的實(shí)現(xiàn)提供構(gòu)建模塊, 還可以用來(lái)實(shí)現(xiàn)其他協(xié)議.

          -協(xié)程庫(kù) (tornado.gen)讓用戶(hù)通過(guò)更直接的方法來(lái)實(shí)現(xiàn)異步編程, 而不是通過(guò)回調(diào)的方式.
          Tornado web 框架和 HTTP 服務(wù)器提供了一整套WSGI的方案.可以讓Tornado編寫(xiě)的Web框架運(yùn)行在一個(gè)WSGI容器中 (WSGIAdapter),或者使用 TornadoHTTP 服務(wù)器作為一個(gè)WSGI容器 (WSGIContainer),這兩種解決方案都有各自的局限性, 為了充分享受Tornado為您帶來(lái)的特性,你需要同時(shí)使用Tornadoweb框架和HTTP服務(wù)器.

           

          • Tornado的關(guān)鍵概念:

          異步和非阻塞 I/O

          實(shí)時(shí)的web特性通常需要為每個(gè)用戶(hù)一個(gè)大部分時(shí)間都處于空閑的長(zhǎng)連接.在傳統(tǒng)的同步web服務(wù)器中,這意味著需要給每個(gè)用戶(hù)分配一個(gè)專(zhuān)用的線(xiàn)程,這樣的開(kāi)銷(xiāo)是十分巨大的.為了減小對(duì)于并發(fā)連接需要的開(kāi)銷(xiāo),Tornado使用了一種單線(xiàn)程事件循環(huán)的方式.這意味著所有應(yīng)用程序代碼都應(yīng)該是異步和非阻塞的,因?yàn)樵谕粫r(shí)刻只有一個(gè)操作是有效的.

          -阻塞

          一個(gè)函數(shù)通常在它等待返回值的時(shí)候被阻塞 .一個(gè)函數(shù)被阻塞可能由于很多原因:網(wǎng)絡(luò)I/O,磁盤(pán)I/O,互斥鎖等等.事實(shí)上, 每一個(gè)函數(shù)都會(huì)被阻塞,只是時(shí)間會(huì)比較短而已。

          -異步

          一個(gè)異步 函數(shù)在它結(jié)束前就已經(jīng)返回了,而且通常會(huì)在程序中觸發(fā)一些動(dòng)作然后在后臺(tái)執(zhí)行一些任務(wù).(和正常的同步 函數(shù)相比, 同步函數(shù)在返回之前做完了所有的事).

          -協(xié)程

          Tornado 中推薦用 協(xié)程 來(lái)編寫(xiě)異步代碼. 協(xié)程使用 Python 中的關(guān)鍵字 yield來(lái)替代鏈?zhǔn)交卣{(diào)來(lái)實(shí)現(xiàn)掛起和繼續(xù)程序的執(zhí)行。協(xié)程和異步編程的代碼一樣簡(jiǎn)單, 而且不用浪費(fèi)額外的線(xiàn)程. 它們還可以減少上下文切換讓并發(fā)更簡(jiǎn)單.

           

          • Tornado的環(huán)境配置:

          Pip install tornado

           

          • Tornado的HelloWorld

          import tornado.ioloop
          import tornado.web
          # handler類(lèi),它代表著業(yè)務(wù)邏輯,我們進(jìn)行服務(wù)端開(kāi)發(fā)時(shí)就是編寫(xiě)一堆一堆的handler用來(lái)服務(wù)客戶(hù)端請(qǐng)求。
          class MainHandler(tornado.web.RequestHandler):
              def get(self):
                  self.write("Hello,world")
          def make_app():
              return tornado.web.Application(
                  # 路由表,它將指定的url規(guī)則和handler掛接起來(lái),形成一個(gè)路由映射表。當(dāng)請(qǐng)求到來(lái)時(shí),根據(jù)請(qǐng)求的訪(fǎng)問(wèn)url查詢(xún)路由映射表來(lái)找到相應(yīng)的業(yè)務(wù)handler。
                  [
                      (r"/", MainHandler),
                  ]
              )
          if __name__ == "__main__":
              # app實(shí)例,它代表著一個(gè)完成的后端app,它會(huì)掛接一個(gè)服務(wù)端套接字端口對(duì)外提供服務(wù)。
              app = make_app()
              # 后端app監(jiān)聽(tīng)端口設(shè)置
              app.listen(8888)
              # ioloop實(shí)例,全局的tornado事件循環(huán)
              tornado.ioloop.IOLoop.current().start()

          一個(gè)普通的tornado web服務(wù)器通常由四大組件組成。

          -1.ioloop實(shí)例,它是全局的tornado事件循環(huán),是服務(wù)器的引擎核心,示例中tornado.ioloop.IOLoop.current()就是默認(rèn)的tornado ioloop實(shí)例。

          -2.app實(shí)例,它代表著一個(gè)完成的后端app,它會(huì)掛接一個(gè)服務(wù)端套接字端口對(duì)外提供服務(wù)。一個(gè)ioloop實(shí)例里面可以有多個(gè)app實(shí)例,示例中只有1個(gè),實(shí)際上可以允許多個(gè),不過(guò)一般幾乎不會(huì)使用多個(gè)。

          -3.handler類(lèi),它代表著業(yè)務(wù)邏輯,我們進(jìn)行服務(wù)端開(kāi)發(fā)時(shí)就是編寫(xiě)一堆一堆的handler用來(lái)服務(wù)客戶(hù)端請(qǐng)求。

          -4.路由表,它將指定的url規(guī)則和handler掛接起來(lái),形成一個(gè)路由映射表。當(dāng)請(qǐng)求到來(lái)時(shí),根據(jù)請(qǐng)求的訪(fǎng)問(wèn)url查詢(xún)路由映射表來(lái)找到相應(yīng)的業(yè)務(wù)handler

          這四大組件的關(guān)系是,一個(gè)ioloop包含多個(gè)app(管理多個(gè)服務(wù)端口),一個(gè)app包含一個(gè)路由表,一個(gè)路由表包含多個(gè)handlerioloop是服務(wù)的引擎核心,它是發(fā)動(dòng)機(jī),負(fù)責(zé)接收和響應(yīng)客戶(hù)端請(qǐng)求,負(fù)責(zé)驅(qū)動(dòng)業(yè)務(wù)handler的運(yùn)行,負(fù)責(zé)服務(wù)器內(nèi)部定時(shí)任務(wù)的執(zhí)行。

          當(dāng)一個(gè)請(qǐng)求到來(lái)時(shí),ioloop讀取這個(gè)請(qǐng)求解包成一個(gè)http請(qǐng)求對(duì)象,找到該套接字上對(duì)應(yīng)app的路由表,通過(guò)請(qǐng)求對(duì)象的url查詢(xún)路由表中掛接的handler,然后執(zhí)行handler。handler方法執(zhí)行后一般會(huì)返回一個(gè)對(duì)象,ioloop負(fù)責(zé)將對(duì)象包裝成http響應(yīng)對(duì)象序列化發(fā)送給客戶(hù)端。

           

          • Tornado的Redis使用

          import json

          import redis

          import tornado.ioloop

          import tornado.web

           

          class FactorialService(object):

           

             def __init__(self):

                 self.cache = redis.StrictRedis("localhost", 6379)  # 緩存換成redis

                 self.key = "factorials"

           

             def calc(self, n):

                 s = self.cache.hget(self.key, str(n)) # hash結(jié)構(gòu)保存計(jì)算結(jié)果

                 if s:

                     return int(s), True

                 s = 1

                 for i in range(1, n):

                     s *= i

                 self.cache.hset(self.key, str(n), str(s))  # 保存結(jié)果

                 return s, False

           

           

          classFactorialHandler(tornado.web.RequestHandler):

           

             service = FactorialService()

           

             def get(self):

                 n = int(self.get_argument("n") or 1)  # 參數(shù)默認(rèn)值

                 fact, cached = self.service.calc(n)

                 result = {

                     "n": n,

                     "fact": fact,

                     "cached": cached

                 }

                 self.set_header("Content-Type", "application/json;charset=UTF-8")

                 self.write(json.dumps(result))

           

           

          def make_app():

             return tornado.web.Application([

                 (r"/fact", FactorialHandler),

             ])

           

          if __name__ == "__main__":

             app = make_app()

             app.listen(8888)

             tornado.ioloop.IOLoop.current().start()

           

          當(dāng)我們?cè)俅卧L(fǎng)問(wèn)http://localhost:8888/fact?n=50,可以看到瀏覽器輸出如下
          {"cached": false, "fact":608281864034267560872252163321295376887552831379210240000000000, "n":50}
          ,再刷新一下,瀏覽器輸出{"cached": true, "fact":608281864034267560872252163321295376887552831379210240000000000, "n":50},可以看到cached字段由true編程了false,表明緩存確實(shí)已經(jīng)保存了計(jì)算的結(jié)果。我們重啟一下進(jìn)程,
          再次訪(fǎng)問(wèn)這個(gè)連接,觀(guān)察瀏覽器輸出,可以發(fā)現(xiàn)結(jié)果的cached依舊等于true。說(shuō)明緩存結(jié)果不再是存在本地內(nèi)存中了。


          • Tornado的項(xiàng)目結(jié)構(gòu):

          備注:手工創(chuàng)建上述的文件夾及文件

          -application.py

          全局環(huán)境設(shè)置,包括靜態(tài)目錄設(shè)置、模板目錄設(shè)置、是否debug,及可能需要用到的cookies加密設(shè)置

          -server.py

          啟動(dòng)tornado服務(wù)主文件,主要包括web的訪(fǎng)問(wèn)URL及端口配置

          url.py

          URL路由,即用來(lái)配置訪(fǎng)問(wèn)某個(gè)URL路徑時(shí),該具體定位到哪個(gè)HTML文件

          handles 文件夾

          用來(lái)具體處理網(wǎng)頁(yè)動(dòng)態(tài)交互請(qǐng)求,里面主要是getpost方法中的邏輯開(kāi)發(fā)。

          Handlers文件夾下的index.py

          存放對(duì)應(yīng)的Handlers類(lèi)響應(yīng)請(qǐng)求

          statics 文件夾

          用來(lái)存放網(wǎng)頁(yè)需要的CSS樣式表文件、Javascript文件及圖片、視頻等靜態(tài)網(wǎng)頁(yè)內(nèi)容,這個(gè)文件夾的特征是,通過(guò)瀏覽器URL路徑可直接訪(fǎng)問(wèn),所以不要存放需要保密的后臺(tái)程序文件

          templates 文件夾

          用來(lái)存放靜態(tài)HTML文件。

          1. tornado.web

          tornado的基礎(chǔ)web框架模塊

          RequestHandler

          封裝了對(duì)應(yīng)一個(gè)請(qǐng)求的所有信息和方法,write(響應(yīng)信息)就是寫(xiě)響應(yīng)信息的一個(gè)方法;對(duì)應(yīng)每一種http請(qǐng)求方式(get、post等),把對(duì)應(yīng)的處理邏輯寫(xiě)進(jìn)同名的成員方法中(如對(duì)應(yīng)get請(qǐng)求方式,就將對(duì)應(yīng)的處理邏輯寫(xiě)在get()方法中),當(dāng)沒(méi)有對(duì)應(yīng)請(qǐng)求方式的成員方法時(shí),會(huì)返回“405: Method Not Allowed”錯(cuò)誤。

          Application

          Tornado Web框架的核心應(yīng)用類(lèi),是與服務(wù)器對(duì)接的接口,里面保存了路由信息表,其初始化接收的第一個(gè)參數(shù)就是一個(gè)路由信息映射元組的列表;其listen(端口)方法用來(lái)創(chuàng)建一個(gè)http服務(wù)器實(shí)例,并綁定到給定端口(注意:此時(shí)服務(wù)器并未開(kāi)啟監(jiān)聽(tīng))。

          2. tornado.ioloop

          tornado的核心io循環(huán)模塊,封裝了Linux的epoll和BSD的kqueue,tornado高性能的基石。以L(fǎng)inux的epoll為例,其原理如下圖:

           

           

          IOLoop.current()

          返回當(dāng)前線(xiàn)程的IOLoop實(shí)例。

          IOLoop.start()

          啟動(dòng)IOLoop實(shí)例的I/O循環(huán),同時(shí)服務(wù)器監(jiān)聽(tīng)被打開(kāi)。

          總結(jié)Tornado Web程序編寫(xiě)思路
          創(chuàng)建web應(yīng)用實(shí)例對(duì)象,第一個(gè)初始化參數(shù)為路由映射列表。
          定義實(shí)現(xiàn)路由映射列表中的handler類(lèi)。
          創(chuàng)建服務(wù)器實(shí)例,綁定服務(wù)器端口。
          啟動(dòng)當(dāng)前線(xiàn)程的IOLoop。

          3 httpserver
          上一節(jié)我們說(shuō)在tornado.web.Application.listen()(示例代碼中的app.listen(8000))的方法中,創(chuàng)建了一個(gè)http服務(wù)器示例并綁定到給定端口


          • Tornado的常用操作:

          -options

          tornado.options模塊——全局參數(shù)定義、存儲(chǔ)、轉(zhuǎn)換。

          tornado.options.define()

          用來(lái)定義options選項(xiàng)變量的方法,定義的變量可以在全局的tornado.options.options中獲取使用,傳入?yún)?shù):

          name 選項(xiàng)變量名,須保證全局唯一性,否則會(huì)報(bào)“Option'xxx' already defined in ...”的錯(cuò)誤;

          default 選項(xiàng)變量的默認(rèn)值,如不傳默認(rèn)為None;

          type 選項(xiàng)變量的類(lèi)型,從命令行或配置文件導(dǎo)入?yún)?shù)的時(shí)候tornado會(huì)根據(jù)這個(gè)類(lèi)型轉(zhuǎn)換輸入的值,轉(zhuǎn)換不成功時(shí)會(huì)報(bào)錯(cuò),可以是strfloat、intdatetime、timedelta中的某個(gè),若未設(shè)置則根據(jù)default的值自動(dòng)推斷,若default也未設(shè)置,那么不再進(jìn)行轉(zhuǎn)換??梢酝ㄟ^(guò)利用設(shè)置type類(lèi)型字段來(lái)過(guò)濾不正確的輸入。

          multiple 選項(xiàng)變量的值是否可以為多個(gè),布爾類(lèi)型,默認(rèn)值為False,如果multipleTrue,那么設(shè)置選項(xiàng)變量時(shí)值與值之間用英文逗號(hào)分隔,而選項(xiàng)變量則是一個(gè)list列表(若默認(rèn)值和輸入均未設(shè)置,則為空列表[])。

          help 選項(xiàng)變量的幫助提示信息,在命令行啟動(dòng)tornado時(shí),通過(guò)加入命令行參數(shù)--help 可以查看所有選項(xiàng)變量的信息(注意,代碼中需要加入tornado.options.parse_command_line())。

          tornado.options.options

          全局的options對(duì)象,所有定義的選項(xiàng)變量都會(huì)作為該對(duì)象的屬性。

          tornado.options.parse_command_line()

          轉(zhuǎn)換命令行參數(shù),并將轉(zhuǎn)換后的值對(duì)應(yīng)的設(shè)置到全局options對(duì)象相關(guān)屬性上。

          -日志

          當(dāng)我們?cè)诖a中調(diào)用parse_command_line()或者parse_config_file()的方法時(shí),tornado會(huì)默認(rèn)為我們配置標(biāo)準(zhǔn)logging模塊,即默認(rèn)開(kāi)啟了日志功能,并向標(biāo)準(zhǔn)輸出(屏幕)打印日志信息。

          如果想關(guān)閉tornado默認(rèn)的日志功能,可以在命令行中添加--logging=none 或者在代碼中執(zhí)行如下操作:

          from tornado.options import options, parse_command_line

          options.logging= None

          parse_command_line()


          • Tornado的常用模塊:

          • Web framework:

             tornado.web — RequestHandler and Application classes

             tornado.template - 模板

             tornado.routing - 基本路由實(shí)現(xiàn)

             tornado.escape - 轉(zhuǎn)義和字符串操作

             tornado.locale - 國(guó)際化支持

             tornado.websocket - 與瀏覽器的雙向通信socket

          • tornado的HTTP服務(wù)器和客戶(hù)端:

              tornado.httpserver- 非阻塞HTTP服務(wù)器

             tornado.httpclient - 異步HTTP客戶(hù)端

             tornado.httputil - 操縱HTTP頭和URL

             tornado.http1connection - HTTP / 1.x客戶(hù)端/服務(wù)器實(shí)現(xiàn)

          • 異步網(wǎng)絡(luò):

             tornado.ioloop -主事件循環(huán)

             tornado.iostream - Flexible output generation(靈活的輸出生成

             tornado.netutil - 操作HTTP報(bào)頭和URL的工具類(lèi)

             tornado.tcpclient- IOStream連接工廠(chǎng)

             tornado.tcpserver- IOStream基于TCP的服務(wù)器

          • 協(xié)程和并發(fā)

             tornado.gen - 基于發(fā)生器的協(xié)程

             tornado.locks - 同步原語(yǔ)

             tornado.queues - 協(xié)程隊(duì)列

             tornado.process - 用于多個(gè)進(jìn)程的實(shí)用程序

          • 與其他服務(wù)集成

             tornado.auth - 使用OpenIDOAuth進(jìn)行第三方登錄

             tornado.wsgi - 與其他Python框架和Web服務(wù)器的網(wǎng)關(guān)接口

             tornado.platform.caresresolver - 使用C-Ares的異步DNS解析器

             tornado.platform.twisted - twistedtornado之間的橋梁

             tornado.platform.asyncio- asynciotornado之間的橋梁

          • Utilities

             tornado.autoreload - 自動(dòng)檢測(cè)開(kāi)發(fā)中的代碼更改

             tornado.concurrent-  Work withFuture objects

             tornado.log - 打印日志的

             tornado.options - 命令行解析

             tornado.stack_context - 跨異步回調(diào)的異常處理

             tornado.testing - 對(duì)異步代碼的單元測(cè)試支持

             tornado.util - 通用工具類(lèi)

           

          • 參考鏈接:

          Tornado簡(jiǎn)介:

          https://blog.csdn.net/Ka_Ka314/article/details/81163740

          Tornado的項(xiàng)目架構(gòu):

          https://zhuanlan.zhihu.com/p/127922316

          Tornado+Redis

          https://zhuanlan.zhihu.com/p/37382503

          Tornado簡(jiǎn)易教程

          https://blog.csdn.net/belalds/article/details/80575755

          Tornado開(kāi)發(fā)教程

          https://www.cnblogs.com/jiangxiaobo/p/12776283.html

          用 gunicorn + gevent 跑 tornado app

          https://zhuanlan.zhihu.com/p/31635068

          Tornado手冊(cè)

          http://www.ttlsa.com/docs/tornado/#overview

          Tornado官網(wǎng)

          https://www.tornadoweb.org/en/stable/

          Tornado的前后端

          https://www.cnblogs.com/xiaobeibei26/p/6646083.html

          公眾號(hào)二維碼

          End:如果有興趣了解金融量化交易和其他數(shù)據(jù)分析的實(shí)用技術(shù),歡迎關(guān)注本公眾號(hào)

          瀏覽 69
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚州无码 | 日本无码操逼视频 | 亚洲AV无码一区二区三区动漫 | 久操热 | 色婷婷丁香激情五月电影 |