sleuth+zipkin系列之異常處理(十三)

本文的異常處理分爲兩種,第一種講的是zipkin原生的異常處理,第二種就是針對實際業務作異常處理的擴展,本文的重點講的是如何根據自身的實際狀況定製異常處理。java

zipkin經過對span打tag,打上error的tag表示此次調用出錯了。web

zipkin異常處理
zipkin的默認會捕獲沒有被應用程序catch的異常,這是什麼意思?spring

這句話的意思就是,加入你程序發生了錯誤,若是異常被你程序給捕獲了,那麼zipkin就會默認此次請求是成功的。api

若是應用將異常一直往外拋,沒有作任何處理,這就被zipkin給獲取到了,那麼zipkin就會默認此次請求是失敗的,會打對此次請求產生的span打上error的tag .網絡

自定義異常處理
咱們本身的應用,確定都是有統一的異常處理的,因此沒有處理的異常,一直往外拋的異常能夠說不多的, 有時候判斷一個調用鏈是否成功,並非簡簡單單的判斷這個應用程序有沒有出錯,有沒有報異常。 至少對我來講,我但願看到的是這個調用鏈的實際執行結果,執行失敗了,那麼爲何執行會執行失敗?是參數不符合要求? 仍是網絡異常? 仍是一些條件不符合? 這些我都想收集到, 那麼,這種狀況怎麼辦,默認的zipkin是不會知足的。 其實要實現這種功能很簡單,一個切面就能夠搞定。app

/**
 * @Author 張雲和
 * @Date 2018/8/20
 * @Time 11:36
 */
@Aspect
@Component
@Slf4j
public class ResponseStatusAspect {
  
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void requestMapping() {}
    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)")
    public void postMapping() {}
    @Pointcut("@annotation(org.springframework.web.bind.annotation.PutMapping)")
    public void putMapping() {}
    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    public void getMapping() {}
    @Pointcut("@annotation(org.springframework.web.bind.annotation.DeleteMapping)")
    public void deleteMapping() {}
    @Pointcut("@annotation(org.springframework.web.bind.annotation.PatchMapping)")
    public void patchMapping() {}
    // 全局的trace對象
    @Autowired
    Tracer tracer;
     // 針對全部Controller層的方法的切面
    @Around("requestMapping() || postMapping() || putMapping() || getMapping() || deleteMapping() || patchMapping()")
    public Object doSurround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
         
        // 方法的執行結果
        Object result = proceedingJoinPoint.proceed();post

        try {
            // 返回值爲空的直接跳過
            if(null!=result){
                // 結果轉換
                BaseResult baseResult = (BaseResult) result;
                // 判斷是否執行成功
                if(!baseResult.isSuccess()){
                    // 執行失敗,打上錯誤標籤
                    tracer.addTag("error",baseResult.getErrorMessage());
                }
            }
           // 針對這一塊,使用try catch , 保證不會影響程序的正常運行
        }catch (Exception ignored){}spa

        return result;
    }.net

}對象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
例:

@RequestMapping("/api/login")
public BaseResult login(User user) throws Exception {
  // 
  return userService.login(user);
}

1
2
3
4
5
6
1
2
3
4
5
6


總結:

Trace對象是spring容器中一個針對span操做的對象, 每一個span對象是存儲在ThreadLocal中的,因此當一個請求進來以後,能夠隨時對他進行添加修改的操做。

上面的這種作法,使用一個切面就解決了, 這種作法,須要公司內部的java應用的返回值格式要高度統一。由於這個切面咱們最終是會作成一個starter包,供各個java應用調用的。 --------------------- 

相關文章
相關標籤/搜索