日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
借助AOP為JavaWeb應(yīng)用記錄性能數(shù)據(jù)

作為開發(fā)者,應(yīng)用的性能始終是我們最感興趣的話題之一。然而,不是所有的開發(fā)者都對自己維護(hù)的應(yīng)用的性能有所了解,更別說快速定位性能瓶頸并實施解決方案了。

創(chuàng)新互聯(lián)于2013年成立,先為花溪等服務(wù)建站,花溪等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為花溪企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

今年北京 Velocity 的贊助商大多從事 APM 領(lǐng)域,提供性能剖析、可視化甚至優(yōu)化的解決方案。這些廠商的產(chǎn)品看起來能夠很好地幫助中小企業(yè)的開發(fā)者解決應(yīng)用性能上的缺陷,但是這些產(chǎn)品幾乎都有著一個致命的缺陷:極強(qiáng)的侵入性。

開發(fā)者需要在業(yè)務(wù)生產(chǎn)代碼中嵌入 APM 廠商提供的埋點代碼,才能夠使用 APM 廠商提供的 Saas 服務(wù)。在瞬息萬變的技術(shù)大潮中,這種代碼級別的侵入和綁定,總是讓開發(fā)者憂心忡忡。如果我作為架構(gòu)師,在自建 APM 還是使用 Saas APM 上,我也會謹(jǐn)慎考慮。

然而無論自建 APM 還是使用 Saas 服務(wù),其底層模型無非就是海量日志的實時處理,數(shù)據(jù)來源就是應(yīng)用產(chǎn)生的性能日志了。

If we have data, let’s look at data. If all we have are opinions, let’s go with mine.

Jim Barksdale

這是一個數(shù)據(jù)為王的時代,夸張一點說,數(shù)據(jù)可以指導(dǎo)一切!

言歸正傳,如果我們不希望使用 APM 嘗試提供的強(qiáng)侵入的服務(wù),我們就只能自建服務(wù)了,比如以 AOP 的方式采集線程內(nèi)調(diào)用樹以及調(diào)用開銷并輸出日志,然后使用 ELK(Elasticsearch, Logstash, and Kibana) 去采集日志并提供搜索、可視化等功能。如果采集的日志僅作為離線計算使用,可以直接用 Flume 把日志寫入 HDFS。

隨著系統(tǒng)流量越來越大,上述的方案漸漸就扛不住了,然后就需要自己實現(xiàn)高性能的日志采集 Agent,把采集到的日志一股腦寫入 Kafuka 之類的能扛大量堆積消息的 MQ 里面,然后使用 Storm/JStorm 做實時的流式計算。

前些日子我簡單搞了一個基于 AOP 來抓取調(diào)用樹和開銷的嘗試,感覺有點意思,分享一下。

抓取調(diào)用樹和時間開銷

在 Java 里面獲取代碼塊的時間開銷最常見的手段就是 System.currentTimeMillis()。Apache 和 Guava 等流行類庫都有對獲取時間開銷這一功能的封裝類 StopWatch。

捕獲調(diào)用樹就沒有什么常見的封裝了。一種推薦的做法,是在一次調(diào)用中,給每個要剖析的代碼塊一個唯一的標(biāo)記,這個標(biāo)記要能夠體現(xiàn)代碼塊之間的嵌套、順序等關(guān)系。

舉個栗子,我們有如下調(diào)用關(guān)系。

 
 
  1. func1
  2. +- func2
  3. |  +- func3
  4. |  /- func4
  5. /- func5

為了體現(xiàn)調(diào)用之間的嵌套和順序,我們給 func1 標(biāo)記 0,給 func2 標(biāo)記 0.1,給 func3 標(biāo)記 0.1.1,給 func4 標(biāo)記 0.1.2,給 func5 標(biāo)記 0.2。如此一來,我們便能夠輕易地根據(jù)標(biāo)記重建出調(diào)用樹。

我們可以把調(diào)用樹的抓取和記錄每個代碼塊的時間開銷的功能以線程安全的手法封裝起來,給這個封裝起一個類似于 Profiler 的名字。Profiler 提供 2 個靜態(tài)方法,enter 在進(jìn)入代碼塊之前調(diào)用,exit 在代碼塊結(jié)束之后調(diào)用。

在實現(xiàn) Profiler 的時候,需要給每個線程維護(hù)一個調(diào)用棧,以及剖析結(jié)果列表?;旧峡梢詫崿F(xiàn)為 enter 壓棧,exit 退棧并把結(jié)果放入結(jié)果列表,當(dāng)調(diào)用棧退空后,輸出完整的剖析結(jié)果。

AOP 與方法攔截器

Profiler 有一個需要嚴(yán)格執(zhí)行的約定,就是 enter 和 exit 必須成對調(diào)用,就像 C++ 里面 new 和 delete 必須成對出現(xiàn)一樣,否則內(nèi)存會被直接打爆,遠(yuǎn)不是內(nèi)存泄露這么簡單。

這種約定如果寫到業(yè)務(wù)代碼中,會死的很難看,各種 try finally 硬生生的把業(yè)務(wù)邏輯打斷,本來業(yè)務(wù)代碼就已經(jīng)很惡心了,這么一搞簡直沒法維護(hù)。

所以我們需要一種比較科學(xué)的方式,以無入侵的方式實現(xiàn)對 Profiler 的正確調(diào)用。AOP 是一種合適的工具。

這里以 Spring AOP 為例,實現(xiàn)一個簡單的例子。

首先引入 Spring AOP 的依賴,或者包含 org.aopalliance.intercept.MethodInterceptor 的包。

 
 
  1.     org.springframework
  2.     spring-aop
  3.     2.5.6

如果需要代碼能夠運行,還需要引入 cglib 的依賴。

 
 
  1.     cglib
  2.     cglib-nodep
  3.     2.2

方法攔截器的參考實現(xiàn)如下,使用 try finally 這樣的 code pattern 去保證 Profiler 被正確使用。

 
 
  1. public class Interceptor implements MethodInterceptor {
  2.     @Override
  3.     public Object invoke(MethodInvocation invocation) throws Throwable {
  4.         Class clazz = invocation.getMethod().getDeclaringClass();
  5.         String method = invocation.getMethod().getName();
  6.         String mark = clazz.getCanonicalName() + "#" + method;
  7.         Profiler.enter(mark);
  8.         try {
  9.             return invocation.proceed();
  10.         } finally {
  11.             String log = Profiler.exit();
  12.             if (log != null) {
  13.                 System.out.println(log);
  14.             }
  15.         }
  16.     }
  17. }

名稱欄目:借助AOP為JavaWeb應(yīng)用記錄性能數(shù)據(jù)
文章路徑:http://www.dlmjj.cn/article/dhsicdj.html