自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

借助 AOP 為 Java Web 應(yīng)用記錄性能數(shù)據(jù)

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

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

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

[[147869]]

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

然而無論自建 APM 還是使用 Saas 服務(wù),其底層模型無非就是海量日志的實(shí)時處理,數(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ù)為王的時代,夸張一點(diǎn)說,數(shù)據(jù)可以指導(dǎo)一切!

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

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

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

抓取調(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)用。

在實(shí)現(xiàn) Profiler 的時候,需要給每個線程維護(hù)一個調(diào)用棧,以及剖析結(jié)果列表?;旧峡梢詫?shí)現(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é)的方式,以無入侵的方式實(shí)現(xiàn)對 Profiler 的正確調(diào)用。AOP 是一種合適的工具。

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

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

  1. <dependency> 
  2.     <groupId>org.springframework</groupId> 
  3.     <artifactId>spring-aop</artifactId> 
  4.     <version>2.5.6</version> 
  5. </dependency> 

如果需要代碼能夠運(yùn)行,還需要引入 cglib 的依賴。

  1. <dependency> 
  2.     <groupId>cglib</groupId> 
  3.     <artifactId>cglib-nodep</artifactId> 
  4.     <version>2.2</version> 
  5. </dependency> 

方法攔截器的參考實(shí)現(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.     } 
責(zé)任編輯:王雪燕 來源: 潘家邦
相關(guān)推薦

2016-11-28 09:13:29

單頁Web模板數(shù)據(jù)

2025-02-11 09:39:00

2013-01-04 13:47:52

CompuwareAPM

2021-03-01 23:26:41

日志Spring BootAOP

2018-09-10 12:14:59

Modern數(shù)據(jù)架構(gòu)IBM

2013-01-14 12:24:06

Firefox OS

2009-03-23 10:04:46

Java Web入侵檢Java Web應(yīng)用EasyJWeb

2009-08-25 15:35:45

citrxinetscalerncore

2013-08-16 10:14:32

APIWeb應(yīng)用以API為中心的Web

2020-06-08 19:30:21

大數(shù)據(jù)技術(shù)智能建筑

2009-06-03 10:32:36

Oracle性能優(yōu)化分區(qū)技術(shù)

2010-04-02 15:20:44

惠普成功案例

2013-07-26 17:07:33

Foglight容量

2010-08-25 09:48:14

W3CWeb性能工作組

2013-08-09 14:18:33

2016-08-23 14:37:21

2023-12-26 00:58:53

Web應(yīng)用Go語言

2019-10-17 10:10:23

優(yōu)化Web前端

2021-08-30 09:56:59

Web安全攻擊Java

2023-02-21 14:16:42

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號