当前位置: 首页 > 后端技术 > Java

三分钟,你将学会如何在SpringBoot项目中集成CAT调用链

时间:2023-04-01 19:09:33 Java

买买买结算系统。一年一度的双十一购物狂欢节即将来临,又到了剁手党开始表演的时候了。当我们将种草已久的商品放入购物车,点击“结算”按钮后,就会来到购物所需的结算页面。我们来创建一个虚构的买买买结算系统,为结算页面提供商品、促销、库存等结算信息。基于此系统,如何在SpringBoot项目中集成CAT调用链。买买买结算系统包括以下四项:结算UI:为前端页面提供基础结算数据。ShoppingCartAPI:获取用户购物车中有哪些商品。商品API:获取商品详情商品促销API:获取商品促销信息商品库存API:获取商品库存信息时序图如下:通过Maven添加依赖com.dianping.catcat-client3.0.0配置client.xml创建/data/appdatas/cat/目录,并创建client.xml文件:注意:将127.0.0.1替换为CAT服务器的IP。配置项目名称buybuybuy结算系统中有5个项目,每个项目都需要配置自己的项目名称。首先,在每个项目中创建以下文件:src/main/resources/META-INF/app.properties然后,在每个项目中添加以下内容:CheckoutUI:app.name=buy-buy-buy-checkoutShoppingCartAPI:app.name=buy-buy-buy-cart产品API:app.name=buy-buy-buy-product产品促销API:app.name=buy-buy-buy-promotion产品库存API:app.name=buy-buy-buy-store注意:商品名称只能包含英文字母(a-z、A-Z)、数字(0-9)、下划线(_)和破折号(-)。先写两个公共类,方便后面调用。第一个类实现了Cat.Context接口来存储调用链上下文信息:publicclassCatContextimplementsCat.Context{privateMapproperties=newHashMap<>();@OverridepublicvoidaddProperty(Stringkey,Stringvalue){properties.put(key,value);}@OverridepublicStringgetProperty(Stringkey){returnproperties.get(key);}@OverridepublicStringtoString(){return"CatContext{"+"properties="+properties+'}';}}第二个类定义了一些常量,作为调用API时header中的key。公共类CatHttpConstants{publicstaticfinalStringCAT_HTTP_HEADER_CHILD_MESSAGE_ID="DD-CAT-CHILD-MESSAGE-ID";publicstaticfinalStringCAT_HTTP_HEADER_PARENT_MESSAGE_ID="DD-CAT-PARENT-MESSAGE-ID";publicstaticfinalStringCAT_HTTP_HEADER_ROOT_MESSAGE_ID="DD-CAT-ROOT-MESSAGE-ID";}开始埋点使用CAT进行分布式调用链监控,需要修改工程中埋点代码:埋点when刚刚收到请求。在准备调用API时埋入。那么buybuybuy结算系统需要做哪些代码修改呢?看时序图的变化就明白了:第一个埋点,刚收到请求的时候,这里是使用Filter实现的,代码如下:)抛出ServletException{}@OverridepublicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)抛出IOException,ServletException{HttpServletRequestrequest=(HttpServletRequest)servletRequest;CatContextcatContext=newCatContext();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);事务t=Cat.newTransaction(CatConstants.TYPE_URL,request.getRequestURI());尝试{Cat.logEvent("Service.method",request.getMethod(),Message.SUCCESS,request.getRequestURL().toString());Cat.logEvent("Service.client",request.getRemoteHost());filterChain.doFilter(servletRequest,servletResponse);t.setStatus(交易.SUCCESS);}catch(Exceptionex){t.setStatus(ex);Cat.logError(前);扔前;}最后{t.complete();}}@Overridepublicvoiddestroy(){}}Filter已经写好了,接下来还需要把Filter注册到SpringBoot中:@ConfigurationpublicclassCatConfiguration{@BeanpublicFilterRegistrationBeancatServletFilter(){FilterRegistrationBeanregistration=newFilterRegistrationBean();CatServletFilterfilter=newCatServletFilter();注册.setFilter(过滤器);registration.addUrlPatterns("/*");registration.setName("cat-servlet-filter");注册.setOrder(1);返回注册;}}第二个埋点,在调用API的HttpClient工具类中增加一个代码,以GET方式为例子:publicstaticStringdoGet(Stringurl)throwsIOException{HttpGethttpGet=newHttpGet(url);CloseableHttpResponse响应=null;CloseableHttpClienthttpClient=HttpClientBuilder.create().build();字符串内容=空;事务t=Cat.newTransaction(CatConstants.TYPE_URL,url);尝试{上下文ctx=newCatContext();Cat.logRemoteCallClient(ctx);httpGet.setHeader(CatHttpConstants.CAT_HTTP_HEADER_ROOT_MESSAGE_ID,ctx.getProperty(Cat.Context.ROOT));httpGet.setHeader(CatHttpConstants.CAT_HTTP_HEADER_PARENT_MESSAGE_ID,ctx.getProperty(Cat.Context.PARENT));httpGet.setHeader(CatHttpConstants.CAT_HTTP_HEADER_CHILD_MESSAGE_ID,ctx.getProperty(Cat.Context.CHILD));响应=httpClient.execute(httpGet);如果(重新ponse.getStatusLine().getStatusCode()==200){content=EntityUtils.toString(response.getEntity(),"UTF-8");t.setStatus(交易.SUCCESS);}}catch(Exceptione){Cat.logError(e);t.setStatus(e);扔e;}finally{if(response!=null){response.close();}if(httpClient!=null){httpClient.close();}t.complete();}returncontent;}结束语以上是SpringBoot集成CAT调用链的完整示例,可以灵活应用,更优雅的集成到实际项目中。另外,CAT还有很多丰富的功能,可以在官网找到。