版权声明:坚持原创,坚持深入原理,未经博主允许不得转载!! https://blog.csdn.net/lemon89/article/details/78276018
相关文章:
[分布式监控CAT] Server端源码解析——初始化
[分布式监控CAT] Client端源码解析
[分布式监控CAT] Server端源码解析——消息消费\报表处理
定制化SDK解决埋点问题
SQL相关埋点
使用ORM插件-MybatisPlugin
效果:
Throwable(及其子类)异常上报
使用log日志框架的appender机制
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="CatAppender" />
</root>
效果:
URL请求监控
使用Filter机制实现,并实现URL聚合等其他功能
效果:
代码级别监控
aop 做监控,内部封装,将aop-expression暴露出来给用户配置(填写需要监控的实现类范围)
字节码织入技术
效果:
接口抽象\静态绑定
为了向后兼容,轻松替换埋点的实现。比如切换为zipkin或者其他产品的API。从而减少对业务线的影响。
仿照slf4j的设计,使用了静态绑定。
分布式调用链
CatCrossHttpClient作为 httpClient的代理类暴露给用户使用。
@Component
public class CatCrossHttpClient
extends HttpClientProxy
{
private String serverToCall;
public void setServerToCall(String serverToCall)
{
this.serverToCall = serverToCall;
}
public String execute(HttpRequestBase request, int socketTimeout, int connectTimeout)
throws Exception
{
Transaction t = Cat.newTransaction("PigeonCall", request.getURI().getPath());
createCrossReport(request, this.serverToCall);
Cat.Context context = new CatContext();
Cat.logRemoteCallClient(context);
request.setHeader("_catRootMessageId", context.getProperty("_catRootMessageId"));
request.setHeader("_catParentMessageId", context.getProperty("_catParentMessageId"));
request.setHeader("_catChildMessageId", context.getProperty("_catChildMessageId"));
request.setHeader("ClientApplication.Name", Cat.getManager().getDomain());
try
{
String ret = super.execute(request, socketTimeout, connectTimeout);
t.setStatus("0");
return ret;
}
catch (Exception e)
{
Cat.logEvent("HTTP_REST_CAT_ERROR", request.getURI().toString(), e.getMessage(), " ");
t.setStatus(e);
throw e;
}
finally
{
t.complete();
}
}
private void createCrossReport(HttpRequestBase request, String serverToCall)
throws Exception
{
Cat.logEvent("PigeonCall.app", serverToCall, "0", " ");
Cat.logEvent("PigeonCall.server", request.getURI().getHost(), "0", " ");
Cat.logEvent("PigeonCall.port", String.valueOf(request.getURI().getPort()), "0", " ");
MessageTree tree = Cat.getManager().getThreadLocalMessageTree();
((DefaultMessageTree)tree).setDomain(Cat.getManager().getDomain());
((DefaultMessageTree)tree).setIpAddress(InetAddress.getLocalHost().getHostAddress());
}
}
当有外部请求进来,通过如下的Filter判断请求中是否带有分布式调用链埋点,如果有就继续构造这个链条。当然分布式调用链得以使用的前提是被监控的应用中有引入这两个功能!
public class HttpCatCrossFilter
implements Filter
{
private static final Logger logger = LoggerFactory.getLogger(HttpCatCrossFilter.class);
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
throws IOException, ServletException
{
HttpServletRequest request = (HttpServletRequest)req;
if (isCatTracing(request))
{
String requestURI = request.getRequestURI();
Transaction t = Cat.newTransaction("PigeonService", requestURI);
try
{
Cat.Context context = new CatContext();
context.addProperty("_catRootMessageId", request.getHeader("_catRootMessageId"));
context.addProperty("_catParentMessageId", request.getHeader("_catParentMessageId"));
context.addProperty("_catChildMessageId", request.getHeader("_catChildMessageId"));
Cat.logRemoteCallServer(context);
createCrossReport(request, t);
filterChain.doFilter(req, resp);
t.setStatus("0");
}
catch (Exception e)
{
logger.error("Get cat msgtree error :" + e);
Cat.logEvent("HTTP_REST_CAT_ERROR", request.getRequestURL().toString(), e.getMessage(), " ");
t.setStatus(e);
}
finally
{
t.complete();
}
}
else
{
filterChain.doFilter(req, resp);
}
}
private void createCrossReport(HttpServletRequest request, Transaction t)
throws Exception
{
Cat.logEvent("PigeonService.app", request.getHeader("ClientApplication.Name"), "0", " ");
Cat.logEvent("PigeonService.client", request.getRemoteAddr(), "0", " ");
MessageTree tree = Cat.getManager().getThreadLocalMessageTree();
((DefaultMessageTree)tree).setDomain(Cat.getManager().getDomain());
((DefaultMessageTree)tree).setIpAddress(InetAddress.getLocalHost().getHostName());
}
public void init(FilterConfig arg0)
throws ServletException
{}
public void destroy() {}
private boolean isCatTracing(HttpServletRequest request)
{
return (null != request.getHeader("_catRootMessageId")) && (null != request.getHeader("_catParentMessageId")) && (null != request.getHeader("_catChildMessageId"));
}
}
效果:
各开源监控对比
zipkin:
优点:分布式调用链理论的实现系统。最大的特点是分布式调用链。Spring Cloud Sleuth 可以方便的对zipkin元数据进行采集。
缺点:功能单一,监控维度、监控信息不够丰富。没有告警功能。
pinpoint:
优点:使用字节码织入技术,对用户完全透明,实现自动埋点。可展示代码级别监控。
缺点:功能不足够丰富。对于其他非java程序,实现客户端难度大。
Cat:
优点:功能丰富,多模型报表展示。可展示代码级别监控。以及特殊业务数据监控。支持多语言客户端。多数情况可以替代日志的查看。
缺点: 手动埋点,需要改造才能减少埋点的侵入性。