软件巨头卧谈会
深夜時分,忙碌了一天的機房里逐漸安靜下來,幾個軟件巨頭nginx, Tomcat, Redis, Node.js又開始夜談了。?
nginx伸了一個懶腰:哎喲,今天可累死我了,高峰期我居然維持了上萬個連接,人類可真會壓榨我啊,就給我這么一臺破機器!?
Tomcat :得了吧老弟,我知道你用的epoll很厲害, 但是你只是“維持”了連接而已,通過這些連接發過來的數據請求,你一個都不管,都分給我們Tomcat集群了,我們才是真苦逼啊!
nginx:誰說的?那些對靜態文件的請求我不都處理了嗎?都沒往你那里發。?
Tomcat :處理個靜態文件算啥!關鍵是用戶發過來的動態請求,需要訪問數據庫,訪問緩存,訪問MQ,訪問微服務,執行業務邏輯,這才是要命的東西!
nginx覺得被Tomcat打擊到了,立刻反擊:我看了一下,你線程池里有幾十個線程仆人給你干活,是你管理不善吧, 你看看0x7954, ?向數據庫發了個SQL就坐在那里喝茶了。還有0x6904,剛才訪問了一下微服務,這躺在那里睡半天了, 你也不管管。?
Tomcat :唉,我也沒法管啊,他們倆停下里休息,還不是遇到了耗時的操作?阻塞住了!不等著怎么辦?還有啊, 我的機器CPU只有4個核心,同一時刻只能有4個線程仆人能執行,操作系統老大要對他們做輪換, 總得有人歇著, 要是有100個CPU核心就好了。?
Redis :別做夢了,怎么可能有100個核心 !? Tomcat 兄, 你看看我這里只有一個線程仆人在處理對緩存的讀寫請求,不也干得好好的, 你瞧瞧我這個仆人是怎么干活的,多勤快!
Tomcat大為吃驚: 哦? 你只有一個仆人? ?執行這么多緩存的命令!你這個仆人是超人啊!
Redis :超人談不上,他只要挨個執行任務就可以了。單線程還有個額外的好處,不用對內存的數據加鎖。
Tomcat:真是讓我羨慕啊,我這里多線程弄不好就出現死鎖,頭疼。
Nginx 笑道:Tomcat老兄,你可以仿照Redis的方式來,把那些線程懶仆人都開除了,只留一個,你給他多發三倍工資,他也會變成超人的。
Tomcat動心了,不過他思考了一會兒,發現了問題的本質
Tomcat :不對,不對, 你們倆這是給我挖坑。Redis的那些任務都是內存操作,內存的訪問多快啊,100納秒左右就行了,我Tomcat處理的任務都是文件,數據,網絡這些操作,需要10到幾百毫秒。? 我要是按照Redis的路數,就會變成這樣了:?
Tomcat :看到了吧,0x7954還得歇著喝茶。本質就是任務太耗時,阻塞住了, 還得用多個線程來處理!
Node.js 半天沒吭聲,這時候跳了出來 :Tomcat兄,此言差矣, 任務太耗時,也可以用單線程啊!你把它搞成異步的不就行了!?
Tomcat : 異步?怎么異步?我的超級線程0x7954遇到了訪問數據庫的任務,很耗時,他不歇著還能怎么辦??
Node.js:簡單啊,執行下一個任務!但是,在執行之前,要給0x7954安插一個回調函數,等到數據庫返回數據了,通知0x7954執行這個回調函數,處理返回數據不就行了!
Tomcat :聽起來不錯啊,一個線程就把所有的事情做完了,還不用歇著 !?
Node.js:是啊是啊,我一直就是這么干的,這就叫“單線程,非阻塞IO,事件循環”
Tomcat很羨慕這種方式,他又思考了一會兒,發現了問題。
Tomcat : 不對啊,如果想用單線程,那所有的I/O操作都必須是非阻塞的,如果有一個不是,那我唯一的仆人就沒法去干別的事情了。
Node.js:嘿嘿,Tomcat兄臺還是挺厲害的嘛,我會盡最大的努力使用非阻塞的方式來處理所有的I/O ,對于那些實在搞不定的 ,比如Linux文件I/O,DNS,CPU密集型的任務如加密,壓縮等,嘿嘿,我就用個線程池!?
Tomcat :說來說去,又回到了線程池!
Node.js :嘿嘿,沒有完美的事物嘛, 大部分都是非阻塞的操作,只有少部分才需要線程池的支持。?
Tomcat 嘆了口氣:唉!我要是想改成你這樣,還挺費勁的。
Vert.x :Tomcat兄,不用羨慕Node.js, 咱們Java 也能實現這種純粹異步的編程, 你看看我,不就是這樣嗎?碼農翻身的這篇文章已經說得很清楚了:《Java能抵擋住JavaScript的進攻嗎?》
Tomcat :果然,我大Java無所不能啊,哈哈。
突然間,系統的流量暴增
Nginx :怎么回事?大半夜的,怎么突然來了這多連接??
Redis:慘了慘了,臨近618, 估計人類搞了什么活動,每次搞活動,我這里都壓力山大,兄弟們,別聊了,忙起來吧!
總結
- 上一篇: 小姐姐用动图展示 10 大 Git 命令
- 下一篇: 神仙打架:PG 和 MySQL 到底哪个