比如:
100 萬(wàn) QPS 、4G 數(shù)據(jù)
4 萬(wàn) QPS 、400G 數(shù)據(jù)
兩種場(chǎng)景怎么架構(gòu) redis
https://www.infoq.cn/article/cS_Pp9r8Gjd9bpGpjTTv 攜程的 redis 容器化 其中有一段寫到:Master 掛了不希望 K8S 立刻把它拉起來(lái),希望哨兵來(lái)感知到它,因?yàn)?K8S 如果在哨兵感知前拉起了它,導(dǎo)致哨兵還沒(méi)切換 Master/Slave,Master 就活過(guò)來(lái)并且數(shù)據(jù)都丟失,這時(shí)候一同步到 Slave 上數(shù)據(jù)也全沒(méi)有了,等于執(zhí)行了一個(gè)清空操作,這對(duì)于業(yè)務(wù)和 DBA 來(lái)說(shuō)是不能接受的。 這種情況出現(xiàn)的原理是什么? Master 在掛了重新被拉起來(lái),為什么數(shù)據(jù)會(huì)全部丟失?看上去這里的意思是指 Master 里的數(shù)據(jù)一點(diǎn)都沒(méi)有了,不是指在 Master 掛了的時(shí)刻沒(méi)有持久化的數(shù)據(jù)沒(méi)有了。百思不得其解。。。。
https://docs.djangoproject.com/en/3.1/releases/3.1/
沒(méi)看到有人發(fā),我來(lái)發(fā)一下好了 新增 view 和 middleware 的異步支持,可以在 view 上用 async def 了。ORM 的異步支持接下來(lái)的版本會(huì)繼續(xù)做 JSONField 已經(jīng)支持所有的數(shù)據(jù)庫(kù),用 MySQL 的想要這個(gè)特性可以不再需要 Django-MySQL 了
Django 毫無(wú)疑問(wèn)是最好的 Python Web 框架,開發(fā)團(tuán)隊(duì)也是相當(dāng)孜孜不倦…
1.每天的數(shù)據(jù)量很大,大概 5 億多條,如果用 mysql 存儲(chǔ),再用來(lái)查詢監(jiān)控,肯定不行的。 那么用什么來(lái)存儲(chǔ)呢?
2.數(shù)據(jù)監(jiān)控報(bào)警,可以知道當(dāng)前金幣發(fā)放的數(shù)據(jù)量,如果超過(guò) /少于 3 天前,7 天前的數(shù)據(jù)量 10%,就發(fā)出報(bào)警, 用什么開源的工具可以快速實(shí)現(xiàn)呢?
之前運(yùn)維架構(gòu)基于傳統(tǒng)的虛擬云主機(jī)和其他 IaaS 之上的,傳統(tǒng)云主機(jī)運(yùn)維的可以通過(guò)堡壘機(jī)保證操作都記錄下來(lái),滿足等保要求。如果運(yùn)維架構(gòu)遷移到 K8S 上之后應(yīng)該怎樣滿足等保合規(guī)的要求?
老哥們,作為程序員,業(yè)務(wù)晚上會(huì)報(bào)警,自己一個(gè)人還好,影響家里人休息,大家咋處理的。
前情
在疫情期間自己學(xué)習(xí)了 React 開發(fā)了一個(gè) AWS 中國(guó)器的計(jì)算器 https://v2ex.com/t/679030 , 當(dāng)時(shí)核心的動(dòng)機(jī)是 解決日常工作中使用 AWS 中國(guó)區(qū)中成本相關(guān)的問(wèn)題 React 練手
更新
在 V2 上多次看到前端和后端同學(xué)關(guān)于 React/Vue 的積極討論, 作為一個(gè)背鍋工程師, 反正大家寫什么都需要運(yùn)維, 就都學(xué)習(xí)一下, 這樣也能和前端同學(xué)友好交流. 所有就有了這個(gè) 基于 Vue 的 flashcard 項(xiàng)目.
https://flashcards.engineerdraft.com/cost
此次動(dòng)機(jī) Vue 練手, 只是學(xué)習(xí)沒(méi)有應(yīng)用沒(méi)有啥意思 希望可以通過(guò) flashcards 的題目來(lái)引導(dǎo)大家使用 計(jì)算器 , 來(lái)找到答案.
當(dāng)然我也準(zhǔn)備了 容器 和 DNS 相關(guān)的題目, 后續(xù)也會(huì)更新一些小題目來(lái)幫助
引子
看到前后端同學(xué)關(guān)于 React/Vue 進(jìn)行各種有意義的"探討", 作為默默無(wú)聞的運(yùn)維同學(xué)決定不再沉默, 結(jié)合自己工作的問(wèn)題, 偷偷造了一個(gè)輪子: AWS 中國(guó)區(qū)(EC2/RDS/Elasticache) 計(jì)算器分享 https://cloud.engineerdraft.com/
背景
公司的業(yè)務(wù)運(yùn)行在 AWS 中國(guó)區(qū)上, 由于我們是一家有技(暫)術(shù)(不)追(盈)求(利)的科技創(chuàng)新公司, 在日常運(yùn)維中, 我們?cè)谌绾翁胬习骞?jié)省成本上進(jìn)行各種折騰(北京 Region 遷移 寧夏 Region, 實(shí)例調(diào)整和匹配, 預(yù)留實(shí)例, Spot Instance)等, 在這過(guò)程中我們經(jīng)常會(huì)遇到這樣的問(wèn)題 我如何快速知道一臺(tái) EC2 的配置和各種價(jià)格(OnDeman, Not Upfront, etc)差別 ? 從而選擇價(jià)格最優(yōu)的機(jī)型. 目前線上 CPU Bound 的業(yè)務(wù)跑在一臺(tái) 8 GB 內(nèi)存的機(jī)器(C5.xlarge), 我可以換成其他的什么機(jī)型? 從而合理優(yōu)化使用機(jī)型. 在遷移北京 Region 到 寧夏 Region 中, 我想要知道 AWS 在不同 Region 的價(jià)格差別多少? 從而評(píng)估遷移 Region 的收益. 業(yè)務(wù)要上線一個(gè)新的服務(wù), 個(gè)新服務(wù)每個(gè)月大概的 AWS 費(fèi)用支出多少? 從而合理評(píng)估項(xiàng)目的成本. AWS 中國(guó)在追趕 Global 的道路上前進(jìn)了一步, 支持了一個(gè)新的機(jī)型 :-), 和舊機(jī)型(配置, 價(jià)格, 性能)對(duì)比變化了什么? 從而科學(xué)評(píng)估是否遷移新機(jī)型.
發(fā)現(xiàn)目前市面上并沒(méi)有特別趁手的工具, 比較接近的是 云勢(shì)數(shù)據(jù)計(jì)算器 , 個(gè)人最開始也是用了一陣, 總體上還是不錯(cuò)的, 但是在一些場(chǎng)景下(比如: 我需要快速找到一個(gè)機(jī)型不支持 search, 不能快速對(duì)比北京和寧夏實(shí)例的價(jià)格差別等), 所以自己造了一個(gè)輪子, 分享給大家, 希望可以幫助同樣在使用 AWS 中國(guó)的同學(xué).
特殊說(shuō)明
由于定位是效率工具, 只考慮了 PC 上展示.
最近在兩臺(tái)服務(wù)器上線了一個(gè)程序,相同的 cpu,都是 centos7,都沒(méi)有 cpufreq governor,但是一個(gè)用 perf stat 抓到的 cycles 只能達(dá)到基準(zhǔn)頻率,而另外一遍能達(dá)到最高的睿頻,兩臺(tái)機(jī)器都比較空閑,可以認(rèn)為還有大量閑置資源,閑置有點(diǎn)不大理解為什么會(huì)有這樣的區(qū)別。
為了說(shuō)明問(wèn)題,用服務(wù)器 1 代替有問(wèn)題的,服務(wù)器 2 代替正常運(yùn)行的。
為了排除 cpu 遷移的問(wèn)題,在服務(wù)器 1 上添加了 cpu binding,結(jié)果基本沒(méi)差別,為了排除 io 的差異,用 tmpfs 直接接管了服務(wù)器 1 的 io 操作,現(xiàn)在服務(wù)器 1 用 perf 抓仍然跑在基頻,不知道有同學(xué)有相關(guān)經(jīng)驗(yàn)沒(méi),求教。
非常感謝。
目前該問(wèn)題的影響面廣不廣,這個(gè)還暫時(shí)未知,不過(guò)根據(jù)我遇到的情況來(lái)看,影響大多在服務(wù)器端的外部服務(wù)之間的調(diào)用。對(duì) web 用戶端來(lái)說(shuō),因?yàn)闉g覽器內(nèi)證書鏈?zhǔn)歉碌?不涉及該問(wèn)題。但對(duì)于 服務(wù)端來(lái)說(shuō),對(duì)于一些對(duì)外調(diào)用的 https 請(qǐng)求,如果對(duì)方域名證書鏈中涉及到該過(guò)期 CA 的話,可能會(huì)訪問(wèn)失敗。
Tips1:如果你的應(yīng)用程序的部署方式是直接運(yùn)行在主機(jī)上的話,可以使用配置管理工具( ansible/saltstack ),統(tǒng)一修改。如果是容器話部署的情況,可能涉及的稍微多一些,需要修改項(xiàng)目的 Dockerfile,之后滾動(dòng)更新該服務(wù)(當(dāng)然如果你的應(yīng)用不涉及到對(duì)外訪問(wèn) https/ssl 調(diào)用,理論上可以延后更改?。?
Tips2: 刪除過(guò)期證書后,記得要重啟主機(jī)上運(yùn)行的服務(wù)??!
詳見: resolve-certificate-verify-failed-with-2020-may-30
有啥免費(fèi)好用的 linux 運(yùn)維管理工具推薦呢? 除了 ansible,SaltStack,Puppet 這些。
輕量級(jí)的,支持批量執(zhí)行 sh,py,sql 腳本, 批量上傳文件,支持主機(jī)、服務(wù)分組管理這些,
功能不需要多,簡(jiǎn)單,穩(wěn)定,安全可靠就好。
最近關(guān)于個(gè)人服務(wù)器的運(yùn)維和管理,寫了一系列文章,可供參考: https://github.com/shfshanyue/op-note
目前,有一個(gè)簡(jiǎn)單的站點(diǎn)部署在上邊 https://shici.xiange.tech
今天早上來(lái)公司發(fā)現(xiàn) mysql 被刪了...只留下了比特幣地址和郵箱.搜地址和數(shù)據(jù)庫(kù)關(guān)鍵詞發(fā)現(xiàn)這幾天有好多人中招....現(xiàn)在恢復(fù)了表....做了自動(dòng)快照,寶塔后臺(tái)也開通了網(wǎng)站防火墻,修改了數(shù)據(jù)庫(kù)密碼,限制了指定 ip 登錄.....不知道有沒(méi)有用,有大佬有類似的經(jīng)驗(yàn)么,這種會(huì)不會(huì)來(lái)第二次
公司目前希望能固定化下來(lái) CI/CD 流程. 這樣方便公司統(tǒng)一去管理. 固定的流程會(huì)減少開發(fā)的理解成本. 但也帶來(lái)了一些問(wèn)題.一些需要自由度比較高的項(xiàng)目, 或者一些小小的改動(dòng)都有可能沖擊之前的固化流程. 如果是做平臺(tái), 個(gè)人感覺反而開發(fā)可以定制化構(gòu)建步驟更好一些. 平臺(tái)方只需要給開發(fā)一系列的步驟來(lái)滿足構(gòu)建部署需求.
接口日志是記錄在哪里? 日志文件嗎? 是否將接口請(qǐng)求的 request header 和傳入的參數(shù),服務(wù)端輸出的 response header 和數(shù)據(jù)都記錄到日志里? 業(yè)務(wù)中日志記錄是否有規(guī)范,比如要求按某種格式寫:“{觸發(fā)記錄日志的文件名和行數(shù)} {原因} {其他涉及的參數(shù)}”
我在的公司記錄的是日志文件,查看日志只能才 FTP 上下載日志文件下來(lái)看,有時(shí)候日志文件幾十 M,下載的時(shí)候還會(huì)拖到服務(wù)器的帶寬,感覺這個(gè)做法不好
win 控制 linux 被控機(jī)。linux 控制 linux 被控機(jī)?;?powershell 腳本。100%支持 linux 的 bash 腳本。100%支持 win 的 bat 腳本。因?yàn)槭悄_本,通過(guò)膠水,間接 100%支持 csh,zsh,vbs 等。 主控機(jī)支持:win10,win2012r2,win2016,win2019,centos7,centos8,ubuntu1404,ubuntu1604,ubuntu1804,debian8,debian9,debian10, 被控機(jī)支持:win7,win2008r2,win10,win2012,win2016,win2019,centos7,centos8,ubuntu1404,ubuntu1604,ubuntu1804,debian8,debian9,debian10 卡死你 3000 主控機(jī)安裝: https://gitee.com/chuanjiao10/kasini3000/wikis/安裝 win 版卡死你 3000 主控機(jī)https://gitee.com/chuanjiao10/kasini3000/wikis/安裝 linux 版卡死你 3000 主控機(jī)使用: 1 按照 https://gitee.com/chuanjiao10/kasini3000/tree/master/docs/examples/nodelist.csv 編寫被控機(jī) ip、端口、賬戶、密碼、并保存在 c:\ProgramData\kasini3000\nodelist.csv 2 c:\ProgramData\kasini3000\k-console.ps1 k-console.ps1 有 2 個(gè)快捷方式。kc=用穩(wěn)定版 pwsh。kcp=用 psv7 版 pwsh,建議用 kcp 3 cdip 192.168.1.2 #選中被控機(jī) 4 kct #復(fù)制文件,從主控機(jī)到被控機(jī) 5 kcf #復(fù)制文件,從被控機(jī)到主控機(jī) 6 gtbkj #進(jìn)入被控機(jī)命令行 7 .\krun.ps1 -腳本文件名 d:
https://jiajunhuang.com/articles/2020_02_19-should_i_use_microservice.md.html
微服務(wù),火了好幾年的東西。曾經(jīng)我們看中的是微服務(wù)拆分之后,每個(gè)項(xiàng)目變得更小,對(duì)團(tuán)隊(duì)的每個(gè)人來(lái)說(shuō)維護(hù)成本降低,因?yàn)樾枰私?的東西局限于一個(gè)更小的服務(wù)。第二是加強(qiáng)了技術(shù)選型的靈活性。但是由于沒(méi)有實(shí)踐,并不知道微服務(wù)會(huì)帶來(lái)什么大的問(wèn)題。 當(dāng)我們大規(guī)模應(yīng)用微服務(wù)之后,問(wèn)題才開始慢慢顯現(xiàn)出來(lái)。 網(wǎng)絡(luò)調(diào)用過(guò)多 技術(shù)棧太過(guò)靈活 難于應(yīng)對(duì)連表查詢的需求 核心應(yīng)用崩潰會(huì)導(dǎo)致大面積癱瘓 運(yùn)維成本增加 接口風(fēng)格不一致
上面就是個(gè)人總結(jié)的一些微服務(wù)所帶來(lái)的問(wèn)題。對(duì)每個(gè)缺點(diǎn)的詳細(xì)說(shuō)明請(qǐng)看原文 :)
我一般是放 /opt,也見過(guò)放在 /var 和 home 下的
現(xiàn)在用兩臺(tái)配置了 LVS(DR)模式做端口轉(zhuǎn)發(fā)+高可用,后端是兩臺(tái) apache http server 做正向代理。最近有個(gè)奇怪得問(wèn)題,apache 代理的某個(gè) URL 變慢了,導(dǎo)致了 Client 端訪問(wèn) LVS 提供的虛 IP+端口出現(xiàn)了大量的 Connection Timeout 和 Connection Refused 錯(cuò)誤,我用 telnet 測(cè)試是瞬間 Connection Refused。把 LVS APACHE 和這四臺(tái)機(jī)器的內(nèi)核參數(shù)查了一遍,好像也沒(méi)什么問(wèn)題。大佬能提供一個(gè)排查的思路嗎?
有沒(méi)有正在使用的呀?定制化程度怎么樣? 了解騰訊內(nèi)部使用情況? 有游戲公司在使用么? 運(yùn)維平臺(tái)推薦? 謝謝了??!
Python 寫了一些 Devops (運(yùn)維)相關(guān)的系統(tǒng),這些系統(tǒng)都在我們內(nèi)部跑了很久,效果顯著成績(jī)斐然,這里給匯總了下,對(duì) Devops 感興趣的小伙伴可以看看,有私有有開源
https://ops-coffee.cn/devops
看得教程一頭霧水, 只能理解那個(gè)自帶的 http 請(qǐng)求, 看了很久也沒(méi)看到有比如數(shù)據(jù)庫(kù)查詢, 文件處理什么的其他例子, 后來(lái)去看看其他教程, 實(shí)現(xiàn)倒算是勉強(qiáng)實(shí)現(xiàn)了, 但感覺也太復(fù)雜了吧? ?
就比如例子中的我假設(shè)有個(gè)長(zhǎng)耗時(shí)的任務(wù), 怎么寫才會(huì)簡(jiǎn)單點(diǎn)? import tornado.ioloop import tornado.web import time import _thread # 模擬耗時(shí)任務(wù) def long_work(arg): time.sleep(5) yield arg * 1024 def mycoroutine(func): def wrapper(self): gen = func(self) work_gen = next(gen) def fun(): result = next(work_gen) try: gen.send(result) except StopIteration: pass _thread.start_new_thread(fun, ()) return wrapper class IndexHandler(tornado.web.RequestHandler): @tornado.web.asynchronous @mycoroutine def get(self): arg = 10 # 假設(shè)請(qǐng)求的參數(shù) result = yield long_work(arg) self.finish(f'
Index {result}
') class SyncHandler(tornado.web.RequestHandler): def get(self): self.write('SyncHandler
') def make_app(): return tornado.web.Application([ (r'/', IndexHandler), (r'/sync', SyncHandler) ]) if __name__ == '__main__': app = make_app() app.listen(8888) tornado.ioloop.IOLoop.current().start() 小白 python tornado 也不熟 剛試著用 需要配置兩個(gè)端口來(lái)保證 一個(gè)端口掛了另一個(gè)會(huì)起來(lái) 服務(wù)不會(huì)終止 通過(guò) nginx 要怎么配置? 要哭了 不會(huì)做 很尷尬
比如說(shuō)要等某個(gè)耗時(shí)操作的結(jié)果, 該怎么寫?
網(wǎng)上看了半天例子, 照著做了做, 貌似行不通
class AsyncTaskHandler(tornado.web.RequestHandler): @tornado.web.asynchronous @tornado.gen.coroutine def get(self, *args, **kwargs): resp = yield tornado.gen.Task(self.do_something) self.finish(resp) @tornado.gen.coroutine def do_something(self, *args, **kwargs): time.sleep(10) return {'message': 'OKOK'}
按網(wǎng)上的方法更改了配置后,單純本地打開 html 文件是顯示有圖片上傳的選項(xiàng)的, 但服務(wù)跑起來(lái)的方式打開的話, 就沒(méi)有了, 這是怎么回事??
記得先前有個(gè) issue 提及到 routing 的問(wèn)題的,深夜翻一下 Tornado 的代碼,剛剛好遇上 update 到 v4.5多了這么一個(gè) routing 的實(shí)現(xiàn),終于有了一個(gè)官方點(diǎn)的稍微好看優(yōu)雅點(diǎn)的方式去組織 Tornado 的 Application 和 Handler 了 直接看代碼吧 https://github.com/tornadoweb/tornado/blob/master/tornado/routing.py 官方的文檔都還沒(méi)有更新Tornado 的代碼寫得挺優(yōu)雅的,很適合圍觀
看博客上面的評(píng)測(cè),性能表現(xiàn)很不錯(cuò)。https://morepypy.blogspot.jp/2017/03/async-http-benchmarks-on-pypy3.html?m=1 UVloop 新版本也開放了對(duì) tornado 的支持。 https://github.com/Magicstack/uvloop/issues/35 看目前網(wǎng)絡(luò)上面的評(píng)測(cè) sanic+uvloop 評(píng)測(cè)數(shù)據(jù)遙遙領(lǐng)先。 如果 pypy 支持 Python3.5 之后, pypy+uvloop+tornado 可以跑出什么樣的數(shù)據(jù)?
用下面的代碼做文件上傳,在自己電腦測(cè)試能夠成功上傳,到局域網(wǎng)其他電腦測(cè)試,顯示 finished!了,但是沒(méi)看到文件,請(qǐng)問(wèn)前輩,是什么原因呢?該代碼運(yùn)行在 xp 系統(tǒng)上,上傳文件夾已設(shè)置最高權(quán)限。import tornado.ioloop import tornado.web import shutil import os class UploadFileHandler(tornado.web.RequestHandler): def get(self): self.write('''
Upload File
''') def post(self): upload_path=os.path.join(os.path.dirname(__file__),'files') #文件的暫存路徑 file_metas=self.request.files['file'] #提取表單中‘ name ’為‘ file ’的文件元數(shù)據(jù) for meta in file_metas: filename=meta['filename'] filepath=os.path.join(upload_path,filename) with open(filepath,'wb') as up: #有些文件需要已二進(jìn)制的形式存儲(chǔ),實(shí)際中可以更改 up.write(meta['body']) self.write('finished!') app=tornado.web.Application([ (r'/file',UploadFileHandler), ]) if __name__ == '__main__': app.listen(3000) tornado.ioloop.IOLoop.instance().start()
是不是就不用增加 XSRF 的支持了,畢竟這個(gè)還是用來(lái)處理 cookie 的。
現(xiàn)在的需求是:手機(jī) app 上傳圖片->tornado 調(diào)用 c++算法庫(kù)處理->向手機(jī)返回結(jié)果。 目前遇到的問(wèn)題是 c++算法庫(kù)需要耗時(shí) 1 秒左右,這樣會(huì)把整個(gè) tornado 阻塞住吧?有什么好的異步解決方法或思路嗎? 請(qǐng)問(wèn)我這個(gè)需求可以用協(xié)程的方式解決嗎?還是用多進(jìn)程的方式解決?
打算好好學(xué)習(xí)下 tornado ,請(qǐng)大家推薦一些好的 tornado 項(xiàng)目,謝謝
最近在用 Python 開發(fā)一個(gè)自己的網(wǎng)站,要用到七牛做為網(wǎng)站的 storage ,但是七牛官方 sdk 不支持異步,所以打算自己寫一個(gè)異步的 sdk 。寫出來(lái)之后自己用著還可以,所以想給大家分享一下,不喜勿噴。
python version : >=3.4
github: https://github.com/free-free/tornaqiniu
doc: https://github.com/free-free/tornaqiniu
tornado 可以使用如下方式并行異步請(qǐng)求。 @gen.coroutine def get(self): http_client = AsyncHTTPClient() response1, response2 = yield [http_client.fetch(url1), http_client.fetch(url2)]
這個(gè)時(shí)候, 1,2 是同時(shí)發(fā)送出去的,也就是說(shuō)使用這種方式,可以讓 n 個(gè)請(qǐng)求,同時(shí)發(fā)出去,等他們都返回了再統(tǒng)一返回。
那么我要如何保證,其中一個(gè)請(qǐng)求壞了,其余的結(jié)果依舊可用?
剛開始學(xué) tornado ,它的異常處理機(jī)制有點(diǎn)弄不明白。
寫了一個(gè)測(cè)試用的小腳本,期望遇到 404 的時(shí)候能夠觸發(fā)我自己聲明的 write_error 函數(shù),然而 write_error 并沒(méi)有生效,輸出的是 tornado 默認(rèn)的 404 頁(yè)面。
代碼如下: #!/bin/env python3.5 #coding:utf-8 import os import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web from tornado.options import define, options define("port", default=8000, help="端口", type=int) class BaseHandler(tornado.web.RequestHandler): def write_error(self, stat, **kw): self.write('Func write_error !') class IndexHandler(BaseHandler): def get(self): self.write('hello') handlers = [ (r'/index', IndexHandler), ] settings = { 'template_path': os.path.join(os.path.dirname(__file__), "templates"), 'static_path': os.path.join(os.path.dirname(__file__), 'static'), } if __name__ == '__main__': tornado.options.parse_command_line() app = tornado.web.Application(handlers=handlers, **settings) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) print(options.port) tornado.ioloop.IOLoop.instance().start()
然后去 google 了一下,把 BaseHandler 成了這樣,但是 404 的時(shí)候還是返回了默認(rèn)的 404 頁(yè)面: class BaseHandler(tornado.web.RequestHandler): def _handle_request_exception(self, e): self.write_error(404) def send_error(self, stat, **kw): self.write_error(404) def write_error(self, stat, **kw): self.write('Func write_error !')
在 localhost 下測(cè)試,像 demo 一樣, get 或 post 里面沒(méi)有任何多余的耗時(shí)代碼,直接返回。得到的結(jié)果是每秒 200 多的并發(fā)數(shù),這正常么? 目前系統(tǒng)是 win7 , CPU 是 E3 1231 , 從任務(wù)管理器來(lái)看,似乎是單線程跑滿了(因?yàn)檫M(jìn)程的 CPU 占用率為 13 )。 各位用 tornado 的朋友也是同樣的結(jié)果么? 還是說(shuō)哪里有坑?
下面是 tornado.httpclient.AsyncHTTPClient 類的 fetch() 方法的源代碼。我沒(méi)有在里面找到任何"fetch"的動(dòng)作,它是怎么實(shí)現(xiàn) “ Executes a request, asynchronously returning an HTTPResponse ”的?
完整代碼在: https://github.com/tornadoweb/tornado/blob/master/tornado/httpclient.py def fetch ( self , request , callback = None , raise_error = True , ** kwargs ): """Executes a request, asynchronously returning an `HTTPResponse`. The request may be either a string URL or an `HTTPRequest` object. If it is a string, we construct an `HTTPRequest` using any additional kwargs: ``HTTPRequest(request, **kwargs)`` This method returns a `.Future` whose result is an `HTTPResponse`. By default, the ``Future`` will raise an `HTTPError` if the request returned a non-200 response code (other errors may also be raised if the server could not be contacted). Instead, if ``raise_error`` is set to False, the response will always be returned regardless of the response code. If a ``callback`` is given, it will be invoked with the `HTTPResponse`. In the callback interface, `HTTPError` is not automatically raised. Instead, you must check the response's ``error`` attribute or call its `~HTTPResponse.rethrow` method. """ if self . _closed : raise RuntimeError ( "fetch() called on closed AsyncHTTPClient" ) if not isinstance ( request , HTTPRequest ): request = HTTPRequest ( url = request , ** kwargs ) else : if kwargs : raise ValueError ( "kwargs can't be used if request is an HTTPRequest object" ) # We may modify this (to add Host, Accept-Encoding, etc), # so make sure we don't modify the caller's object. This is also # where normal dicts get converted to HTTPHeaders objects. request . headers = httputil . HTTPHeaders ( request . headers ) request = _RequestProxy ( request , self . defaults ) future = TracebackFuture () if callback is not None : callback = stack_context . wrap ( callback ) def handle_future ( future ): exc = future . exception () if isinstance ( exc , HTTPError ) and exc . response is not None : response = exc . response elif exc is not None : response = HTTPResponse ( request , 599 , error = exc , request_time = time . time () - request . start_time ) else : response = future . result () self . io_loop . add_callback ( callback , response ) future . add_done_callback ( handle_future ) def handle_response ( response ): if raise_error and response . error : future . set_exception ( response . error ) else : future . set_result ( response ) self . fetch_impl ( request , handle_response ) return future def fetch_impl ( self , request , callback ): raise NotImplementedError ()
180.150.179.13 和 180.150.179.12 都無(wú)法 ping 通,一個(gè)小時(shí)了。。。