版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、Java代去哪兒了隨著Java 8的到來, 了。它到底去了哪里?再也見不到代成為一名優(yōu)秀的Web前端開發(fā)者本文其中一位了兩位工程師為Web開發(fā)者們所多條建議,了多種實用的工具與技術,而另一位則對于如何克服瀏覽器開發(fā)時所的提出了諸多建議。Netty案例集錦之多線程篇Netty案例集錦的案例來源于作者在實際項目中遇到 網(wǎng)友的反饋??偨Y、以及Netty社區(qū)Kafka Consumer文章將詳細介紹High Level Consumer,Consumer Group,Consumer Group Rebalance和Simple Consumer,以及未來新版本中對Kafka High Level C
2、onsumer的重新設計使用Consumer Controller解決Split Brain和Herd等問題。我為什么用Node隨著無線端的快速普及,前后端分離技術走上前臺,而Node由于它的一些特性被工程師快速接受尤其是前端工程師,所以產(chǎn)生了很多Node是否會引起新的技術的。們本期主編流程編輯人提供反饋商務合作內(nèi)容合作七牛云CEO。ECUG社區(qū)發(fā)起人,是國內(nèi)Go語言實踐圈子公認的Go語言語言編程,并著有Go卷首語這個月七牛剛剛舉辦了 D-Future 大會。數(shù)據(jù)。這些數(shù)據(jù)人類容易理解,但計算機則很難。非結構化數(shù)據(jù)忠實地傳遞人的意在數(shù)據(jù)世界正以每三年翻一番的速度在膨脹,而這其中 95% 以上都
3、是非結構化數(shù)識到這一點。另外今天日志的處理能力、分析方法,以及產(chǎn)生對經(jīng)營有效指導的能這是一個以數(shù)據(jù)為的會議。如果要用一個詞來概括當前互聯(lián)網(wǎng)時代的特征,那就是兩個字:數(shù)據(jù)。實際上信息一直都存在,只是它以前存在于原子世界,有了計算機和互聯(lián)網(wǎng)之后,出現(xiàn)了一個由數(shù)據(jù)構愿。比如,我拿起說幾段語音,告訴據(jù),而且這個比例還在不斷的。如此力依然存在很多。超過半數(shù)的企業(yè)還對方要的東西?;蛘咄ㄟ^和視驚人的數(shù)據(jù)量,應該如何收集,如何保存,如何進行分析和挖掘,這又是一個很重要的課題。非結構化數(shù)據(jù)今天主要的用途是用來做交互,但是計算機對于語義的理解非常原始,所以在交互的智能化程度上,沒有日志,大部分企業(yè)對數(shù)據(jù)的分析頻,
4、表達一個商品長什么樣,商品該怎么僅僅停留在象日活用戶、用戶留存等基礎階段。絕大部分企業(yè)會定期刪除日志。使用的??梢钥吹?,非結構化數(shù)據(jù)自成的:比特世界。并且這個新的世然而然會成為交互的一個中介。這些非結界正在以每三年翻一倍的速度在膨脹。計算機和互聯(lián)網(wǎng)擴展了人的邏輯能力,讓我構化數(shù)據(jù)是實際存在事物的,而剛剛分析了非結構化數(shù)據(jù)和日志相這也是原子世界被瘋狂地到比特世仍然有非常巨大的空間。知道有關的一些,這些絕不是七牛一家希望有志于去們有了很強的分析和這樣的數(shù)字化洪流下,非常巨大的影響。未來的能力。在的商業(yè)將受到界一個根本原因,因為業(yè)務要上網(wǎng)。自然語言分析、NLP 這樣的一些技術,我公司所能解決的,們還
5、有語音識別,有或者里面對數(shù)據(jù)應用價值的企業(yè),都能夠一起共同開第二,當業(yè)務上網(wǎng)之后,的運營會發(fā)于場景、對于動作的捕捉與識別等,但是這些都還非常早期。這些技術如果能夠往前走一步,就會帶來巨大的想象空間。用戶每一次溝通,每一次交互過程,都沉淀拓這個數(shù)據(jù)世界。希望能夠分析數(shù)據(jù)生質變。在舊的商業(yè)過程當中,大部分的使用場景,去觸及它的方方面面,去構建一個完整的技術棧,構建一個全新的商業(yè)形態(tài)。首先,來看一看業(yè)務本身?;ヂ?lián)網(wǎng)化的企業(yè)會找一些樣本客戶來做但業(yè)務上網(wǎng)后,可以天然地問卷。每一次的最基礎的一個訴求就是業(yè)務上網(wǎng)。對比一下傳統(tǒng)的商業(yè)和新興的商業(yè)形態(tài),最交易過程,能把所有用戶的行為都下了大量的信息,但限于的
6、分析能力還大的一個不同是什么?如果用一個來。今天不是取樣數(shù)據(jù),而是全量地很原始,所以今天幾乎所有的非結構化數(shù)據(jù)都還沒有二次分析。平步云端,數(shù)據(jù)為先。讓一起共同發(fā)詞去概括舊的商業(yè)形態(tài),我個人想到的一句話是“一手交錢一手交貨”,這就是舊的商業(yè)形態(tài)最基本的特色。但是互聯(lián)網(wǎng)改用戶行為。每天都在產(chǎn)生上千萬掘數(shù)據(jù)背后的價值,共同構建新時代的商業(yè)文明。上億的交易錄去改進 要的課題。,而如何通過這些交易記的商業(yè)模式,是一個非常重再看用戶行為的日志。日志是計變了這一切,它讓交易成為了可能。算機生成的,所以它天然可以很容易被計算機去理解,這個理解是全面的,不會損失什么信息。所以日志本身是一個更高含金量的金礦,但是
7、大部分的企業(yè)還沒有意互聯(lián)網(wǎng)時代業(yè)務的特征,我也概括了一句話:“非結構化數(shù)據(jù)是人類最自然的溝無論是非結構化數(shù)據(jù)或者用戶行為通方式”。、音頻、自然表達的語言文本以及等媒介,都是非結構化的日志,都很多機遇和。我們先看一看非結構化數(shù)據(jù)。如前所說,現(xiàn)45文章 | Article因為在“使用不熟悉的技術開始一個全新的項目”,或是對第JavaScript 應用的開發(fā)真正理解背后的過程。對于 Walton 來說,僅僅編寫出可以運行的代碼算不得優(yōu)秀。他見過許多編寫 CSS 與 JavaScript 的人,他們 “只求找到能夠運行的代碼,然后就繼續(xù)下一步工作了?!焙芏鄷r候,開發(fā)者并不了解某段代碼運行的機制。Wal
8、ton 建議開發(fā)者進行深入鉆研:成為一名優(yōu)秀的Web前端開發(fā)者進行標準化時,Yeoman 的表現(xiàn)“非常出色”。 Murphey 也提到了 Broccoli,認為它將來或許能夠取代 Grunt 和 Yeoman。編寫高質量的代碼。建議是,對“了項目中經(jīng)過良好定義的風格指南”的代碼進行要充分理解代碼的工作原理或許會很耗時間,但我向你保證,從長遠來說,這種方式最終將節(jié)省你大量的時間。一旦你充分理解你所參與重構,還應當使用 l工具, 例如 JSCS 或ESL。的系統(tǒng)是如何的,你就無需不斷地進行猜使用Git。Murphey 建議在Git 中使用特性分支,因此得以“通過交互式 rebase,在與他人測與檢
9、驗這些費時的工作了。提交時對提交進行,并且盡可能地在較小的單元上進行工作,以減少的發(fā)生機率”。預先了解瀏覽器將產(chǎn)生的改動。Web 開發(fā)者應當持續(xù)了解有哪些瀏覽器的改動會破壞現(xiàn)有的代碼。以下代碼在 IE10 中必然會導致整個JavaScript 框架的方法出錯:此外還應當通過 ghooks 在 push 操作與 commit操作前運行鉤子操作。作者 Abel Avram譯者 邵思華在服務端生成 HTML。出于性能方面的考慮,Murphey在大型項目中盡可能在服務端生var isIE6 = !isIE7 & !isIE8 & !isIE9;成 HTML?!邦A先生成這些文件,將其作為靜態(tài)文件保存,以
10、加快處理請求的速度。隨后在客戶端的相應事件中可通過客戶端代碼操作這些HTML 文件,并在客戶端模板中修改。”本文了兩位工程師為 Web 開發(fā)者們所提出開發(fā)者更深入地了解如何使用異步調(diào)用、回調(diào)以及 promise。仔細閱讀規(guī)范。Walton,雖然閱讀規(guī)范是的多條建議,其中一位了多種實用的工具一項艱辛的任務,但一旦出現(xiàn)瀏覽器對某個頁面的渲染不同的情況,這一任務就是不可避免的了。他為此特別舉例說明:與技術,而另一位則對于如何克服瀏覽器開發(fā)時所的提出了諸多建議。使用模塊。Murphey 相信,模塊應當作為客戶端 web 應用程序的構建塊。她最近在擁抱 Node。Murphey 建議 web 開發(fā)者熟練
11、掌握 Node.js 的相關知識,至少要了解如何初始化一個Node 項目、如何搭建一臺Express 服務器、以及如何使用 request 模塊轉發(fā)請求。Rebecca Murphey 是來自于 Bazaarvoice 的一使用 wck 以實現(xiàn)模塊化的效果,但她希望最近我遇到這樣一個例子,與可伸縮(flex)元素的默認最小尺寸有關。根據(jù)規(guī)范所說,可伸縮元素的 min-width 與 min-height 的初始值是 auto,而不是 0,這就意味著在默認情況下,這些元素不可能收縮到比其中的內(nèi)容尺寸還小。而在過去 8 個月中,F(xiàn)irefox 是唯一一個正確地實現(xiàn)了這一特性的瀏覽器。位工程師。今年
12、早些時候,她發(fā)布了一篇讓每個人都能夠使用 ECMAScript 標準模塊的那一天能夠早日到來。博客文章“ 前端(JS)開發(fā)者的基本素質之 2015 版”,為 JavaScript 開發(fā)者在進行客戶端 web 開發(fā)時使用的工具與開發(fā)方式提出了一測試你的代碼。在 Murphey 看來,為你的代碼編寫測試,并且保證代碼的可測試性是至關重Philip Walton 是來自的一位工程些建議。她在文章的總結:師,他最近撰寫了一篇博客文章“如何成為一名優(yōu)秀的前端工程師”。這篇文章的觀點另辟要的。雖然她對于ern“非常中意”,但出學習 ECMAScript 2015,的參考資料有:于,她還是堅持使用 Moch
13、a。關于這一方蹊徑,他并沒有向讀者任何工具或框架,Understanding ES6、ES6 Rocks 以 及面,她也強烈MichaelFeathers 的著作修而是專注于如何處理這一領域中的某些。如果你遇到了這個跨瀏覽器的不一致性問題,BabelJS。在此還要加上一條,即 Axel改代碼的藝術。在他看來,優(yōu)秀員工與真正杰出的的差別并且注意到你的在 Chrome、IE、Opera 和Rausayer 的著作 探索 ES6??紤]到 不在于他們的知識量,而在于他們的思考方式。他是這樣描述開發(fā)者的智慧的:Safari 上的展現(xiàn)完全相同, 只在 Firefox 上有所差別,那你很可能會認為是 Fir
14、efox 的問在當前這個時間點上似乎還沒有必要了解ECMAScript 2015 的所有細節(jié),Murphey 建議實現(xiàn)流程自動化。Murphey 曾經(jīng)嘗試使用 Grunt 與 Gulp,但她最終還是選擇了 Yeoman。67文章 | Article題。實際上,我發(fā)現(xiàn)這一情況,在我職業(yè)者這條職業(yè)路線,那么 Walton 建議你參與開源項目,這同樣可以感受到在團隊中工作的益處。的 Flexbugs 項目中,有許多由用戶的 bugJava代去哪兒了其實都是由這種不一致性所導致的。而如果我按照用戶所提議的那些臨時方案來改變實現(xiàn)方式,那么在兩周前所發(fā)布的 Chrome 44 中又會產(chǎn)生問題。由于這些臨時
15、方案選擇了違背規(guī)范的方式,它們在無形中起到了提倡不正確行為的 作用。重復發(fā)明。Walton 相信,雖然“重復發(fā)明對于業(yè)務來說是有害的”,但它對于學習很有好處。在有些情況下,他建議你自己編寫代碼,而不是依賴于第的代碼,因為這一過程將讓你學到許多東西。當然這也要看情況而定。代碼。Walton 表示,從閱讀他人的代碼中可以學到很多知識,它可以拓寬你的思路,了解“新的工作方法”,同時也有助于你在團隊中的工作。實際上,這一點確實相當必要,因為“作為一位工程師來說,你的時間大部分都是在一個現(xiàn)有的代碼庫中添加或修改代碼”,而不是從頭開始編寫全新的代碼。將你的經(jīng)驗下來。Walton 的最后一條建議是將你所學到
16、的東西用文字下來:“按我的經(jīng)驗來看,寫作、以及開發(fā) demo,這些方法能夠迫使我對知識點進行充分的挖掘,并做到從內(nèi)到外的完全理解。哪怕你寫的東西完全沒人看,但寫作的過程本身就已經(jīng)值得你付出的努力了?!迸c人一起工作。Walton“強烈”建議你至少在職業(yè)生涯的初期階段要盡量在某個團隊中進行工作,向更有經(jīng)驗的團隊成員學習,作者 Monica Beckwith 譯者 段建華查 看 英 文 原 文 ing a Great WebFront-end Developer并讓他們你的代碼。如果之后選擇了在 Java 虛擬機(以下簡稱 JVM)中,類包含其對應的元數(shù)據(jù),比如類的層級信息,方法數(shù)據(jù)和方法信息(如字
17、節(jié)碼,棧和變量大?。?,運制代的大小,32 位機器默認的64M,64 位的機器則為 85M。代的大代的垃圾回收和老年代的回收是綁定的,一旦其行時常量池,已確定的符號和虛方法表。中一個區(qū)域被占滿,這兩個區(qū)都要進行回收。但是有一個明顯過 -XX:MaxPermSize 設置,由于可以通在過去(當自定義類加載器使用不普遍的時候),類幾乎是“靜態(tài)的”并且很少被卸載和代的大小,一旦類的元數(shù)據(jù)超過了設定的大小,程序就會耗盡內(nèi)存,并出現(xiàn)內(nèi)存溢出錯誤(OOM)。回收,因此類也可以被看成“的”。另外由于類作為 JVM 實現(xiàn)的一部分,它們不由程序來創(chuàng)建,因為它們也被認為是“非堆”的內(nèi)存。備注: 在 JDK7 之前的
18、 HotSpot 虛擬機中, 納入字符串常量池的字符串被在,在 JDK8 之前的 HotSpot 虛擬機中,類的這些因此導致了一系列的性能問題和內(nèi)存溢出錯“的”數(shù)據(jù)存放在一個叫做代一段連續(xù)的內(nèi)存空間,代的區(qū)域。在 JVM 啟動誤。想要了解這些代移除這些字符串的信息,請這里查看。之前可以通過設置 -XX:MaxPermSize 的值來控89文章 | Article文章 | Article辭代,迎元空間最大可分配空間就是系統(tǒng)可用內(nèi)存空間。因此,從行文到現(xiàn)在提到的元空間稍微有點不嚴塊的分配。類加載器 1 和 3 表明使用了反射或就不會遇到代存在時的內(nèi)存溢出錯謹。準確的來說,每一個類加載器的區(qū)域者為類
19、加載器,他們使用了特定大小組塊。隨著Java8 的到來,再也見不到代了。了。誤,也不會出現(xiàn)泄漏的數(shù)據(jù)移到交換區(qū)這樣的事情。最終用戶可以為元空間設置一個可用空間最大值,如果不進行設置,JVM 會自動根據(jù)類的元數(shù)據(jù)大小動態(tài)增加元空間的容量。都稱作一個元空間,所有的元空間合在一起就而類加載器 2 和 4 根據(jù)其條目的數(shù)量使用小型或者中型的組塊。但是這并不意味著類的元數(shù)據(jù)信息也是說的元空間。當一個類加載器被垃這些數(shù)據(jù)被移到了一個與堆不相連的本地內(nèi)存圾回收器標記為不再存活,其對應的元空間會被回收。在元空間的回收過程中沒有重定位和壓縮等操作。但是元空間內(nèi)的元數(shù)據(jù)會進行掃區(qū)域,這個區(qū)域就是要提到的元空間。元
20、空間調(diào)優(yōu)與工具正如上面提到的,元空間虛擬機控制元 這項改動是很有必要的,因為對代進行調(diào)注意:器代的移除并不代表自定義的類加載描來確定 Java。優(yōu)是很的。的元數(shù)據(jù)可能會隨著空間的增 長。但是有些時候 想限 問題就解決了。因此,你還必須你每一次 Full GC 發(fā)生而進行移動。并且為代設置空間大小也是很難確定的,因為這其中制其增長,比如通過顯式在命令行中設 的內(nèi)存消耗情況,因為一旦發(fā)生泄漏,會占用你的大量本地內(nèi)存,并且還可能導致交換區(qū)交換更加糟糕。元空間虛擬機負責元空間的分配,其采用的形式為組塊分配。組塊的大小因類加載器的類型而異。在元空間虛擬機中存在一個全局的空閑組塊列表。當一個類加載器需要組
21、塊時,它就會從這個全局的組塊列表中獲取并維持一個自己的組塊列表。當一個類加載器不再存活,那置 -XX:MaxMetaspaize。 默 認 情 況 下,-有很多影響,比如類的總數(shù),常量池的大XX:MaxMetaspaize 的值沒有限制,因此元小和方法數(shù)量等。空間甚至可以延伸到交換區(qū),但是這時候當我們進行本地內(nèi)存分配時將會失敗。元空間內(nèi)存管理元空間的內(nèi)存管理由元空間虛擬機來完成。先同時,HotSpot 虛擬機的每種類型的回收器都需要特殊處理的元數(shù)據(jù)。將元數(shù)對于一個 64 位的服務器端 JVM 來說,其默認么其持有的組塊將會被,并返回給全局組前,對于類的元數(shù)據(jù)需要不同的回收據(jù)從代剝離出來,不僅實
22、現(xiàn)了對元空間的的 XX:Metaspaize 值為 21MB。這就是初塊列表。類加載器持有的組塊又會被分成多個器進行處理,現(xiàn)在只需要執(zhí)行元空間虛擬機的 C+ 代碼即可完成。在元空間中,類和其元數(shù)據(jù)的生命周期和其對應的類加載器是相同的。話句話說,只要類加載器存活,其加載的類的元數(shù)據(jù)也是存活的,因而不會被回收掉。無縫管理,還可以簡化 Full GC 以及對以后的并發(fā)類元數(shù)據(jù)等方面進行優(yōu)化。始的高水位線。一旦觸及到這個水位線,F(xiàn)ull GC 將會被觸發(fā)并卸載沒有用的類(即這些類對應的類加載器不再存活),然后這個高水位線將會重置。新的高水位線的值取決于 GC 后塊,每一個塊一個單元的元信息。組塊中的塊
23、是線性分配(指針碰撞分配形式)。組塊分配自內(nèi)存區(qū)域。這些全局的虛擬內(nèi)存映移除代的影響射區(qū)域以鏈表形式連接,一旦某個虛擬內(nèi)存映射區(qū)域清空,這部分內(nèi)存就會返回給操作系統(tǒng)。了多少元空間。如果個高水位線則上升。如果的空間,這由于類的元數(shù)據(jù)分配在本地內(nèi)存中,元空間的空間過多,則高水位線下降。如果初始化的高水位線設置過下圖展示的是虛擬內(nèi)存區(qū)域如何進行元組1011文章 | Article文章| Article代碼段 2低,上述高水位線調(diào)整情況會發(fā)生很多次。jmap -clss打印類加載器數(shù)據(jù)。通過回收器的日志可以觀察到 Full(-clss 是 -perms的替代方案,在GC 多次調(diào)用。為了避免頻繁的 GC
24、,建議將 JDK8 之前,-perms用來打印類加載器的XX:Metaspaize 設置為一個相對較高的值。數(shù)據(jù))。代碼段 1 輸出就是 DaCapo Avrorabenjsark 程序的類加載器數(shù)據(jù)。-gc LVMID 用來打印元空間的信息,經(jīng)過多次 GC 之后,元空間虛擬機自動調(diào)節(jié)高水位線,以此來推遲下一次回收到來。具體內(nèi)容如下圖所示。jcmdGC.class_ss 一個新的命有這樣兩個選項 -XX:MetaspaceFreeRatio令,用來連接到運行的 JVM 并輸出詳盡的類元數(shù)據(jù)的柱狀圖。和 -XX:MaxMetaspaceFreeRatio, 他們類似于GC 的 FreeRatio
25、 選項,用來設置元空間空閑比注 意: 在 JDK6 build13 下, 需 要 加上 -XX:+UnlockDiagnosticVMOptions 才能正確使用 jcmd 這個命令。(見代碼段 2)例的最大值和最小值。這兩個選項設置對應的值??梢酝ㄟ^命令行對使用 jcmd 的示例輸出 :下面是一些改進的工具,用來獲取空間的信息。關于元提示:如果想了解字段的里。信息,請這代碼段 11213$ jmap -clssAttaching to pros ID 6476, please wait.Debugger attached sucsfully.Server compiler detected.
26、JVM veris 25.5-b02finding class loader puting per loader s.done.please wait. computing liveness.livenessysis may be inaccurate .class_loader classesbytes parent_loaderalive? type011655 1222734nulllive0 x000000074004a6c0000 x000000074004a708deadjava/util/ResourceBundle$RBClassLoader0 x00000007c0053e2
27、0012 0 x000000074004a76000nulldeadsun/misc/ Launcher$ExtClassLoader0 x00000007c002d248013 0 x00000007401189c811471 0 x00000007400752f8deadsun/reflect/ DelegatingClassLoader0 x00000007c0009870014 0 x000000074004a7081163160530 x000000074004a760deadsun/misc/Launcher$AppClassLoader0 x00000007c0038190015
28、 0 x00000007400752f8538 7738540 x000000074004a708dead/dacapo/harness/DacapoClassLoader0 x00000007c00638b0016 total = 6N/Aalive=1, dead=5N/A001 $ jcmd GC.class_ss002 7140:003 Index Super InstBytes KlassBytes annoionsCpAll MethodCount Bytecodes MethodAllROAllRWAllTotal Claame0041-000024576600 C0052-12
29、901364800000040576616 Lavrora.arch.legacy.LegacyInstr;0063-12698404800000024576600 B007443137856648019248129488625288163683056846936 java.lang.Class0085431369686240876094457033616120723200044072 java.lang.String009643758725600129671493560 java.util.HashMap$Node01078365740860807203693016 avrora.sim.u
30、til.MulticastFSMProbe01184355488504068013144028015361816 avrora.sim.FiniteSeMachine$Se0129-00024576600 Ljava.lang.Object;01310-00024576600 I01411-00024576600 Lavrora.sim.platform.ExternalFlash$Page;015.016 1300 1098060801744102901808117632084384 sun.util.resour.OpenListResourceBundle0172244312794288
31、2024 2260976128015618823135144 1906688 4684704 6591392 Total01834.0%12.1%0.0%34.3%-8.5%47.6%28.9%71.1% 100.0%019 Index Super InstBytes KlassBytes annoionsCpAll MethodCount Bytecodes MethodAllROAllRWAllTotal Claame001 $ jcmd help GC.class_ss002 9522:GC.class_ssProvide sistics about Java class meta da
32、ta. Requires-XX:+UnlockDiagnosticVMOptions.Impact: High: Depends on Java heap size and content.Syntax : GC.class_ss options Arguments:columns : optional Comma-separated list of all the columns to show. If not specified, the following columns are shown:Options: (options must be specified using the or
33、 = syntax)-all : optional Show all columns (, false)-csv : optional Prin CSV (comma-separated values) format for spreadsheets (, false)-help : optional Show meaning of all the columns (, false)文章| Article存在前面已經(jīng)提到,元空間虛擬機采用了組塊分配的形式,同時區(qū)塊的大小由類加載器類型決定。類信息并不是固定大小,因此有可能分配的空閑區(qū)塊和類需要的區(qū)塊大小不同,這種情況下可能導致碎片存在。元空間虛
34、擬機目前并不支Sun,Oracle 和 AMD 等公司致力于服務器端JVM 優(yōu)化。Monica 還是 JavaOne 2013 會議的Netty案例集錦之多線程篇嘉賓。想要關注的可以在mon_beck。上查找查看英文原文:Where Has the JavGone?rmGen持壓縮操作,所以碎片化是目前最大。作者簡介Monica Beckwith 是一位在硬件行業(yè)有著 10 多年經(jīng)驗的性能研究工程師。她目前在 Servergy公司能架構師一職。該公司為一家提供高效服務器的。此外,Monica 曾在作者Netty 案例集錦系列文章介紹Netty 的特點些問題嚴重制約了對 Netty 的深入掌握和
35、實際項目應用。Netty 相關問題比較難定位的主要原因如下:NIO 編程自身的復雜性,涉及到大量 NIO 類庫、Netty 自身封裝的類庫等,當你需要打開黑盒定位問題時,必須對這些類庫了如指掌;否則即便定位到問題所在,也不知所以然,更無法修復;Netty 復雜的多線程模型,用戶在實際使用 Netty 時,會涉及到 Netty 自己封裝的線程組、線程池、NIO 線程,以及業(yè)務線程,通信鏈路的創(chuàng)建、I/O 消息的讀寫會涉及到復雜的線程切換,這會讓初學者云山霧繞,調(diào)試起來非常痛苦,甚至都不知道從哪里調(diào)試;Netty 入門比較簡單,主要原因有如下幾點:Netty 的 API 封裝比較簡單,將復雜的網(wǎng)絡
36、通信通過 BootStrap 等工具類做了二次封裝,用戶使用起來比較簡單;Netty 源碼自帶的 Demo 比較多,通過 Demo可以很快入門;Netty 社區(qū)資料、相關學習書籍也比較多,學習資料比較豐富。但是很多入門之后的 Netty 學習者遇到了很多困惑,例如不知道在實際項目中如何使用Netty、遇到 Netty 問題之后無從定位等,這Netty 版本的跨度大,從實際情況看,涉及到了Netty 3.X、4.X 和5.X 等多個版本,1415專題 | Topic專題 | Topic2.2. 問題定位每個 Major 版本之間特性變化非常大,即便是 Minor 版本都存在一些差異,這些功能特性
37、和類庫差異會給使用者帶來很多問題,版本升級之后稍有不慎就會掉入陷阱。際項目中如何使用好 Netty 多線程更加,由業(yè)務調(diào)用者線程執(zhí)行的,也就是說申請和在同一個業(yè)務線程中進行。初次排查并很多網(wǎng)上問題和事故都來源于對 Netty 線程模型了解不透徹所致。鑒于此,Netty 案例集錦系列就首先從多線程方面開始。使 用 bin Heap生了jmap -dump:format=b,file=netty.將堆內(nèi)存 dump 出來, 通過 IBM 的 yzer 工具進行分析,發(fā)現(xiàn) ByteBuf 發(fā)。沒有發(fā)現(xiàn)導致內(nèi)存的根因,繼續(xù)分析Netty 內(nèi)存池的實現(xiàn)原理。Netty 內(nèi)存池實現(xiàn)原理分析:查看 Nett
38、y 的內(nèi)存池分配器 PooledByteBufAllocator 的源碼實現(xiàn),發(fā)現(xiàn)內(nèi)存池實際是基于線程上下文實現(xiàn)的,相關代碼如下。1.2. 案例來源Netty 3 版本升級遭遇內(nèi)存泄漏案例問題描述Netty 案例集錦的案例來源于作者在實際項目因為使用了 Netty4 的內(nèi)存池,所以首先 中遇到總結、以及 Netty 社區(qū)網(wǎng)友的反懷疑是不是申請的 ByteBuf 沒有被 導饋,大多數(shù)案例都來源于實際項目,也有少部致?查看代碼,發(fā)現(xiàn)消息發(fā)送完成之后,Netty 底 層 已 經(jīng) 調(diào) 用 ReferenceCountUtil.也就是說內(nèi)存的申請和必須在同一線程上分是讀者在學習 Netty 中遭遇的比較
39、典型的問題。業(yè)務代碼升級 Netty3 到 Netty4 之后,運行下文中,不能跨線程。跨線程之后實際操作的就不是同一塊兒內(nèi)存區(qū)域,這會導致很多嚴重一段時間,Java 進程就會宕機,查看系統(tǒng)運行release(message) 對內(nèi)存進行了。這是怎日志發(fā)現(xiàn)系統(tǒng)發(fā)生了內(nèi)存(見下圖)。么回事呢?難道 Netty 4.X 的內(nèi)存池有 Bug,內(nèi)存便是其中之一。內(nèi)存在 A 線1.3. 多線程篇調(diào)用 release 操作內(nèi)存失???程申請,切換到 B 線程回收的。,實際是無法正確對內(nèi)存進行內(nèi)存進行(切換使用堆內(nèi)存池,方便對),發(fā)現(xiàn)堆內(nèi)存一直飆升。學習和掌握 Netty 多線程模型是個難點,在實考慮到 Ne
40、tty 內(nèi)存池自身 Bug 的可能性不大,首先從業(yè)務的使用方式入手分析:2.3. 問題根因內(nèi)存的分配是在業(yè)務代碼中進行,由于使用到了業(yè)務線程池做 I/O 操作和業(yè)務操作的隔離,實際上內(nèi)存是在業(yè)務線程中分配的;Netty 4 修改了Netty 3 的線程模型:在Netty3 的時候,upstream 是在 I/O 線執(zhí)行的,而 downstream 是在業(yè)務線執(zhí)行。當 Netty內(nèi)存的照 Netty應 Netty操作是在 outbound 中進行,按 3 的線程模型,downstream( 對4 的 outbound,Netty 4 取 消 了從網(wǎng)絡一個數(shù)據(jù)報投遞給業(yè)務 handler 的時候,
41、handler 是在 I/O 線執(zhí)行;而當我們在業(yè)務線程中調(diào)用 write 和 writeAndFlush向網(wǎng)絡發(fā)送消息的時候 ,handler 是在業(yè)務線upstream 和 downstream) 的 handler 也是1617專題 | Topic專題 | Topic執(zhí)行,直到最后一個 Header handler 將消避免錯誤的:跨線程、重復等有給產(chǎn)品帶來預期的性能,有些甚至還發(fā)息寫入到發(fā)送隊列務線程才返回。都是 操作,要避免。特別是跨線程申請和 ,往往具有隱蔽性,問題定位難度較大;防止隱式的申請和分配:之前曾經(jīng)發(fā)生過一個案例,為了解決內(nèi)存池跨線程申請和問題,有用戶對內(nèi)存池做了二次包裝
42、,以實現(xiàn)多線程操作時,內(nèi)存始終由包裝的管理線生了非常嚴重的性能下降,這與 Netty出的數(shù)據(jù)并不一致。給Netty4 修 改 了 這 一 模 型, 在 Netty 4 里inbound( 對應 Netty 3 的 upstream) 和outbound( 對應 Netty 3 的 downstream) 都是在Netty性能測試對比數(shù)據(jù):比較了兩NioEventLoop(I/O 線程 ) 中執(zhí)行。當在業(yè)個分別建立在 Netty 3 和 4 基礎上 echo 協(xié)議務線通過ChannelHandlerContext.write 發(fā)服務器。(Echo 非常簡單,這樣,任何的送消息的時候,Netty
43、4 在將消息發(fā)送事件調(diào)度到 ChannelPipeline 的時候, 首先將待發(fā)送的消息封裝成一個 Task,然后放到 NioEventLoop的任務隊列中,由NioEventLoop 線程異步執(zhí)行。后續(xù)所有 handler 的調(diào)度和執(zhí)行,包括消息的產(chǎn)生都是Netty 的原因,而不是協(xié)議的原因)。我使它們服務于相同的分布式 echo 協(xié)議客戶端,來自這些客戶端的 16384 個并發(fā)連接重復發(fā)送 256 字節(jié)的隨機負載,幾乎使千兆以太網(wǎng)飽和。程申請和,這樣可以用戶業(yè)務線程模型和方式的差異。誰知運行一段時間之后再次發(fā)生了內(nèi)存,最后發(fā)現(xiàn)原來調(diào)用 ByteBuf 的 write 操作時,如果內(nèi)存容量,
44、會自動進行容量擴展。擴展操作由業(yè)務線程執(zhí)行,這就繞過了內(nèi)存池管理線程,發(fā)送、I/O 事件程負責處理。, 都由 NioEventLoop 線根據(jù),Netty 4:發(fā)生了“逃逸”;GC 中斷頻率是原來的 1/5: 45.5 vs. 9.2次 / 分鐘;在本案例中,ByteBuf 在業(yè)務線程中申請,在后避免跨線程申請和使用內(nèi)存池,由于存在續(xù)的 ChannelHandler 中,ChannelHandler“逃逸”等隱式的內(nèi)存創(chuàng)建,實際生成速度是原來的 1/5:41.81 MiB/ 秒。207.11vs是由 Netty 的 I/O 線程 (EventLoop) 執(zhí)行的,上跨線程申請和使用內(nèi)存池是非常的
45、行為。盡管從技術角度看可以實現(xiàn)一個跨線程協(xié)調(diào)的內(nèi)存池機制,甚至重寫 PooledByteBufAllocator,但是這無疑會增加很多復雜性,通常也使用不到。如果確實存在跨線程的 ByteBuf 傳遞,而且無法保證 ByteBuf 在另一個線程中會重新分配大小等因此內(nèi)存的申請和致內(nèi)存泄漏。不在同一個線程中,導3.2. 問題定位Netty 3 和 Netty圖。4 的 I/O 事件處理流程(見右2.4. 案例總結操作,最簡單保險的方式就是做一次 ByteBuf 的拷貝,但這會造降。程切換點能下Netty 4.X 版本新增的內(nèi)存池確實非常高效,但是如果使用不當則會導致各種嚴重。諸如內(nèi)存這類問題,功
46、能測試并沒有異常,比較好的案就是如果存在跨線程的如果相關接口沒有進行壓測或者穩(wěn)定性測試而直接上線,則會導致嚴重的線上問題。ByteBuf 傳遞,對 ByteBuf 的寫操作要在分配線程完成,另一個線程只能做讀操作。操作完成之后發(fā)送一個事件通知分配線程,由分配線內(nèi)存池 PooledByteBuf 的使用建議:程執(zhí)行內(nèi)存操作。申請之后一定要記得 ,Netty 自 身Netty 3 版本升級性能下降案例問題描述業(yè)務代碼升級 Netty 3 到 Netty4 之后,并沒Socket和發(fā)送的 ByteBuf 系統(tǒng)會自動釋放,用戶不需要做二次;如果用戶使用Netty 的內(nèi)存池在應用中做ByteBuf 的對
47、象池使用,則需要自己主動;1819專題 | Topic專題 | Topic3.3. 問題總結通過對熱點方法的分析,發(fā)現(xiàn)在消息發(fā)送過程中,有兩處熱點:NioEventLoop 只有一個,所以執(zhí)行效率更低,返回給客戶端的應答時延就大。時延增大之后,自然導致系統(tǒng)并發(fā)量降低,性能下降。netty 5 如何打印 executor 線程的占用情況,如空閑線程數(shù)?executor 設置的大小一般如何進行計算的?業(yè)務代碼示例如下所示。該問題的根因還是由于 Netty4 的線程模型變消息發(fā)送性能統(tǒng)計相關 Handler;編碼 Handler。更引起,線程模型變更之后,不僅影響業(yè)務的功能,甚至對性能也會造成很大的
48、影響。找出問題根因之后,針對 Netty 4 的線程模型對業(yè)務進行專項優(yōu)化,將耗時的編碼等操作遷移到業(yè)務線程中執(zhí)行,為 I/O 線程減負,性能達到預期,遠超過了 Netty 3 老版本的性能。4.2. 問題定位對使用 Netty 3 版本的業(yè)務產(chǎn)品進行性能對比測試,發(fā)現(xiàn)上述兩個 Handler 也是熱點方法。既然都是熱點,為啥切換到 Netty4 之后性能下降這么厲害呢?對 Netty 的升級需要從功能、兼容性和性能等多個角度進行綜合考慮,切不可只盯著 API 變更這個芝麻,而丟掉了性能這個西瓜。API 的變更會導致編譯錯誤,但是性能下降卻隱藏于無形之中,稍不留意就會中招。從服務端初始化代碼來
49、看,并沒問題,Netty 3 的業(yè)務線程調(diào)度模型圖如下所示:充分利用了業(yè)務多線程并行編碼和 Handler 處理的優(yōu)勢,周期 T 內(nèi)可以處理 N 條業(yè)務消息,切換到 Netty 4 之后,業(yè)務耗時 Handler 被 I/O線程串行執(zhí)行,因此性能發(fā)生比較大的下降(見下圖)。業(yè)務 LogicServerHandler 沒有接收到消息,有如下幾種可能:客戶端并沒有將消息發(fā)送到服務端,可以在服務端 LoggingHandler 中打印日志查看;通過方法的調(diào)用樹分析發(fā)現(xiàn)了兩個版本的差異:在 Netty 3 中,上述兩個熱點方法都是由業(yè)務線程負責執(zhí)行;而在 Netty 4 中,則是由 NioEventL
50、oop(I/O) 線程執(zhí)行。 對于某個鏈路,業(yè)務是擁有多個線程的線程池,而對于講究快速交付、敏捷開發(fā)和灰度發(fā)布的互聯(lián)網(wǎng)應用,升級的時候更應該要當心。服務端部分消息發(fā)生異常,導致消息被丟棄/ 忽略,沒有走到LogicServerHandler中;執(zhí)行業(yè)務Handler 的DefaultEventExecutor中的線程太繁忙,導致任務隊列積壓,長時間得不到處理。Netty 業(yè)務 Handler 接收不到消息案例問題描述服務碰到一個問題,經(jīng)常有請求上來到 MessageDecoder 就結束了, 沒有繼續(xù)往LogicServerHandler 里面送,覺得很奇怪,是通過抓包結合日志分析,可能導致問
51、題的原因1 和 2 排除,需要繼續(xù)對可能原因 3 進行排查。不是線程了?請教:2021專題 | Topic專題| TopicNetty 5 如何打印executor 線程的占用情況,如空閑線程數(shù)?回答這些問題,首先要了解Netty的線程組和線程池機制。Netty 的 EventExecutroup 實際就是一組 EventExecutor,它的定義如下:通常通過它的 next 方法從線程組中獲取一個線程池,代碼如下:4.3. 問題總結實際就像 JDK 的線程池,不同的業(yè)務場景、硬件環(huán)境和性能標就會有不同的配置,無法給出事實上,Netty 為了防止多線程執(zhí)行某個 Handler(Channel)
52、引起線程安全問題,實際只有一個線程會執(zhí)行某個 Handler,代碼如下所示。標準的。需要進行實際測試、評估和調(diào)優(yōu)Netty EventExecutor 典型實現(xiàn) 有SingleThreadEventExecutor 的消息隊列中得不到及時處理,現(xiàn)象就是業(yè)務 Handler 好像得不到執(zhí)行,部分業(yè)務消息丟失。來靈活調(diào)整。兩個:DefaultEventExecutor 和SingleThreadEventLoop, 在 本 案 例 中, 因最后再總結回顧下問題,對于案例中的代碼,實際上在使用單線程處理某個 Handler 的LogicServerHandler,作者可能想并發(fā)多線程為 使 用 的
53、是 DefaultEventExecutroup,需要的是,SingleThreadEventExecutor所以實際執(zhí)行業(yè)務 Handler 線程池就 講解完 Netty 線程模型 后,問題原因也 的 pendingTasks 可能是個耗時的操作,因此調(diào)用的時候需要注意。是 DefaultEventExecutor, 它 繼 承 自SingleThreadEventExecutor, 從名稱就可以看出它是個單線程的線程池。工作原理如下:定位出來 了。其實 發(fā) 現(xiàn),可以通過 執(zhí)行這個 Handler,業(yè)務處理性能,但實EventExecutor 獲取 EventExecutroup 的信息,然
54、后獲取整個 EventExecutor 線程組信息,最后打印線程負載信息,代碼及執(zhí)行結果如下。DefaultEventExecutor 聚合JDK 的Executor和 Thread, 首次執(zhí)行 Task 的時候啟動線程,將線程池狀態(tài)修改為運行態(tài);Thread run 方法循環(huán)從隊列中獲取 Task 執(zhí)行,如果隊列為空,則同步阻塞,線程無限循環(huán)執(zhí)行,直到接收到退出信號。用戶想通過 N e t t y 提 供 的DefaultEventExecutroup 來 并 發(fā) 執(zhí)行業(yè)務 Handler,但實際上卻是單線程 SingleThreadEventExecutor 在 串 行 執(zhí) 行 業(yè)務邏輯,
55、當服務端消息接收速度超過業(yè)務邏輯執(zhí)行速度時,就會導致業(yè)務消息積壓在2223專題 | Topic專題| Topic際并沒有達到設計效果。面這樣的調(diào)用方法在多線程環(huán)境下安全嗎?謝謝!如果業(yè)務性能存在問題,并不奇怪,因為業(yè)務實際是單線程串行處理的!當然,如果業(yè)務存在多個 Channel,則每個 / 多個 Channel 會對應一個線程(池),也可以實現(xiàn)多線程處理,這取決于客戶端的接入數(shù)。5.2. 解答Netty 4 優(yōu)化了 Netty 3 的線程模型, 其中一個非常大的優(yōu)化就是用戶不需要再擔心ChannelHandler 會被并發(fā)調(diào)用,總結如下:案例中代碼的線程處理模型如下圖所示(單個鏈路模型)。C
56、hannelHandlers 的方法不會被 Netty 并發(fā)調(diào)用;用戶不再需要對 ChannelHandler 的各個方法做同步保護;ChannelHandler 實例不允許被多次添加到 ChannelPiple 中,否則線程安全將得不到保證;根據(jù)上述分析,MyHandler 的 channelRead方法不會被并發(fā)調(diào)用,因此不存問題。程安全5.3. 一些特例ChannelHandler 的線程安全存在幾個特例,總結如下:Netty 4 ChannelHandler線程安全疑問問題如 果 ChannelHandler 被 注 解 為 Sharable,全局只有一個 handler 實例,它會被
57、多個 Channel 的 Pipeline 共享, 會被多線程并發(fā)調(diào)用,因此它不是線程安全的;6. 作者簡介,2007 年畢業(yè)于東如果存在跨 ChannelHandler 的實例級變量共享,需要特別注意,它可能不是線程安全的。我有一個非線程安全的類ThreadUnsafeClass,這個類會在 channelRead 方法中被調(diào)用。我下學,2008 年進的設計和開入公司從事高性能通信非線程安全的跨ChannelHandler 變量原理如下圖。Netty 支持在添加ChannelHandler 的時候,發(fā)工作,有 7 年 NIO 設計和開發(fā)經(jīng)驗,精通Netty、Mina 等 NIO 框架和中間件
58、,現(xiàn)任指定執(zhí)行該 Handler 的 EventExecutroup,架構部架構師,Netty指這就意味著在整個 ChannelPipeline 執(zhí)行過程中,可能會發(fā)生線程切換。此時,如果同一個對象在多個 ChannelHandler 中被共享, 可能會被多線程并發(fā)操作。(見下圖)南作者。目前從事的架構設計工作。下一間件和 PaaS:Nettying:Netty 之家。:Nettying2425專題| TopicKafka設計(四):Kafka Consumer作者High Level Consumer很多時候,客戶程序只是希望從 KafkaGroup。ZooKeeper 中 Consumer
59、 相關節(jié)點如圖所示。數(shù)很多傳統(tǒng)的 Message Queue 都會在消息被消費完后將消息刪除,一方面避免重復消費,另一方面可以保證Queue 的長度比較短,提高效率。而如上文所述,Kafka 并不刪除已消費的消息,為了實現(xiàn)傳統(tǒng) Message Queue 消息只被消費一次的語義,Kafka 保證每條消息在同一個 Consumer Group 里只會被某一個 Consumer 消費。與傳統(tǒng) Message Queue 不同的是,Kafka還允許不同 Consumer Group 同時消費同一條消息,這一特性可以為消息的多元化處理提供支持。據(jù),不太關心消息 offset 的處理。同時也希望提供一些
60、語義,例如同一條消息只被某一個 Consumer 消費(單播)或被所有 Consumer消 費( 廣 播)。 因 此,Kafka High LevelConsumer 提供了一個從 Kafka 消費數(shù)據(jù)的抽象,從而義。掉其中的細節(jié)并提供豐富的語Consumer GroupHigh Level Consumer 將從某個 Partition 讀取的最后一條消息的 offset 存于 ZooKeeper中(Kafka 從 0.8.2 版 本 開始同時支持 將 offset 存于 Zookeeper 中與將 offset 存于專用的 Kafka Topic 中)。這個 offset 基于客戶程序提供
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度環(huán)境污染治理與修復合同
- 2024年版建筑項目合同樣本
- 永磁同步電機的課程設計
- 企業(yè)建筑施工安全生產(chǎn)管理制度匯編
- 花瓶插花課程設計
- 中國石化安全風險評估指導意見
- 部編版八年級《道德與法治》上冊同步練習(全冊,含答案)
- 系統(tǒng)文件監(jiān)控課程設計
- 網(wǎng)紅飲料制作課程設計
- 股市基金課程設計
- 水利五大員施工員教材講義
- 醫(yī)療機構資產(chǎn)負債表(通用模板)
- 廢舊鋰離子電池高值資源化回收利用項目環(huán)評報告書
- 審計英語詞匯大全講課教案
- JIS G3507-1-2021 冷鐓用碳素鋼.第1部分:線材
- 初二家長會ppt通用PPT課件
- 小學生家庭作業(yè)布置存在的誤區(qū)及改進策略論文1
- 一元一次含參不等式教學設計83
- 生物醫(yī)學研究的統(tǒng)計學方法課后習題答案 2014 主編 方積乾
- 牛仔面料成本核算
- 加拿大礦業(yè)政策
評論
0/150
提交評論