简述
前篇文章简单的介绍了aeron框架的架构与其到底能做什么,今天就让我们从一个demo出发,开始揭开aeron的神秘面纱
demo
ini
public static void main(String[] args)
{
final String channel = "aeron:ipc";
final String message = "my message";
final IdleStrategy idle = new SleepingIdleStrategy();
final UnsafeBuffer unsafeBuffer = new UnsafeBuffer(ByteBuffer.allocate(256));
try (MediaDriver driver = MediaDriver.launch();
Aeron aeron = Aeron.connect();
Subscription sub = aeron.addSubscription(channel, 10);
Publication pub = aeron.addPublication(channel, 10))
{
while (!pub.isConnected())
{
idle.idle(); // 简单理解为阻塞即可
}
unsafeBuffer.putStringAscii(0, message);
System.out.println("sending:" + message);
while (pub.offer(unsafeBuffer) < 0)
{
idle.idle();
}
FragmentHandler handler = (buffer, offset, length, header) ->
System.out.println("received:" + buffer.getStringAscii(offset));
while (sub.poll(handler, 1) <= 0)
{
idle.idle();
}
}
}
result:
makefile
sending:my message
received:my message
关键点
- MediaDriver.launch()
- Aeron.connect()
- aeron.addSubscription
- aeron.addPublication
- pub.offer
- pub.poll
MediaDriver
MediaDriver的作用
引入官网的描述:
rust
The Media Driver component is responsible for managing the sending and receiving of
data over the media (UDP or IPC) in use for any active publications and/or subscriptions
翻译过来其实就是:media driver其实可以通过udp/ipc的方式来接收数据,然后发布给其他的pub和sub
MediaDriver核心组件
- Driver Conductor
用来接受发布者和订阅者的命令
- Receiver
使用udp协议,负责从连接的media接收数据,并且和使用java nio和操作系统的网格堆栈进行交互
- Sender
通过media driver来发送数据
- Client Conductor
用来和Driver Conductor通信
MediaDriver的线程模型
- Dedicated 三个线程,默认模式;receiver一个,sender一个,Driver Conductor一个
- Shared Network 两个线程,
- Shared 只开启一个线程
- Invoker 不开启任何线程
MediaDriver.launch()方法都做了什么
通过上述流程图可以看到,MediaDriver.launch的核心作用是其实是根据当前的线程模型,去初始化Receiver/Sender/DriverConductor,这里只列出了DriverConducto的流程: DriverConductor的doWork方法,可以简单理解成我们线程的run方法,如果我们的线程模型使用的Dedicated模式,则会有一个线程不断调用其doWokr方法,从"cncFile"不断的轮训命令,并把解析的数据放入cncFile对应的ringBuffer里
- 什么是cncFifle? 对应着机器硬盘里的cnc.data文件。
command and control file used between driver and clients
客户端和MediaDriver之间的共享命令的文件
Aeron客户端
Aeron.connect与pub
Aeron.connect方法上述流程图可以看出来,先会初始化ClientConductor,然后调用connectToDriver的方法,生成cncFile对应的bytebuffer。 调用Aeron客户单addSub的时候,也是把命令最终发送到cncFile里,然后MediaDeriver里的Driver Conductor线程通过不断的轮训cncFile文件,来获取对应的命令。
小结
本文通过demo入手,分析了MediaDeriver的基本构成与作用,以及aeron客户端是如何和MediaDeriver进行交互的,aeron架构同于我们常见的一些架构源码,不是那种A调用了B,B调用了C这种同步调用,很多时候,大部分都是异步通信,所以看源码的时候一定要一边记笔记,剥茧抽丝,最终所有的知识点肯定都会贯通的。大家如果有什么问题,可以在评论区里评论交流哦。