自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用Python實(shí)現(xiàn)每秒處理120萬次HTTP請(qǐng)求

開發(fā) 后端
用 Python 做到每秒處理上百萬次 HTTP 請(qǐng)求,可能嗎?也許不能,但直到最近,這已成為現(xiàn)實(shí)。 Japronto 是一個(gè)全新的,為微服務(wù)量身打造的微框架。實(shí)現(xiàn)它的主要目標(biāo)包含夠快、可擴(kuò)展和輕量化。的確它快的嚇人,甚至遠(yuǎn)比 NodeJS 和 Go 還要快的多的多。

用 Python 做到每秒處理上百萬次 HTTP 請(qǐng)求,可能嗎?也許不能,但直到最近,這已成為現(xiàn)實(shí)。 

很多公司都在為了提升程序的執(zhí)行性能和降低服務(wù)器的運(yùn)營成本,而放棄 Python 去選擇其它編程語言,其實(shí)這樣做并不是必須,因?yàn)?Python 完全可以勝任這些任務(wù)。 

Python 社區(qū)最近做了大量關(guān)于性能的優(yōu)化。CPython 3.6 重寫了新的字典從而全面提升解析器的執(zhí)行性能。由于引入更快的調(diào)用規(guī)則和字典查詢緩存,CPython 3.7 甚至還要更快。 

我們可以用 PyPy 的 Just-in-Time 來編譯復(fù)雜的科學(xué)計(jì)算任務(wù),NumPy 的測(cè)試套件也優(yōu)化了和 C 擴(kuò)展的兼容性,同時(shí) PyPy 還計(jì)劃于今年晚些時(shí)候做到和 Python 3.5 保持一致。 

這些振奮人心的變化激勵(lì)著我想要有所創(chuàng)新,Python 所擅長(zhǎng)的領(lǐng)域眾多,我選擇了其中一個(gè):Web 和 MicroServices 開發(fā)。 

了解 Japronto! 

Japronto 是一個(gè)全新的,為微服務(wù)量身打造的微框架。實(shí)現(xiàn)它的主要目標(biāo)包含夠快、可擴(kuò)展和輕量化。的確它快的嚇人,甚至遠(yuǎn)比 NodeJS 和 Go 還要快的多的多。要感謝 asyncio,讓我可以同時(shí)編寫同步和異步代碼。 

Python 的微框架(藍(lán)色)、NodeJS 和 Go (綠色) 和 Japronto (紫色)

勘誤表:用戶 @heppu 提到,如果謹(jǐn)慎點(diǎn)用 Go 的 stdlib HTTP 服務(wù)器可以寫出比上圖的 Go 快 12% 的代碼。另外 fasthttp 也是一個(gè)非常棒的 Go 服務(wù)器,同樣的測(cè)試中它的性能幾乎只比 Japronto 低 18%。真是太棒了!更多細(xì)節(jié)查可以看 https://github.com/squeaky-pl/japronto/pull/12 和 https://github.com/squeaky-pl/japronto/pull/14 

我們可以看到其實(shí) Meinheld WSGI 服務(wù)器已經(jīng)和 NodeJS 和 Go 的性能差不多了。盡管它用的是阻塞式設(shè)計(jì),但還是要比前面那四個(gè)要快的多,前面四個(gè)用的是異步的 Python 解決方案。所以,不要輕易相信別人那些關(guān)于異步系統(tǒng)總是比同步系統(tǒng)更快的說法,雖然都是并發(fā)處理的問題,但事實(shí)遠(yuǎn)不如想象的那么簡(jiǎn)單。 

雖然我只是用 “Hello World” 來完成上面這個(gè)關(guān)于微框架的測(cè)試,但它清晰的展現(xiàn)了各種服務(wù)器框架的處理能力。 

這些測(cè)試是在一臺(tái)亞馬遜 AWS EC2 的 c4.2xlarge 實(shí)例上完成的,它有 8 VCPUs,數(shù)據(jù)中心選在圣保羅區(qū)域,共享主機(jī)、HVM 虛擬化、普通磁盤。操作系統(tǒng)是 Ubuntu 16.04.1 LTS (Xenial Xerus),內(nèi)核為 Linux 4.4.0–53-generic x86_64。操作系統(tǒng)顯示的 CPU 是 Xeon® E5–2666 v3 @ 2.90GHz。Python 我用的版本是 3.6,剛從源碼編譯來的。 

公平起見,所有程序,包括 Go,都只運(yùn)行在單個(gè)處理器內(nèi)核上。測(cè)試工具為 wrk,參數(shù)是 1 個(gè)線程,100 個(gè)鏈接和每個(gè)鏈接 24 個(gè)請(qǐng)求(累計(jì)并發(fā) 2400 次請(qǐng)求)。 

HTTP 流水線(圖片來自 Wikipedia)

HTTP 流水線在這里起著決定性的因素,因?yàn)?Japronto 用它來做執(zhí)行并發(fā)請(qǐng)求的優(yōu)化。 

大多數(shù)服務(wù)器把來自客戶端的流水線和非流水線請(qǐng)求都一視同仁,用同樣的方法處理,并沒有做針對(duì)性的優(yōu)化。(實(shí)際上 Sanic 和 Meinheld 也是默默的把流水線請(qǐng)求當(dāng)做非流水線來處理,這違反了 HTTP 1.1 協(xié)議) 

簡(jiǎn)單來說,通過流水線技術(shù),客戶端不用等到服務(wù)器端返回,就可以在同一條 TCP 鏈接上繼續(xù)發(fā)送后續(xù)的請(qǐng)求。為了保障通訊的完整性,服務(wù)器端會(huì)按照請(qǐng)求的順序逐個(gè)把結(jié)果返回給客戶端。 

細(xì)節(jié)優(yōu)化過程 

當(dāng)一堆小的 GET 請(qǐng)求被客戶端以流水線打包發(fā)送過來,服務(wù)器端很可能只需要一次系統(tǒng)調(diào)用,讀取一個(gè) TCP 數(shù)據(jù)包就能拿到全部的請(qǐng)求。 

系統(tǒng)調(diào)用,以及在內(nèi)核空間到用戶空間之間移動(dòng)數(shù)據(jù),相比起在進(jìn)程內(nèi)部移動(dòng)數(shù)據(jù),成本要高的多。這就是為什么不到萬不得已,要盡可能少做系統(tǒng)調(diào)用的次數(shù)。 

當(dāng) Japronto 收到數(shù)據(jù)并成功解析出請(qǐng)求序列時(shí),它會(huì)嘗試盡可能快的把這些請(qǐng)求執(zhí)行完成,并以正確的順序合并所有結(jié)果,然后只執(zhí)行一次系統(tǒng)調(diào)用發(fā)送數(shù)據(jù)給客戶端。實(shí)際上因?yàn)橛?scatter/gather IO 這樣的系統(tǒng)調(diào)用,合并的工作并不需要自己去完成,只不過 Japronto 暫時(shí)還沒有用到這些功能。 

然而事情并不總是那么完美,有時(shí)候請(qǐng)求需要耗費(fèi)很長(zhǎng)時(shí)間去處理,等待完成的過程增加了不必要的延遲。 

當(dāng)我們做優(yōu)化時(shí),有必要考慮系統(tǒng)調(diào)用的成本和請(qǐng)求的預(yù)期完成時(shí)間。 

經(jīng)過優(yōu)化 Japronto 拿到了 1,214,440 RPS 的成績(jī)

除了利用客戶端流水線請(qǐng)求,和優(yōu)化調(diào)用,還有一些其它可用的技術(shù)。 

Japronto 幾乎都是用 C 寫的。包含解析器、協(xié)議、鏈接管理、路由、請(qǐng)求、應(yīng)答等對(duì)象都是用 C 擴(kuò)展寫的。 

Japronto 力圖做到 Python 的懶加載,比如,協(xié)議頭的字典只有在被試圖請(qǐng)求到時(shí)才會(huì)被創(chuàng)建,另外一系列的對(duì)象也只有在第一次使用時(shí)才會(huì)被創(chuàng)建。 

Japronto 使用超牛逼的 picohttpparser C 庫來解析狀態(tài)、協(xié)議頭以及分片的 HTTP 消息體。Picohttpparser 是直接調(diào)用現(xiàn)代 CPU 集成的 SSE4.2 擴(kuò)展文本處理指令去快速匹配 HTTP 標(biāo)記的邊界(那些 10 年前的老 x86_64 CPU 都有這玩意兒)。I/O 用到了超棒的 uvloop,它是一個(gè) libuv 的封裝,在最底層,它是調(diào)用 epoll 來提供異步讀寫通知。 

Picohttpparser 依賴 SSE4.2 和 CMPESTRI x86_64 的特性做解析

Python 是有垃圾收集功能的語言,為避免不必要的增加垃圾收集器的壓力,在設(shè)計(jì)高性能系統(tǒng)時(shí)一定要多加注意。Japronto 的內(nèi)部被設(shè)計(jì)的嘗試避免循環(huán)引用和盡可能少的分配、釋放內(nèi)存,它會(huì)預(yù)先申請(qǐng)一塊區(qū)域來存放對(duì)象各種,同時(shí)嘗試在后續(xù)請(qǐng)求中重用那些沒有被繼續(xù)引用的 Python 的對(duì)象,而不是將那些對(duì)象直接扔掉。

這些預(yù)先申請(qǐng)的內(nèi)存的大小被固定為 4KB 的倍數(shù)。內(nèi)部結(jié)構(gòu)會(huì)非常小心和頻繁的使用這些連續(xù)的內(nèi)存區(qū)域,以減少緩存失效的可能性。 

Japronto 會(huì)盡可能避免不必要的緩存間復(fù)制,只在正確的位置執(zhí)行操作。比如,在處理路由時(shí),先做 URL 解碼再進(jìn)行路由匹配。 

開源貢獻(xiàn)者們,我需要你們的幫助 

我已經(jīng)連續(xù)不斷的開發(fā) Japronto 超過三個(gè)月,不光在每一個(gè)工作日,周末也無休。除了每天的工作外,我把所有時(shí)間精力都投入到這個(gè)項(xiàng)目上了。 

我想是時(shí)候和社區(qū)分享我的勞動(dòng)果實(shí)了。 

Japronto 已經(jīng)可靠的實(shí)現(xiàn)了下面這些功能: 

  • 實(shí)現(xiàn) HTTP 1.x 并且支持分片上傳
  • 完整支持 HTTP 流水線
  • 可配置是否讓鏈接 Keep-alive
  • 支持同步和異步視圖
  • Master-multiworker 多任務(wù)處理
  • 代碼熱加載
  • 簡(jiǎn)單易用的路由規(guī)則

下一次,我將深入研究關(guān)于 Websockets 和 HTTP 異步應(yīng)答數(shù)據(jù)流。 

寫文檔和做測(cè)試還有許多工作要做,如果你有興趣加入我,請(qǐng)?jiān)?Twitter 上直接聯(lián)系我. 這里是 Japronto 的 GitHub 項(xiàng)目倉庫. 

同時(shí),如果你的公司正在尋找熟悉性能優(yōu)化和 DevOps 的 Python 工程師,我很樂意為你效勞,在全球任何地方都可以。 

結(jié)束語 

上面提到的所有技術(shù)不只適用于 Python,也同樣可以被應(yīng)用到其它語言,如 Ruby、JavaScript,甚至 PHP 等。我非常感興趣去付諸實(shí)踐,但是,除非有人能在這事上投入資金支持,恐怕我沒有足夠的精力去完成。 

在此我要感謝 Python 社區(qū)為優(yōu)化性能所付出的持續(xù)投入。尤其是 Victor Stinner @VictorStinner、INADA Naoki @methane 和 Yury Selivanov @1st1 以及整個(gè) PyPy 團(tuán)隊(duì)。 

獻(xiàn)給我摯愛的 Python。

原文鏈接:http://www.iteye.com/news/32363 

責(zé)任編輯:龐桂玉 來源: 馬哥Linux運(yùn)維
相關(guān)推薦

2017-04-24 14:39:01

PythonHTTP語言

2020-05-27 11:31:43

Python 開發(fā)程序員

2020-03-30 15:04:10

數(shù)據(jù)庫工具技術(shù)

2022-08-23 07:38:26

谷歌DDoS攻擊

2021-08-30 09:36:09

DDoS攻擊網(wǎng)絡(luò)攻擊網(wǎng)絡(luò)安全

2010-10-27 09:09:21

NoSQL

2012-03-27 16:09:33

憤怒的小鳥太空版

2012-07-23 10:19:08

微軟Azure云計(jì)算

2015-12-11 17:18:34

2018-11-06 09:20:34

Netflix負(fù)載均衡云網(wǎng)關(guān)

2020-06-22 10:03:27

安全網(wǎng)絡(luò)攻擊技術(shù)

2011-12-06 20:52:03

移動(dòng)支付

2024-02-29 10:19:23

2011-09-06 09:48:41

MTK平臺(tái)

2011-05-20 11:34:27

iOS游戲App StoreiOS

2021-09-01 13:54:58

卡巴斯基惡意軟件網(wǎng)絡(luò)安全

2023-05-18 22:22:19

2025-04-03 15:28:20

2011-12-14 09:55:36

AiriSiri

2013-09-13 10:16:34

Windows 8.1
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)