首先来看一个基本的CAT埋点操作:
public static void main(String[] args) { Transaction transaction = Cat.newTransaction("type","transaction"); transaction.addData("key","value"); transaction.setStatus(Transaction.SUCCESS); transaction.complete(); }
复制
上面这段代码记录了一个简单的transaction就完成了,再让线程sleep一段时间就可以在服务端页面看到如下页面。(sleep是为了让消息能够发送出去)接下来我们就以Transaction为例看看CAT到底做了哪些工作。
一、创建Transaction
public static Transaction newTransaction(String type, String name) { return Cat.getProducer().newTransaction(type, name); }
复制
newTransaction方法获取消息生产者创建Transaction,而getProducer方法返回在返回调用了checkAndInitialize方法,这也是整个CAT客户端IOC的开始。想了解CAT的IOC可以查看:CAT源码分析番外篇——IOC容器Plexus。
最终的newTransaction操作:
public Transaction newTransaction(String type, String name) { if (!m_manager.hasContext()) { m_manager.setup(); } if (m_manager.isMessageEnabled()) { DefaultTransaction transaction = new DefaultTransaction(type, name, m_manager); m_manager.start(transaction, false); return transaction; } else { return NullMessage.TRANSACTION; } }
复制
检查消息管理器有没有Context,没有就建一个。创建的时候涉及到一个很重要的类:DefaultMessageTree。
判断是否可以记录消息,可以就开启事务。否则返回一个空事务。在开启事务的过程中transaction被放到了消息树中。
二、添加数据和设置状态
public void addData(String key, Object value) { if (m_data instanceof StringBuilder) { ((StringBuilder) m_data).append('&').append(key).append('=').append(value); } else { String str = String.valueOf(value); int old = m_data == null ? 0 : m_data.length(); StringBuilder sb = new StringBuilder(old + key.length() + str.length() + 16); if (m_data != null) { sb.append(m_data).append('&'); } sb.append(key).append('=').append(str); m_data = sb; } }
复制
将数据以key1=value1&key2=value2&key3=value3…的格式累加。状态用到的一般是成功和异常。
三、Transaction完成
public void complete() { try { if (isCompleted()) { DefaultEvent event = new DefaultEvent("cat", "BadInstrument"); event.setStatus("TransactionAlreadyCompleted"); event.complete(); addChild(event); } else { m_durationInMicro = (System.nanoTime() - m_durationStart) / 1000L; setCompleted(true); if (m_manager != null) { m_manager.end(this); } } } catch (Exception e) { // ignore } }
复制
当transaction已经完成时,会记录错误调用;没完成则通过消息管理器结束该transaction。而实际的结束transaction又交给了context。
public boolean end(DefaultMessageManager manager, Transaction transaction) { if (!m_stack.isEmpty()) { Transaction current = m_stack.pop(); if (transaction == current) { m_validator.validate(m_stack.isEmpty() ? null : m_stack.peek(), current); } else { while (transaction != current && !m_stack.empty()) { m_validator.validate(m_stack.peek(), current); current = m_stack.pop(); } } if (m_stack.isEmpty()) { MessageTree tree = getM_tree().copy(); getM_tree().setMessageId(null); getM_tree().setMessage(null); if (m_totalDurationInMicros > 0) { adjustForTruncatedTransaction((Transaction) tree.getMessage()); } manager.flush(tree); return true; } } return false; }
复制
context做了一系列处理后,会调用flush方法将消息树发送出去。
public void flush(MessageTree tree) { if (tree.getMessageId() == null) { tree.setMessageId(nextMessageId()); } MessageSender sender = m_transportManager.getSender(); if (sender != null && isMessageEnabled()) { sender.send(tree); reset(); } else { m_throttleTimes++; if (m_throttleTimes % 10000 == 0 || m_throttleTimes == 1) { m_logger.info("Cat Message is throttled! Times:" + m_throttleTimes); } } }
复制
可以看到,消息管理器中持有了传输管理器,而传输管理器中的消息发送器就是专门负责小学发送的。这个会在下一篇中详细介绍。
文章转载自贰级天災,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
数据库国产化替代深化:DBA的机遇与挑战
代晓磊
1267次阅读
2025-04-27 16:53:22
2025年4月国产数据库中标情况一览:4个千万元级项目,GaussDB与OceanBase大放异彩!
通讯员
740次阅读
2025-04-30 15:24:06
国产数据库需要扩大场景覆盖面才能在竞争中更有优势
白鳝的洞穴
609次阅读
2025-04-14 09:40:20
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
516次阅读
2025-04-17 17:02:24
一页概览:Oracle GoldenGate
甲骨文云技术
483次阅读
2025-04-30 12:17:56
GoldenDB数据库v7.2焕新发布,助力全行业数据库平滑替代
GoldenDB分布式数据库
474次阅读
2025-04-30 12:17:50
优炫数据库成功入围新疆维吾尔自治区行政事业单位数据库2025年框架协议采购!
优炫软件
363次阅读
2025-04-18 10:01:22
给准备学习国产数据库的朋友几点建议
白鳝的洞穴
331次阅读
2025-05-07 10:06:14
XCOPS广州站:从开源自研之争到AI驱动的下一代数据库架构探索
韩锋频道
292次阅读
2025-04-29 10:35:54
国产数据库图谱又上新|82篇精选内容全览达梦数据库
墨天轮编辑部
278次阅读
2025-04-23 12:04:21