




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、Java代去哪兒了隨著Java 8的到來, 了。它到底去了哪里?再也見不到代成為一名優(yōu)秀的Web前端開發(fā)者本文其中一位了兩位工程師為Web開發(fā)者們所多條建議,了多種實用的工具與技術(shù),而另一位則對于如何克服瀏覽器開發(fā)時所的提出了諸多建議。Netty案例集錦之多線程篇Netty案例集錦的案例來源于作者在實際項目中遇到 網(wǎng)友的反饋。總結(jié)、以及Netty社區(qū)Kafka Consumer文章將詳細(xì)介紹High Level Consumer,Consumer Group,Consumer Group Rebalance和Simple Consumer,以及未來新版本中對Kafka High Level C
2、onsumer的重新設(shè)計使用Consumer Controller解決Split Brain和Herd等問題。我為什么用Node隨著無線端的快速普及,前后端分離技術(shù)走上前臺,而Node由于它的一些特性被工程師快速接受尤其是前端工程師,所以產(chǎn)生了很多Node是否會引起新的技術(shù)的。們本期主編流程編輯人提供反饋商務(wù)合作內(nèi)容合作七牛云CEO。ECUG社區(qū)發(fā)起人,是國內(nèi)Go語言實踐圈子公認(rèn)的Go語言語言編程,并著有Go卷首語這個月七牛剛剛舉辦了 D-Future 大會。數(shù)據(jù)。這些數(shù)據(jù)人類容易理解,但計算機則很難。非結(jié)構(gòu)化數(shù)據(jù)忠實地傳遞人的意在數(shù)據(jù)世界正以每三年翻一番的速度在膨脹,而這其中 95% 以上都
3、是非結(jié)構(gòu)化數(shù)識到這一點。另外今天日志的處理能力、分析方法,以及產(chǎn)生對經(jīng)營有效指導(dǎo)的能這是一個以數(shù)據(jù)為的會議。如果要用一個詞來概括當(dāng)前互聯(lián)網(wǎng)時代的特征,那就是兩個字:數(shù)據(jù)。實際上信息一直都存在,只是它以前存在于原子世界,有了計算機和互聯(lián)網(wǎng)之后,出現(xiàn)了一個由數(shù)據(jù)構(gòu)愿。比如,我拿起說幾段語音,告訴據(jù),而且這個比例還在不斷的。如此力依然存在很多。超過半數(shù)的企業(yè)還對方要的東西。或者通過和視驚人的數(shù)據(jù)量,應(yīng)該如何收集,如何保存,如何進行分析和挖掘,這又是一個很重要的課題。非結(jié)構(gòu)化數(shù)據(jù)今天主要的用途是用來做交互,但是計算機對于語義的理解非常原始,所以在交互的智能化程度上,沒有日志,大部分企業(yè)對數(shù)據(jù)的分析頻,
4、表達一個商品長什么樣,商品該怎么僅僅停留在象日活用戶、用戶留存等基礎(chǔ)階段。絕大部分企業(yè)會定期刪除日志。使用的??梢钥吹剑墙Y(jié)構(gòu)化數(shù)據(jù)自成的:比特世界。并且這個新的世然而然會成為交互的一個中介。這些非結(jié)界正在以每三年翻一倍的速度在膨脹。計算機和互聯(lián)網(wǎng)擴展了人的邏輯能力,讓我構(gòu)化數(shù)據(jù)是實際存在事物的,而剛剛分析了非結(jié)構(gòu)化數(shù)據(jù)和日志相這也是原子世界被瘋狂地到比特世仍然有非常巨大的空間。知道有關(guān)的一些,這些絕不是七牛一家希望有志于去們有了很強的分析和這樣的數(shù)字化洪流下,非常巨大的影響。未來的能力。在的商業(yè)將受到界一個根本原因,因為業(yè)務(wù)要上網(wǎng)。自然語言分析、NLP 這樣的一些技術(shù),我公司所能解決的,們還
5、有語音識別,有或者里面對數(shù)據(jù)應(yīng)用價值的企業(yè),都能夠一起共同開第二,當(dāng)業(yè)務(wù)上網(wǎng)之后,的運營會發(fā)于場景、對于動作的捕捉與識別等,但是這些都還非常早期。這些技術(shù)如果能夠往前走一步,就會帶來巨大的想象空間。用戶每一次溝通,每一次交互過程,都沉淀拓這個數(shù)據(jù)世界。希望能夠分析數(shù)據(jù)生質(zhì)變。在舊的商業(yè)過程當(dāng)中,大部分的使用場景,去觸及它的方方面面,去構(gòu)建一個完整的技術(shù)棧,構(gòu)建一個全新的商業(yè)形態(tài)。首先,來看一看業(yè)務(wù)本身?;ヂ?lián)網(wǎng)化的企業(yè)會找一些樣本客戶來做但業(yè)務(wù)上網(wǎng)后,可以天然地問卷。每一次的最基礎(chǔ)的一個訴求就是業(yè)務(wù)上網(wǎng)。對比一下傳統(tǒng)的商業(yè)和新興的商業(yè)形態(tài),最交易過程,能把所有用戶的行為都下了大量的信息,但限于的
6、分析能力還大的一個不同是什么?如果用一個來。今天不是取樣數(shù)據(jù),而是全量地很原始,所以今天幾乎所有的非結(jié)構(gòu)化數(shù)據(jù)都還沒有二次分析。平步云端,數(shù)據(jù)為先。讓一起共同發(fā)詞去概括舊的商業(yè)形態(tài),我個人想到的一句話是“一手交錢一手交貨”,這就是舊的商業(yè)形態(tài)最基本的特色。但是互聯(lián)網(wǎng)改用戶行為。每天都在產(chǎn)生上千萬掘數(shù)據(jù)背后的價值,共同構(gòu)建新時代的商業(yè)文明。上億的交易錄去改進 要的課題。,而如何通過這些交易記的商業(yè)模式,是一個非常重再看用戶行為的日志。日志是計變了這一切,它讓交易成為了可能。算機生成的,所以它天然可以很容易被計算機去理解,這個理解是全面的,不會損失什么信息。所以日志本身是一個更高含金量的金礦,但是
7、大部分的企業(yè)還沒有意互聯(lián)網(wǎng)時代業(yè)務(wù)的特征,我也概括了一句話:“非結(jié)構(gòu)化數(shù)據(jù)是人類最自然的溝無論是非結(jié)構(gòu)化數(shù)據(jù)或者用戶行為通方式”。、音頻、自然表達的語言文本以及等媒介,都是非結(jié)構(gòu)化的日志,都很多機遇和。我們先看一看非結(jié)構(gòu)化數(shù)據(jù)。如前所說,現(xiàn)45文章 | Article因為在“使用不熟悉的技術(shù)開始一個全新的項目”,或是對第JavaScript 應(yīng)用的開發(fā)真正理解背后的過程。對于 Walton 來說,僅僅編寫出可以運行的代碼算不得優(yōu)秀。他見過許多編寫 CSS 與 JavaScript 的人,他們 “只求找到能夠運行的代碼,然后就繼續(xù)下一步工作了。”很多時候,開發(fā)者并不了解某段代碼運行的機制。Wal
8、ton 建議開發(fā)者進行深入鉆研:成為一名優(yōu)秀的Web前端開發(fā)者進行標(biāo)準(zhǔn)化時,Yeoman 的表現(xiàn)“非常出色”。 Murphey 也提到了 Broccoli,認(rèn)為它將來或許能夠取代 Grunt 和 Yeoman。編寫高質(zhì)量的代碼。建議是,對“了項目中經(jīng)過良好定義的風(fēng)格指南”的代碼進行要充分理解代碼的工作原理或許會很耗時間,但我向你保證,從長遠(yuǎn)來說,這種方式最終將節(jié)省你大量的時間。一旦你充分理解你所參與重構(gòu),還應(yīng)當(dāng)使用 l工具, 例如 JSCS 或ESL。的系統(tǒng)是如何的,你就無需不斷地進行猜使用Git。Murphey 建議在Git 中使用特性分支,因此得以“通過交互式 rebase,在與他人測與檢
9、驗這些費時的工作了。提交時對提交進行,并且盡可能地在較小的單元上進行工作,以減少的發(fā)生機率”。預(yù)先了解瀏覽器將產(chǎn)生的改動。Web 開發(fā)者應(yīng)當(dāng)持續(xù)了解有哪些瀏覽器的改動會破壞現(xiàn)有的代碼。以下代碼在 IE10 中必然會導(dǎo)致整個JavaScript 框架的方法出錯:此外還應(yīng)當(dāng)通過 ghooks 在 push 操作與 commit操作前運行鉤子操作。作者 Abel Avram譯者 邵思華在服務(wù)端生成 HTML。出于性能方面的考慮,Murphey在大型項目中盡可能在服務(wù)端生var isIE6 = !isIE7 & !isIE8 & !isIE9;成 HTML。“預(yù)先生成這些文件,將其作為靜態(tài)文件保存,以
10、加快處理請求的速度。隨后在客戶端的相應(yīng)事件中可通過客戶端代碼操作這些HTML 文件,并在客戶端模板中修改。”本文了兩位工程師為 Web 開發(fā)者們所提出開發(fā)者更深入地了解如何使用異步調(diào)用、回調(diào)以及 promise。仔細(xì)閱讀規(guī)范。Walton,雖然閱讀規(guī)范是的多條建議,其中一位了多種實用的工具一項艱辛的任務(wù),但一旦出現(xiàn)瀏覽器對某個頁面的渲染不同的情況,這一任務(wù)就是不可避免的了。他為此特別舉例說明:與技術(shù),而另一位則對于如何克服瀏覽器開發(fā)時所的提出了諸多建議。使用模塊。Murphey 相信,模塊應(yīng)當(dāng)作為客戶端 web 應(yīng)用程序的構(gòu)建塊。她最近在擁抱 Node。Murphey 建議 web 開發(fā)者熟練
11、掌握 Node.js 的相關(guān)知識,至少要了解如何初始化一個Node 項目、如何搭建一臺Express 服務(wù)器、以及如何使用 request 模塊轉(zhuǎn)發(fā)請求。Rebecca Murphey 是來自于 Bazaarvoice 的一使用 wck 以實現(xiàn)模塊化的效果,但她希望最近我遇到這樣一個例子,與可伸縮(flex)元素的默認(rèn)最小尺寸有關(guān)。根據(jù)規(guī)范所說,可伸縮元素的 min-width 與 min-height 的初始值是 auto,而不是 0,這就意味著在默認(rèn)情況下,這些元素不可能收縮到比其中的內(nèi)容尺寸還小。而在過去 8 個月中,F(xiàn)irefox 是唯一一個正確地實現(xiàn)了這一特性的瀏覽器。位工程師。今年
12、早些時候,她發(fā)布了一篇讓每個人都能夠使用 ECMAScript 標(biāo)準(zhǔn)模塊的那一天能夠早日到來。博客文章“ 前端(JS)開發(fā)者的基本素質(zhì)之 2015 版”,為 JavaScript 開發(fā)者在進行客戶端 web 開發(fā)時使用的工具與開發(fā)方式提出了一測試你的代碼。在 Murphey 看來,為你的代碼編寫測試,并且保證代碼的可測試性是至關(guān)重Philip Walton 是來自的一位工程些建議。她在文章的總結(jié):師,他最近撰寫了一篇博客文章“如何成為一名優(yōu)秀的前端工程師”。這篇文章的觀點另辟要的。雖然她對于ern“非常中意”,但出學(xué)習(xí) ECMAScript 2015,的參考資料有:于,她還是堅持使用 Moch
13、a。關(guān)于這一方蹊徑,他并沒有向讀者任何工具或框架,Understanding ES6、ES6 Rocks 以 及面,她也強烈MichaelFeathers 的著作修而是專注于如何處理這一領(lǐng)域中的某些。如果你遇到了這個跨瀏覽器的不一致性問題,BabelJS。在此還要加上一條,即 Axel改代碼的藝術(shù)。在他看來,優(yōu)秀員工與真正杰出的的差別并且注意到你的在 Chrome、IE、Opera 和Rausayer 的著作 探索 ES6??紤]到 不在于他們的知識量,而在于他們的思考方式。他是這樣描述開發(fā)者的智慧的:Safari 上的展現(xiàn)完全相同, 只在 Firefox 上有所差別,那你很可能會認(rèn)為是 Fir
14、efox 的問在當(dāng)前這個時間點上似乎還沒有必要了解ECMAScript 2015 的所有細(xì)節(jié),Murphey 建議實現(xiàn)流程自動化。Murphey 曾經(jīng)嘗試使用 Grunt 與 Gulp,但她最終還是選擇了 Yeoman。67文章 | Article題。實際上,我發(fā)現(xiàn)這一情況,在我職業(yè)者這條職業(yè)路線,那么 Walton 建議你參與開源項目,這同樣可以感受到在團隊中工作的益處。的 Flexbugs 項目中,有許多由用戶的 bugJava代去哪兒了其實都是由這種不一致性所導(dǎo)致的。而如果我按照用戶所提議的那些臨時方案來改變實現(xiàn)方式,那么在兩周前所發(fā)布的 Chrome 44 中又會產(chǎn)生問題。由于這些臨時
15、方案選擇了違背規(guī)范的方式,它們在無形中起到了提倡不正確行為的 作用。重復(fù)發(fā)明。Walton 相信,雖然“重復(fù)發(fā)明對于業(yè)務(wù)來說是有害的”,但它對于學(xué)習(xí)很有好處。在有些情況下,他建議你自己編寫代碼,而不是依賴于第的代碼,因為這一過程將讓你學(xué)到許多東西。當(dāng)然這也要看情況而定。代碼。Walton 表示,從閱讀他人的代碼中可以學(xué)到很多知識,它可以拓寬你的思路,了解“新的工作方法”,同時也有助于你在團隊中的工作。實際上,這一點確實相當(dāng)必要,因為“作為一位工程師來說,你的時間大部分都是在一個現(xiàn)有的代碼庫中添加或修改代碼”,而不是從頭開始編寫全新的代碼。將你的經(jīng)驗下來。Walton 的最后一條建議是將你所學(xué)到
16、的東西用文字下來:“按我的經(jīng)驗來看,寫作、以及開發(fā) demo,這些方法能夠迫使我對知識點進行充分的挖掘,并做到從內(nèi)到外的完全理解。哪怕你寫的東西完全沒人看,但寫作的過程本身就已經(jīng)值得你付出的努力了。”與人一起工作。Walton“強烈”建議你至少在職業(yè)生涯的初期階段要盡量在某個團隊中進行工作,向更有經(jīng)驗的團隊成員學(xué)習(xí),作者 Monica Beckwith 譯者 段建華查 看 英 文 原 文 ing a Great WebFront-end Developer并讓他們你的代碼。如果之后選擇了在 Java 虛擬機(以下簡稱 JVM)中,類包含其對應(yīng)的元數(shù)據(jù),比如類的層級信息,方法數(shù)據(jù)和方法信息(如字
17、節(jié)碼,棧和變量大?。?,運制代的大小,32 位機器默認(rèn)的64M,64 位的機器則為 85M。代的大代的垃圾回收和老年代的回收是綁定的,一旦其行時常量池,已確定的符號和虛方法表。中一個區(qū)域被占滿,這兩個區(qū)都要進行回收。但是有一個明顯過 -XX:MaxPermSize 設(shè)置,由于可以通在過去(當(dāng)自定義類加載器使用不普遍的時候),類幾乎是“靜態(tài)的”并且很少被卸載和代的大小,一旦類的元數(shù)據(jù)超過了設(shè)定的大小,程序就會耗盡內(nèi)存,并出現(xiàn)內(nèi)存溢出錯誤(OOM)?;厥?,因此類也可以被看成“的”。另外由于類作為 JVM 實現(xiàn)的一部分,它們不由程序來創(chuàng)建,因為它們也被認(rèn)為是“非堆”的內(nèi)存。備注: 在 JDK7 之前的
18、 HotSpot 虛擬機中, 納入字符串常量池的字符串被在,在 JDK8 之前的 HotSpot 虛擬機中,類的這些因此導(dǎo)致了一系列的性能問題和內(nèi)存溢出錯“的”數(shù)據(jù)存放在一個叫做代一段連續(xù)的內(nèi)存空間,代的區(qū)域。在 JVM 啟動誤。想要了解這些代移除這些字符串的信息,請這里查看。之前可以通過設(shè)置 -XX:MaxPermSize 的值來控89文章 | Article文章 | Article辭代,迎元空間最大可分配空間就是系統(tǒng)可用內(nèi)存空間。因此,從行文到現(xiàn)在提到的元空間稍微有點不嚴(yán)塊的分配。類加載器 1 和 3 表明使用了反射或就不會遇到代存在時的內(nèi)存溢出錯謹(jǐn)。準(zhǔn)確的來說,每一個類加載器的區(qū)域者為類
19、加載器,他們使用了特定大小組塊。隨著Java8 的到來,再也見不到代了。了。誤,也不會出現(xiàn)泄漏的數(shù)據(jù)移到交換區(qū)這樣的事情。最終用戶可以為元空間設(shè)置一個可用空間最大值,如果不進行設(shè)置,JVM 會自動根據(jù)類的元數(shù)據(jù)大小動態(tài)增加元空間的容量。都稱作一個元空間,所有的元空間合在一起就而類加載器 2 和 4 根據(jù)其條目的數(shù)量使用小型或者中型的組塊。但是這并不意味著類的元數(shù)據(jù)信息也是說的元空間。當(dāng)一個類加載器被垃這些數(shù)據(jù)被移到了一個與堆不相連的本地內(nèi)存圾回收器標(biāo)記為不再存活,其對應(yīng)的元空間會被回收。在元空間的回收過程中沒有重定位和壓縮等操作。但是元空間內(nèi)的元數(shù)據(jù)會進行掃區(qū)域,這個區(qū)域就是要提到的元空間。元
20、空間調(diào)優(yōu)與工具正如上面提到的,元空間虛擬機控制元 這項改動是很有必要的,因為對代進行調(diào)注意:器代的移除并不代表自定義的類加載描來確定 Java。優(yōu)是很的。的元數(shù)據(jù)可能會隨著空間的增 長。但是有些時候 想限 問題就解決了。因此,你還必須你每一次 Full GC 發(fā)生而進行移動。并且為代設(shè)置空間大小也是很難確定的,因為這其中制其增長,比如通過顯式在命令行中設(shè) 的內(nèi)存消耗情況,因為一旦發(fā)生泄漏,會占用你的大量本地內(nèi)存,并且還可能導(dǎo)致交換區(qū)交換更加糟糕。元空間虛擬機負(fù)責(zé)元空間的分配,其采用的形式為組塊分配。組塊的大小因類加載器的類型而異。在元空間虛擬機中存在一個全局的空閑組塊列表。當(dāng)一個類加載器需要組
21、塊時,它就會從這個全局的組塊列表中獲取并維持一個自己的組塊列表。當(dāng)一個類加載器不再存活,那置 -XX:MaxMetaspaize。 默 認(rèn) 情 況 下,-有很多影響,比如類的總數(shù),常量池的大XX:MaxMetaspaize 的值沒有限制,因此元小和方法數(shù)量等。空間甚至可以延伸到交換區(qū),但是這時候當(dāng)我們進行本地內(nèi)存分配時將會失敗。元空間內(nèi)存管理元空間的內(nèi)存管理由元空間虛擬機來完成。先同時,HotSpot 虛擬機的每種類型的回收器都需要特殊處理的元數(shù)據(jù)。將元數(shù)對于一個 64 位的服務(wù)器端 JVM 來說,其默認(rèn)么其持有的組塊將會被,并返回給全局組前,對于類的元數(shù)據(jù)需要不同的回收據(jù)從代剝離出來,不僅實
22、現(xiàn)了對元空間的的 XX:Metaspaize 值為 21MB。這就是初塊列表。類加載器持有的組塊又會被分成多個器進行處理,現(xiàn)在只需要執(zhí)行元空間虛擬機的 C+ 代碼即可完成。在元空間中,類和其元數(shù)據(jù)的生命周期和其對應(yīng)的類加載器是相同的。話句話說,只要類加載器存活,其加載的類的元數(shù)據(jù)也是存活的,因而不會被回收掉。無縫管理,還可以簡化 Full GC 以及對以后的并發(fā)類元數(shù)據(jù)等方面進行優(yōu)化。始的高水位線。一旦觸及到這個水位線,F(xiàn)ull GC 將會被觸發(fā)并卸載沒有用的類(即這些類對應(yīng)的類加載器不再存活),然后這個高水位線將會重置。新的高水位線的值取決于 GC 后塊,每一個塊一個單元的元信息。組塊中的塊
23、是線性分配(指針碰撞分配形式)。組塊分配自內(nèi)存區(qū)域。這些全局的虛擬內(nèi)存映移除代的影響射區(qū)域以鏈表形式連接,一旦某個虛擬內(nèi)存映射區(qū)域清空,這部分內(nèi)存就會返回給操作系統(tǒng)。了多少元空間。如果個高水位線則上升。如果的空間,這由于類的元數(shù)據(jù)分配在本地內(nèi)存中,元空間的空間過多,則高水位線下降。如果初始化的高水位線設(shè)置過下圖展示的是虛擬內(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è)置為一個相對較高的值。數(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、 選項,用來設(shè)置元空間空閑比注 意: 在 JDK6 build13 下, 需 要 加上 -XX:+UnlockDiagnosticVMOptions 才能正確使用 jcmd 這個命令。(見代碼段 2)例的最大值和最小值。這兩個選項設(shè)置對應(yīng)的值??梢酝ㄟ^命令行對使用 jcmd 的示例輸出 :下面是一些改進的工具,用來獲取空間的信息。關(guān)于元提示:如果想了解字段的里。信息,請這代碼段 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ū)塊大小不同,這種情況下可能導(dǎo)致碎片存在。元空間虛
34、擬機目前并不支Sun,Oracle 和 AMD 等公司致力于服務(wù)器端JVM 優(yōu)化。Monica 還是 JavaOne 2013 會議的Netty案例集錦之多線程篇嘉賓。想要關(guān)注的可以在mon_beck。上查找查看英文原文:Where Has the JavGone?rmGen持壓縮操作,所以碎片化是目前最大。作者簡介Monica Beckwith 是一位在硬件行業(yè)有著 10 多年經(jīng)驗的性能研究工程師。她目前在 Servergy公司能架構(gòu)師一職。該公司為一家提供高效服務(wù)器的。此外,Monica 曾在作者Netty 案例集錦系列文章介紹Netty 的特點些問題嚴(yán)重制約了對 Netty 的深入掌握和
35、實際項目應(yīng)用。Netty 相關(guān)問題比較難定位的主要原因如下:NIO 編程自身的復(fù)雜性,涉及到大量 NIO 類庫、Netty 自身封裝的類庫等,當(dāng)你需要打開黑盒定位問題時,必須對這些類庫了如指掌;否則即便定位到問題所在,也不知所以然,更無法修復(fù);Netty 復(fù)雜的多線程模型,用戶在實際使用 Netty 時,會涉及到 Netty 自己封裝的線程組、線程池、NIO 線程,以及業(yè)務(wù)線程,通信鏈路的創(chuàng)建、I/O 消息的讀寫會涉及到復(fù)雜的線程切換,這會讓初學(xué)者云山霧繞,調(diào)試起來非常痛苦,甚至都不知道從哪里調(diào)試;Netty 入門比較簡單,主要原因有如下幾點:Netty 的 API 封裝比較簡單,將復(fù)雜的網(wǎng)絡(luò)
36、通信通過 BootStrap 等工具類做了二次封裝,用戶使用起來比較簡單;Netty 源碼自帶的 Demo 比較多,通過 Demo可以很快入門;Netty 社區(qū)資料、相關(guān)學(xué)習(xí)書籍也比較多,學(xué)習(xí)資料比較豐富。但是很多入門之后的 Netty 學(xué)習(xí)者遇到了很多困惑,例如不知道在實際項目中如何使用Netty、遇到 Netty 問題之后無從定位等,這Netty 版本的跨度大,從實際情況看,涉及到了Netty 3.X、4.X 和5.X 等多個版本,1415專題 | Topic專題 | Topic2.2. 問題定位每個 Major 版本之間特性變化非常大,即便是 Minor 版本都存在一些差異,這些功能特性
37、和類庫差異會給使用者帶來很多問題,版本升級之后稍有不慎就會掉入陷阱。際項目中如何使用好 Netty 多線程更加,由業(yè)務(wù)調(diào)用者線程執(zhí)行的,也就是說申請和在同一個業(yè)務(wù)線程中進行。初次排查并很多網(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)導(dǎo)致內(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)的,相關(guān)代碼如下。1.2. 案例來源Netty 3 版本升級遭遇內(nèi)存泄漏案例問題描述Netty 案例集錦的案例來源于作者在實際項目因為使用了 Netty4 的內(nèi)存池,所以首先 中遇到總結(jié)、以及 Netty 社區(qū)網(wǎng)友的反懷疑是不是申請的 ByteBuf 沒有被 導(dǎo)饋,大多數(shù)案例都來源于實際項目,也有少部致?查看代碼,發(fā)現(xiàn)消息發(fā)送完成之后,Netty 底 層 已 經(jīng) 調(diào) 用 ReferenceCountUtil.也就是說內(nèi)存的申請和必須在同一線程上分是讀者在學(xué)習(xí) Netty 中遭遇的比較
39、典型的問題。業(yè)務(wù)代碼升級 Netty3 到 Netty4 之后,運行下文中,不能跨線程。跨線程之后實際操作的就不是同一塊兒內(nèi)存區(qū)域,這會導(dǎo)致很多嚴(yán)重一段時間,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)存一直飆升。學(xué)習(xí)和掌握 Netty 多線程模型是個難點,在實考慮到 Ne
40、tty 內(nèi)存池自身 Bug 的可能性不大,首先從業(yè)務(wù)的使用方式入手分析:2.3. 問題根因內(nèi)存的分配是在業(yè)務(wù)代碼中進行,由于使用到了業(yè)務(wù)線程池做 I/O 操作和業(yè)務(wù)操作的隔離,實際上內(nèi)存是在業(yè)務(wù)線程中分配的;Netty 4 修改了Netty 3 的線程模型:在Netty3 的時候,upstream 是在 I/O 線執(zhí)行的,而 downstream 是在業(yè)務(wù)線執(zhí)行。當(dāng) Netty內(nèi)存的照 Netty應(yīng) Netty操作是在 outbound 中進行,按 3 的線程模型,downstream( 對4 的 outbound,Netty 4 取 消 了從網(wǎng)絡(luò)一個數(shù)據(jù)報投遞給業(yè)務(wù) handler 的時候,
41、handler 是在 I/O 線執(zhí)行;而當(dāng)我們在業(yè)務(wù)線程中調(diào)用 write 和 writeAndFlush向網(wǎng)絡(luò)發(fā)送消息的時候 ,handler 是在業(yè)務(wù)線upstream 和 downstream) 的 handler 也是1617專題 | Topic專題 | Topic執(zhí)行,直到最后一個 Header handler 將消避免錯誤的:跨線程、重復(fù)等有給產(chǎn)品帶來預(yù)期的性能,有些甚至還發(fā)息寫入到發(fā)送隊列務(wù)線程才返回。都是 操作,要避免。特別是跨線程申請和 ,往往具有隱蔽性,問題定位難度較大;防止隱式的申請和分配:之前曾經(jīng)發(fā)生過一個案例,為了解決內(nèi)存池跨線程申請和問題,有用戶對內(nèi)存池做了二次包裝
42、,以實現(xiàn)多線程操作時,內(nèi)存始終由包裝的管理線生了非常嚴(yán)重的性能下降,這與 Netty出的數(shù)據(jù)并不一致。給Netty4 修 改 了 這 一 模 型, 在 Netty 4 里inbound( 對應(yīng) Netty 3 的 upstream) 和outbound( 對應(yīng) Netty 3 的 downstream) 都是在Netty性能測試對比數(shù)據(jù):比較了兩NioEventLoop(I/O 線程 ) 中執(zhí)行。當(dāng)在業(yè)個分別建立在 Netty 3 和 4 基礎(chǔ)上 echo 協(xié)議務(wù)線通過ChannelHandlerContext.write 發(fā)服務(wù)器。(Echo 非常簡單,這樣,任何的送消息的時候,Netty
43、4 在將消息發(fā)送事件調(diào)度到 ChannelPipeline 的時候, 首先將待發(fā)送的消息封裝成一個 Task,然后放到 NioEventLoop的任務(wù)隊列中,由NioEventLoop 線程異步執(zhí)行。后續(xù)所有 handler 的調(diào)度和執(zhí)行,包括消息的產(chǎn)生都是Netty 的原因,而不是協(xié)議的原因)。我使它們服務(wù)于相同的分布式 echo 協(xié)議客戶端,來自這些客戶端的 16384 個并發(fā)連接重復(fù)發(fā)送 256 字節(jié)的隨機負(fù)載,幾乎使千兆以太網(wǎng)飽和。程申請和,這樣可以用戶業(yè)務(wù)線程模型和方式的差異。誰知運行一段時間之后再次發(fā)生了內(nèi)存,最后發(fā)現(xiàn)原來調(diào)用 ByteBuf 的 write 操作時,如果內(nèi)存容量,
44、會自動進行容量擴展。擴展操作由業(yè)務(wù)線程執(zhí)行,這就繞過了內(nèi)存池管理線程,發(fā)送、I/O 事件程負(fù)責(zé)處理。, 都由 NioEventLoop 線根據(jù),Netty 4:發(fā)生了“逃逸”;GC 中斷頻率是原來的 1/5: 45.5 vs. 9.2次 / 分鐘;在本案例中,ByteBuf 在業(yè)務(wù)線程中申請,在后避免跨線程申請和使用內(nèi)存池,由于存在續(xù)的 ChannelHandler 中,ChannelHandler“逃逸”等隱式的內(nèi)存創(chuàng)建,實際生成速度是原來的 1/5:41.81 MiB/ 秒。207.11vs是由 Netty 的 I/O 線程 (EventLoop) 執(zhí)行的,上跨線程申請和使用內(nèi)存池是非常的
45、行為。盡管從技術(shù)角度看可以實現(xiàn)一個跨線程協(xié)調(diào)的內(nèi)存池機制,甚至重寫 PooledByteBufAllocator,但是這無疑會增加很多復(fù)雜性,通常也使用不到。如果確實存在跨線程的 ByteBuf 傳遞,而且無法保證 ByteBuf 在另一個線程中會重新分配大小等因此內(nèi)存的申請和致內(nèi)存泄漏。不在同一個線程中,導(dǎo)3.2. 問題定位Netty 3 和 Netty圖。4 的 I/O 事件處理流程(見右2.4. 案例總結(jié)操作,最簡單保險的方式就是做一次 ByteBuf 的拷貝,但這會造降。程切換點能下Netty 4.X 版本新增的內(nèi)存池確實非常高效,但是如果使用不當(dāng)則會導(dǎo)致各種嚴(yán)重。諸如內(nèi)存這類問題,功
46、能測試并沒有異常,比較好的案就是如果存在跨線程的如果相關(guān)接口沒有進行壓測或者穩(wěn)定性測試而直接上線,則會導(dǎo)致嚴(yán)重的線上問題。ByteBuf 傳遞,對 ByteBuf 的寫操作要在分配線程完成,另一個線程只能做讀操作。操作完成之后發(fā)送一個事件通知分配線程,由分配線內(nèi)存池 PooledByteBuf 的使用建議:程執(zhí)行內(nèi)存操作。申請之后一定要記得 ,Netty 自 身Netty 3 版本升級性能下降案例問題描述業(yè)務(wù)代碼升級 Netty 3 到 Netty4 之后,并沒Socket和發(fā)送的 ByteBuf 系統(tǒng)會自動釋放,用戶不需要做二次;如果用戶使用Netty 的內(nèi)存池在應(yīng)用中做ByteBuf 的對
47、象池使用,則需要自己主動;1819專題 | Topic專題 | Topic3.3. 問題總結(jié)通過對熱點方法的分析,發(fā)現(xiàn)在消息發(fā)送過程中,有兩處熱點:NioEventLoop 只有一個,所以執(zhí)行效率更低,返回給客戶端的應(yīng)答時延就大。時延增大之后,自然導(dǎo)致系統(tǒng)并發(fā)量降低,性能下降。netty 5 如何打印 executor 線程的占用情況,如空閑線程數(shù)?executor 設(shè)置的大小一般如何進行計算的?業(yè)務(wù)代碼示例如下所示。該問題的根因還是由于 Netty4 的線程模型變消息發(fā)送性能統(tǒng)計相關(guān) Handler;編碼 Handler。更引起,線程模型變更之后,不僅影響業(yè)務(wù)的功能,甚至對性能也會造成很大的
48、影響。找出問題根因之后,針對 Netty 4 的線程模型對業(yè)務(wù)進行專項優(yōu)化,將耗時的編碼等操作遷移到業(yè)務(wù)線程中執(zhí)行,為 I/O 線程減負(fù),性能達到預(yù)期,遠(yuǎn)超過了 Netty 3 老版本的性能。4.2. 問題定位對使用 Netty 3 版本的業(yè)務(wù)產(chǎn)品進行性能對比測試,發(fā)現(xiàn)上述兩個 Handler 也是熱點方法。既然都是熱點,為啥切換到 Netty4 之后性能下降這么厲害呢?對 Netty 的升級需要從功能、兼容性和性能等多個角度進行綜合考慮,切不可只盯著 API 變更這個芝麻,而丟掉了性能這個西瓜。API 的變更會導(dǎo)致編譯錯誤,但是性能下降卻隱藏于無形之中,稍不留意就會中招。從服務(wù)端初始化代碼來
49、看,并沒問題,Netty 3 的業(yè)務(wù)線程調(diào)度模型圖如下所示:充分利用了業(yè)務(wù)多線程并行編碼和 Handler 處理的優(yōu)勢,周期 T 內(nèi)可以處理 N 條業(yè)務(wù)消息,切換到 Netty 4 之后,業(yè)務(wù)耗時 Handler 被 I/O線程串行執(zhí)行,因此性能發(fā)生比較大的下降(見下圖)。業(yè)務(wù) LogicServerHandler 沒有接收到消息,有如下幾種可能:客戶端并沒有將消息發(fā)送到服務(wù)端,可以在服務(wù)端 LoggingHandler 中打印日志查看;通過方法的調(diào)用樹分析發(fā)現(xiàn)了兩個版本的差異:在 Netty 3 中,上述兩個熱點方法都是由業(yè)務(wù)線程負(fù)責(zé)執(zhí)行;而在 Netty 4 中,則是由 NioEventL
50、oop(I/O) 線程執(zhí)行。 對于某個鏈路,業(yè)務(wù)是擁有多個線程的線程池,而對于講究快速交付、敏捷開發(fā)和灰度發(fā)布的互聯(lián)網(wǎng)應(yīng)用,升級的時候更應(yīng)該要當(dāng)心。服務(wù)端部分消息發(fā)生異常,導(dǎo)致消息被丟棄/ 忽略,沒有走到LogicServerHandler中;執(zhí)行業(yè)務(wù)Handler 的DefaultEventExecutor中的線程太繁忙,導(dǎo)致任務(wù)隊列積壓,長時間得不到處理。Netty 業(yè)務(wù) Handler 接收不到消息案例問題描述服務(wù)碰到一個問題,經(jīng)常有請求上來到 MessageDecoder 就結(jié)束了, 沒有繼續(xù)往LogicServerHandler 里面送,覺得很奇怪,是通過抓包結(jié)合日志分析,可能導(dǎo)致問
51、題的原因1 和 2 排除,需要繼續(xù)對可能原因 3 進行排查。不是線程了?請教:2021專題 | Topic專題| TopicNetty 5 如何打印executor 線程的占用情況,如空閑線程數(shù)?回答這些問題,首先要了解Netty的線程組和線程池機制。Netty 的 EventExecutroup 實際就是一組 EventExecutor,它的定義如下:通常通過它的 next 方法從線程組中獲取一個線程池,代碼如下:4.3. 問題總結(jié)實際就像 JDK 的線程池,不同的業(yè)務(wù)場景、硬件環(huán)境和性能標(biāo)就會有不同的配置,無法給出事實上,Netty 為了防止多線程執(zhí)行某個 Handler(Channel)
52、引起線程安全問題,實際只有一個線程會執(zhí)行某個 Handler,代碼如下所示。標(biāo)準(zhǔn)的。需要進行實際測試、評估和調(diào)優(yōu)Netty EventExecutor 典型實現(xiàn) 有SingleThreadEventExecutor 的消息隊列中得不到及時處理,現(xiàn)象就是業(yè)務(wù) Handler 好像得不到執(zhí)行,部分業(yè)務(wù)消息丟失。來靈活調(diào)整。兩個:DefaultEventExecutor 和SingleThreadEventLoop, 在 本 案 例 中, 因最后再總結(jié)回顧下問題,對于案例中的代碼,實際上在使用單線程處理某個 Handler 的LogicServerHandler,作者可能想并發(fā)多線程為 使 用 的
53、是 DefaultEventExecutroup,需要的是,SingleThreadEventExecutor所以實際執(zhí)行業(yè)務(wù) Handler 線程池就 講解完 Netty 線程模型 后,問題原因也 的 pendingTasks 可能是個耗時的操作,因此調(diào)用的時候需要注意。是 DefaultEventExecutor, 它 繼 承 自SingleThreadEventExecutor, 從名稱就可以看出它是個單線程的線程池。工作原理如下:定位出來 了。其實 發(fā) 現(xiàn),可以通過 執(zhí)行這個 Handler,業(yè)務(wù)處理性能,但實EventExecutor 獲取 EventExecutroup 的信息,然
54、后獲取整個 EventExecutor 線程組信息,最后打印線程負(fù)載信息,代碼及執(zhí)行結(jié)果如下。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è)務(wù) Handler,但實際上卻是單線程 SingleThreadEventExecutor 在 串 行 執(zhí) 行 業(yè)務(wù)邏輯,
55、當(dāng)服務(wù)端消息接收速度超過業(yè)務(wù)邏輯執(zhí)行速度時,就會導(dǎo)致業(yè)務(wù)消息積壓在2223專題 | Topic專題| Topic際并沒有達到設(shè)計效果。面這樣的調(diào)用方法在多線程環(huán)境下安全嗎?謝謝!如果業(yè)務(wù)性能存在問題,并不奇怪,因為業(yè)務(wù)實際是單線程串行處理的!當(dāng)然,如果業(yè)務(wù)存在多個 Channel,則每個 / 多個 Channel 會對應(yīng)一個線程(池),也可以實現(xiàn)多線程處理,這取決于客戶端的接入數(shù)。5.2. 解答Netty 4 優(yōu)化了 Netty 3 的線程模型, 其中一個非常大的優(yōu)化就是用戶不需要再擔(dān)心ChannelHandler 會被并發(fā)調(diào)用,總結(jié)如下:案例中代碼的線程處理模型如下圖所示(單個鏈路模型)。C
56、hannelHandlers 的方法不會被 Netty 并發(fā)調(diào)用;用戶不再需要對 ChannelHandler 的各個方法做同步保護;ChannelHandler 實例不允許被多次添加到 ChannelPiple 中,否則線程安全將得不到保證;根據(jù)上述分析,MyHandler 的 channelRead方法不會被并發(fā)調(diào)用,因此不存問題。程安全5.3. 一些特例ChannelHandler 的線程安全存在幾個特例,總結(jié)如下:Netty 4 ChannelHandler線程安全疑問問題如 果 ChannelHandler 被 注 解 為 Sharable,全局只有一個 handler 實例,它會被
57、多個 Channel 的 Pipeline 共享, 會被多線程并發(fā)調(diào)用,因此它不是線程安全的;6. 作者簡介,2007 年畢業(yè)于東如果存在跨 ChannelHandler 的實例級變量共享,需要特別注意,它可能不是線程安全的。我有一個非線程安全的類ThreadUnsafeClass,這個類會在 channelRead 方法中被調(diào)用。我下學(xué),2008 年進的設(shè)計和開入公司從事高性能通信非線程安全的跨ChannelHandler 變量原理如下圖。Netty 支持在添加ChannelHandler 的時候,發(fā)工作,有 7 年 NIO 設(shè)計和開發(fā)經(jīng)驗,精通Netty、Mina 等 NIO 框架和中間件
58、,現(xiàn)任指定執(zhí)行該 Handler 的 EventExecutroup,架構(gòu)部架構(gòu)師,Netty指這就意味著在整個 ChannelPipeline 執(zhí)行過程中,可能會發(fā)生線程切換。此時,如果同一個對象在多個 ChannelHandler 中被共享, 可能會被多線程并發(fā)操作。(見下圖)南作者。目前從事的架構(gòu)設(shè)計工作。下一間件和 PaaS:Nettying:Netty 之家。:Nettying2425專題| TopicKafka設(shè)計(四):Kafka Consumer作者High Level Consumer很多時候,客戶程序只是希望從 KafkaGroup。ZooKeeper 中 Consumer
59、 相關(guān)節(jié)點如圖所示。數(shù)很多傳統(tǒng)的 Message Queue 都會在消息被消費完后將消息刪除,一方面避免重復(fù)消費,另一方面可以保證Queue 的長度比較短,提高效率。而如上文所述,Kafka 并不刪除已消費的消息,為了實現(xiàn)傳統(tǒng) Message Queue 消息只被消費一次的語義,Kafka 保證每條消息在同一個 Consumer Group 里只會被某一個 Consumer 消費。與傳統(tǒng) Message Queue 不同的是,Kafka還允許不同 Consumer Group 同時消費同一條消息,這一特性可以為消息的多元化處理提供支持。據(jù),不太關(guān)心消息 offset 的處理。同時也希望提供一些
60、語義,例如同一條消息只被某一個 Consumer 消費(單播)或被所有 Consumer消 費( 廣 播)。 因 此,Kafka High LevelConsumer 提供了一個從 Kafka 消費數(shù)據(jù)的抽象,從而義。掉其中的細(xì)節(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)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 甲供材料合同范本
- 幼兒園托管協(xié)議合同8篇
- 居間合同居間合同
- 2025年克拉瑪依c1貨運從業(yè)資格證考試內(nèi)容
- 工程施工監(jiān)理合同
- 專項工程承包合同文本
- 建筑工程項目分包合同
- 增加附錄條款魚種購銷合同
- 運輸水合同范本
- 卷煙戰(zhàn)略市場規(guī)劃報告
- GB/T 30797-2014食品用洗滌劑試驗方法總砷的測定
- GB/T 20057-2012滾動軸承圓柱滾子軸承平擋圈和套圈無擋邊端倒角尺寸
- GB/T 19808-2005塑料管材和管件公稱外徑大于或等于90mm的聚乙烯電熔組件的拉伸剝離試驗
- 班組建設(shè)工作體系課件
- 第章交通調(diào)查與數(shù)據(jù)分析課件
- 中醫(yī)院情志養(yǎng)生共64張課件
- 慢性心功能不全護理查房
- 秘書理論與實務(wù)教案
- 社區(qū)矯正人員工作手冊
- 淺圓倉滑模及倉頂板施工方案
- 應(yīng)用文第一章緒論2016春
評論
0/150
提交評論