本文的異常處理分爲兩種,第一種講的是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應用調用的。 ---------------------