1. 概述
本文主要分享 SkyWalking DataCarrier 异步处理库。
基于生产者消费者的模式,大体结构如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/0fe6d9e60798a60c1edde8efba9d666f.webp?x-image-process=image/format,png)
实际项目中,没有 Producer 这个类。所以本文提到的 Producer ,更多的是一种角色。
下面我们来看看整体的项目结构,如下图所示 :
![](https://i-blog.csdnimg.cn/blog_migrate/f0ee8979e85be6f2928ea60fa7eb91dd.webp?x-image-process=image/format,png)
org.skywalking.apm.commons.datacarrier.buffer 包,主要包含 Channels 、Buffer 两个类。Channels 是 Buffer 数组的封装。
具有1-5工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加群。在公司待久了,过得很安逸,
但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加群。如果没有工作经验,但基础非常扎实,对java工作
机制,常用设计思想,常用java开发框架掌握熟练的可以加群。java架构群:582505643一起交流。
org.skywalking.apm.commons.datacarrier.buffer.Buffer ,缓存区。
buffer 属性,缓冲数组。Producer 保存的数据到 buffer 里。
strategy ,缓冲策略( org.skywalking.apm.commons.datacarrier.buffer.BufferStrategy ) 。
index 属性,递增位置( org.skywalking.apm.commons.datacarrier.common.AtomicRangeInteger )。
Buffer 在保存数据时,把 buffer 作为一个 “环“,使用 index 记录最后存储的位置,不断向下,循环存储到 buffer 中。通过这样的方式,带来良好的存储性能,避免扩容问题。But ,存储会存在冲突的问题:buffer 写入位置,暂未被消费,已经存在值。此时,根据不同的 BufferStrategy 进行处理。整体流程见 #save(data) 方法。
当 Buffer 被 Consumer 消费时,被调用 #obtain(start, end) 方法,获得数据并清空。为什么会带 start 、end 方法参数呢?下文揭晓答案。
org.skywalking.apm.commons.datacarrier.buffer.Channels ,内嵌多个 Buffer 的通道。