您好,登錄后才能下訂單哦!
工程名 | 端口 | 作用 |
---|---|---|
cat-ui | 8082 | 調用入口服務 |
cat-business-consumer | 8083 | 業務消費服務 |
cat-order-service | 8084 | 訂單服務 |
cat-storage-service | 8085 | 庫存服務 |
上圖是本節實例的埋點圖,首先 cat-ui 的入口 和 調用點 加入cat埋點,cat-business-consumer的入口和調用點加入埋點,cat-order-service 和 cat-storage-service 不再調用其他微服務,所以只在入口加入埋點。通過這樣的埋點,可以組成一條完整的調用鏈。
/**
* Cat.context接口實現類,用于context調用鏈傳遞,相關方法Cat.logRemoteCall()和Cat.logRemoteServer()
*/
public class CatContextImpl implements Cat.Context {
private Map<String, String> properties = new HashMap<>(16);
@Override
public void addProperty(String key, String value) {
properties.put(key, value);
}
@Override
public String getProperty(String key) {
return properties.get(key);
}
}
/**
* 添加header常量,用于http協議傳輸rootId、parentId、childId三個context屬性
*/
public class CatHttpConstants {
/**
* http header 常量
*/
public static final String CAT_HTTP_HEADER_ROOT_MESSAGE_ID = "X-CAT-ROOT-MESSAGE-ID";
public static final String CAT_HTTP_HEADER_PARENT_MESSAGE_ID = "X-CAT-ROOT-PARENT-ID";
public static final String CAT_HTTP_HEADER_CHILD_MESSAGE_ID = "X-CAT-ROOT-CHILD-ID";
}
/**
* http協議傳輸,遠程調用鏈目標端接收context的filter,
* 通過header接收rootId、parentId、childId并放入CatContextImpl中,調用Cat.logRemoteCallServer()進行調用鏈關聯
* 注:若不涉及調用鏈,則直接使用cat-client.jar中提供的filter即可
* 使用方法(視項目框架而定):
* 1、web項目:在web.xml中引用此filter
* 2、Springboot項目,通過注入bean的方式注入此filter
*/
public class CatServletFilter implements Filter {
private String[] urlPatterns = new String[0];
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String patterns = filterConfig.getInitParameter("CatHttpModuleUrlPatterns");
if (patterns != null) {
patterns = patterns.trim();
urlPatterns = patterns.split(",");
for (int i = 0; i < urlPatterns.length; i++) {
urlPatterns[i] = urlPatterns[i].trim();
}
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
String url = request.getRequestURL().toString();
for (String urlPattern : urlPatterns) {
if (url.startsWith(urlPattern)) {
url = urlPattern;
}
}
CatContextImpl catContext = new CatContextImpl();
catContext.addProperty( Cat.Context.ROOT, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID));
catContext.addProperty(Cat.Context.PARENT, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID));
catContext.addProperty(Cat.Context.CHILD, request.getHeader(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID));
Cat.logRemoteCallServer(catContext);
Transaction t = Cat.newTransaction( CatConstants.TYPE_URL, url);
try {
Cat.logEvent("Service.method", request.getMethod(), Message.SUCCESS, request.getRequestURL().toString());
Cat.logEvent("Service.client", request.getRemoteHost());
filterChain.doFilter(servletRequest, servletResponse);
t.setStatus(Transaction.SUCCESS);
} catch (Exception ex) {
t.setStatus(ex);
Cat.logError(ex);
throw ex;
} finally {
t.complete();
}
}
@Override
public void destroy() {
}
}
本節實例中每個工程都會用到調用鏈上下文通用類。
@Component
public class CatRestInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
Transaction t = Cat.newTransaction(CatConstants.TYPE_REMOTE_CALL, request.getURI().toString());
try {
HttpHeaders headers = request.getHeaders();
// 保存和傳遞CAT調用鏈上下文
Cat.Context ctx = new CatContextImpl();
Cat.logRemoteCallClient(ctx);
headers.add(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID, ctx.getProperty(Cat.Context.ROOT));
headers.add(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID, ctx.getProperty(Cat.Context.PARENT));
headers.add(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID, ctx.getProperty(Cat.Context.CHILD));
// 保證請求繼續被執行
ClientHttpResponse response = execution.execute(request, body);
t.setStatus(Transaction.SUCCESS);
return response;
} catch (Exception e) {
Cat.getProducer().logError(e);
t.setStatus(e);
throw e;
} finally {
t.complete();
}
}
}
CatServletFilter 對 cat-ui 的入口進行了埋點,CatRestInterceptor 實現 ClientHttpRequestInterceptor接口 可以對 RestTemplate 發起的請求進行攔截,利用這一點對調用點埋點,同時在 Http Header 中存入 調用鏈的上下文,將調用鏈傳遞下去。
cat-business-consumer、cat-order-service、cat-storage-service 中的埋點與 cat-ui 埋點的方式相同。
發起請求
curl http://127.0.0.1:8082/start
cat 監控界面可以看到本節實例的服務。
點開 “logView” 可以看到完整的調用鏈信息。
點擊 “Graph” 查看圖表形式的調用鏈信息。
https://github.com/gf-huanchupk/SpringCloudLearning/tree/master/chapter15
https://github.com/dianping/cat/wiki
歡迎關注我的公眾號《程序員果果》,關注有驚喜~~
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。