JavaScript的進攻前端
公元2014年,Java 第八代國王終於登上了王位。web
第一次早朝,國王坐在高高的寶座上,看着畢恭畢敬的大臣,第一次體會到了皇權的威力。數據庫
德高望重的IO大臣顫悠悠地走上前來:「啓稟陛下,昨日收到戰報,有個叫作Node.js的番邦又一次向我國進攻,我邊防將士死傷慘重。」編程
「Node.js? 那是什麼東西?」 國王心中一樂, 還真有人自不量力,想不自量力。 想我Java帝國人口之衆多,疆域之廣闊,踩死你小番邦還不像踩死一隻螞蟻似的。後端
「那是用JavaScript寫的一個框架。」 IO大臣看到國王不知道Node.js,內心一沉。瀏覽器
「JavaScript? 愛卿說笑了,一個在瀏覽器中運行的東西,怎麼可能進攻我Java後端。」服務器
「陛下有所不知,這JavaScript發展迅猛,不只佔領了前端,還經過Node.js向後端,尤爲是我國滲透,臣還據說他們用Electron開始蠶食桌面開發了!」微信
「竟有這等事!難道他們想通吃? 咱們不是有Tomcat嗎? 派Tomcat去把Node.js給鎮壓了。」架構
國王開始怨恨本身的父親JDK 7世和祖父JDK 6世沒把這個Node.js當成一回事,沒有把Node.js給扼殺在搖籃之中,把這個禍害留給了本身,內心開始發虛。併發
非阻塞異步IO
線程大臣走上前來:「陛下,Tomcat已經率軍和Node.js惡戰了幾日,敗下陣來, 這Node.js有個獨門武器,叫作‘非阻塞異步IO’。」
「非阻塞? 我據說咱們的Tomcat也能實現非阻塞啊!」 王國有點驚訝。
「不行的,陛下,Tomcat在處理鏈接的時候能實現非阻塞,可是在真正處理請求的時候仍是須要同步操做,一個請求對應一個線程來處理,不像Node.js那樣,都是異步操做,只有一個主線程在忙活。」 線程大臣作了一個簡明扼要的彙報,不知道國王可否聽懂。
(碼農翻身老劉注: Node.js的故事請參見《Node.js: 我只須要一個店小二》)
「衆位愛卿,大家說說該怎麼辦? 總不能讓這小小番邦多次欺負我堂堂Java帝國吧。」
「臣卻是有一計,」 集合大臣說道,「這Node.js雖然來勢洶洶,可是它也有個致命的缺點,那JavaScript是個動態語言,沒法進行編譯時類型檢查,錯誤只有等到運行時才能暴露出來。用它開發個小項目還能夠,一旦項目變大,代碼變多,人員變多,那就會變成噩夢了。」
「愛卿說說具體怎麼辦?」
「咱們能夠派一些臥底去Node.js, 處處傳播這樣的消息,瓦解他們的軍心和士氣,讓他們認爲Node.js寫的系統,很快就會腐化,最終仍是要用我堂堂正正的Java語言來重寫。」
「嗯,此乃心理戰也,至少會穩住一些牆頭草,准奏,由愛卿來安排。 」 國王說道,「不過,此法治標不治本,仍是得想辦法直接把他們戰勝。」
「陛下真乃一代聖君,」 線程大臣立刻開始拍馬屁,與此同時,巧妙地把矛頭轉向老不死的IO大臣:「我Java帝國在第4代國王的時候就出現了非阻塞IO,這麼多年過去了,竟然還沒發展出相似Node.js的系統,實在是不該該啊。」
「老不死」的IO大臣是何等精明:「陛下明鑑, 我Java帝國應用服務器一直以來都是Tomcat獨大,他們採用了線程池,每一個請求一個線程的方式,我也很差干預。」
IO大臣把責任推得一乾二淨。
「沒錯,」 集合大臣爲IO大臣仗義執言,兩肋插刀,「還有一點就是這異步編程,聽起來很好,可是寫起來可就要命了,那麼多的回調,簡直就是反人類,臣民們戲稱爲回調地獄,沒人願意那麼寫,發展不起來也很正常。」
線程大臣立刻接口:「此言差矣,陛下已經教會了臣民們如何使用Lambda表達式,而且如今也出現了RxJava,已經沒什麼回調地獄了!」
「那是如今,之前可沒有!」
「......」
國王看到這幾位大臣要打起來,立刻施展和稀泥之術:「衆位愛卿各有道理,大家且說說,怎麼才能戰勝着來勢洶洶的Node.js吧。」
沒人說話。
國王只好退朝。
京城酒館
京城的小酒館向來是一個多方消息的集散地。
一個金髮碧眼的小夥子正在「危言聳聽」:「據說了沒有,Node.js又贏了幾仗,Tomcat大軍死傷慘重,有很多臣民都投奔到那個番邦去了。」
「這異步操做真的有這麼厲害?」 有人問道。
小夥子喝了一口酒: 「其實不是異步操做更好,而是在高併發的環境異步操做更有效,你們都知道, 一個機器能支持的線程數目是有限的,不可能一直增長。Tomcat那種一個請求一個線程的方式很快就會遇到瓶頸。」
「你說說,到底有什麼好處?」有人刨根問底。
「如今服務器端的操做無非就是操做文件,讀寫數據庫,訪問遠程服務,這些都是所謂阻塞操做。」 小夥子展開了一張圖:
「橙色的都是IO操做,綠色的纔是真正的線程執行, IO操做很是耗時,線程大部分時間都浪費在了等待上面! 若是能讓線程不要等待,去作別的事情,那用少許的線程,甚至一個線程就能夠了。」
衆人紛紛點頭, 這小夥子已經看出了問題的關鍵,如今的不少系統,都是IO密集的, 高併發狀況下,若是一個請求一個線程,浪費巨大。
「想我Java 虛擬機如此強悍,若是能實現異步操做,那還不把Node.js秒成渣?!」小夥子狠狠地用手錘了一下桌子。
正在此時,酒館衝進一隊士兵,趕走衆人,圍住小夥子,領頭的喝問到:「大膽刁民,居然處處宣揚異步思想,給我帶走!」
士兵惡狠狠地把他五花大綁,推出門去, 留下一堆人在那裏議論紛紛。
IO王府
「我讓大家把他請來,怎麼綁來了?快鬆綁!」 IO大臣呵斥完下屬,轉頭親切地問道:「叫什麼名字啊?」
「小人蒂姆, Tomcat府上的幕僚。 」 蒂姆一邊說一邊揉肩膀。
「Tomcat府上的人......」 IO大臣捻着鬍鬚如有所思。
「是的,大人,我還見過您呢,您上次半夜去Tomcat府上密談......」
「住口! 」 IO大臣趕忙轉換話題, 「個人下屬發現你處處宣揚異步思想,究竟要幹什麼? 」
「小人發明了一個系統,叫作Node.x。 」
「爲何不獻於Tomcat 將軍?」
「唉,小人進言屢次,但是將軍不聽啊!」
「你說說看,這是個什麼東西? 是要模仿Node.js嗎?」 IO大臣問道。
以前蒂姆給Tomcat將軍講述過Node.js, 他理都不理,常常是一甩袖子就走, 本身是空有一身本領卻無人賞識, 難道這IO大臣能幫本身一把? 想到此處,蒂姆精神大振。
「確實受到了它的啓發, 可是個人Node.x在架構和一些關鍵的抽象上和Node.js有很大不一樣。」 蒂姆很差意思地笑了笑,「先說說相同的部分,既然都是異步操做,那確定是經過事件驅動的,因此都有一個事件循環。」
IO大臣以前和Swing大臣聊過, 知道事件循環是怎麼回事,這是一個至關古老的概念了。
無非就是有個線程在檢測一個隊列,若是隊列中有事件,就拿出來處理。
「只不過我這裏有所不一樣,能夠建立多個事件循環出來,好比每個CPU核心有一個,這樣能夠充分利用CPU的多核性能。」 蒂姆得意地說道。
(4個CPU core, 4個事件循環)
IO大臣點頭表示讚許, 他據說Node.js好像只有一個主線程,無法直接利用多核的能力。想利用多核的話還得開多個進程才行。
異步操做
「你圖中的那個Hanlder就是具體的業務代碼所在地吧? 具體長什麼樣子啊,讓我看看!」 IO大臣問道。
蒂姆趕忙呈上代碼,這是簡單的Hello World。
這段代碼生成了一個簡單的HTTP 服務器, 在8080端口監聽, 每當有請求來的時候,都返回一個字符串「Hello World!」。
IO大臣一看,大爲吃驚:「你這代碼不須要外部容器,本身就搞了一個HTTP服務器啊?」
「是的,這樣咱們就徹底不用Tomcat了。 我把這種類起來一個名稱,叫作Verticle, 部署之後,這個Verticle就能夠和一個事件循環關聯了。每次有HTTP請求過來,Node.x會封裝成事件,而後分派給它處理了。」
真是個二愣子, IO大臣心想, 怪不得Tomcat對你不待見,你這個東西出來,他的位置不保啊!
IO大臣問道:「那對於數據庫查詢,你這個Handler,哦不,Verticle該怎麼寫? 查詢數據庫這麼慢,豈不是把事件循環都阻塞了?什麼事情都作不了了?」
「大人您忘了,咱們這裏操做必須都是異步的,查詢數據庫也不例外。」
蒂姆說着展現了一段代碼, 經過異步的方式來查詢數據庫。
IO大臣感慨道:「唉,老了,真是不中用了,連異步都忘了。對了,這些個Verticle看起來都是獨立的,是被不一樣的線程調用的,他們之間怎麼進行交互啊?難道也經過共享內存的方式?」
「大人真是厲害,一會兒就問到了核心問題,不能讓他們共享內存,那樣就須要加鎖了,我這裏引入了Event Bus的方法,讓他們之間經過消息傳遞。」
「嗯,不錯,實現了低耦合。」
「不只如此,這些Verticle還能夠部署到不一樣的JVM中,經過Event Bus實現真正的分佈式通訊。」 蒂姆又拋出一個重磅炸彈。
「如此甚好!」 IO大臣愛才之心驟起, 「你願不肯意到老夫府上作幕僚啊?」
「小人願意追隨大人!」
「好!明日早朝,你隨我入宮,面見聖上,老夫保你一世榮華富貴。 」
爲何是Vert.x?
第二日早朝,IO大臣火燒眉毛地給國王報喜:「陛下,我Java 帝國也能夠採用非阻塞異步編程了!擊敗Node.js之日可待。」
IO大臣講述了昨晚的狀況, 細數了Node.x的種種好處。
Tomcat將軍臉上極爲難看, 趕忙阻止:「陛下不可,我Java帝國採用同步處理已經好久了,臣民們已經習慣了,如今改爲異步,怕激起民變。」
「愛卿不要低估臣民採用新技術的能力嘛, 宣蒂姆進殿,呈上代碼。」
蒂姆都不敢看Tomcat, 從懷裏掏出一張紙,雙手奉上。
國王盯着看了半天:「嗯?不對啊,你這不是Java代碼吧?」
Tomcat拿過國王遞過來的代碼,掃了一眼:「「大膽! 你居然敢在朝堂之上公然宣傳JavaScript,來人,拿下!」
「陛下息怒,這是小人制定的一個策略,個人Node.x支持不少語言編程, 除了Java以外,還有JavaScript,Ruby, Scala, Kotlin等等。」
「哦? 是嗎? 這還能把番邦的人給吸引過來呢!你說呢,Tomcat將軍?」 國王說道。
Tomcat有些不自在,想找回場子:「嗯嗯,有必定道理,不過這個Node.x這個名字很差,拾人牙慧,讓人看低我堂堂Java帝國。」
「Node是節點的意思,朕把他改爲vertex如何?也是節點的意思。」
「 陛下聖明,能否叫作vert.x ? 」 IO大臣提議。
「好,准奏,即日起,命你和蒂姆訓練臣民使用vert.x,一個月後向Node.js開戰!」 國王已經忍Node.js好久了。
不,不能讓IO大臣的Vert.x一家獨大!
國王忽然想到了親爹留下來的祖訓, 帝王之術是必定要平衡朝局。
「吩咐下去,今晚朕要和Spring將軍,嗯,還有線程大臣,共進晚餐,朕有些事情要和他們好好談談......」
編輯:千鋒web前端培訓
來自:碼農翻身(微信號:coderising)