Flink数据源拆解分析(WikipediaEditsSource)

//结束时要向服务器发送数据表示离开

ircStream.leave(channel);

}

}

}

上面的代码,我们挑几处重要的展开看一看;

和维基百科消息服务器建立连接后做的事情

  1. 为了弄明白Flink是如何与维基百科的数据源建立连接的,先把ircStream.connect()这段代码展开,对应的是IRCConnection类的connect方法:

public void connect() throws IOException {

if (level != 0) // otherwise disconnected or connect

throw new SocketException(“Socket closed or already open (”+ level +“)”);

IOException exception = null;

Socket s = null;

for (int i = 0; i < ports.length && s == null; i++) {

try {

//建立的是普通Socket连接

s = new Socket(host, ports[i]);

exception = null;

} catch (IOException exc) {

if (s != null)

s.close();

s = null;

exception = exc;

}

}

if (exception != null)

throw exception; // connection wasn’t successful at any port

prepare(s);

}

上述代码表明,Flink与维基百科的数据源服务器之间建立的是普通的Socket连接,至于IRC协议,都是在这个Socket连接的通道里的一些读写操作;

  1. 上面的prepare方法比较关键,展开看看:

protected void prepare(Socket s) throws IOException {

if (s == null)

throw new SocketException(“Socket s is null, not connected”);

socket = s;

level = 1;

s.setSoTimeout(timeout);

in = new BufferedReader(new InputStreamReader(s.getInputStream(),

encoding));

out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),

encoding));

//IRCConnection是Thread的子类,执行start方法就表明会启动一个线程来执行IRCConnection的run方法

start();

//遵守IRC协议约定,发送一些注册相关的内容

register();

}

可以看出,prepare方法做了两个重要的事情:启动一个子线程、发送IRC协议的注册信息,接下来看启动的子线程做了什么;

  1. 打开IRCConnection的run方法:

public void run() {

try {

String line;

while (!isInterrupted()) {

line = in.readLine();

if (line != null)

get(line);

else

close();

}

} catch (IOException exc) {

close();

}

}

run方法中的内容很简单,就是让这个子线程负责读取远端发送的字符串,每读到一行就调用get方法去处理;

  1. get方法的内容很多,做的事情是根据IRC协议解析这个字符串再做不同的处理,这里我们只要关注下面这段,就是收到一条业务消息后如何处理:

//每当有人编辑了维基百科,这里就会收到一条command为PRIVMSG的记录

if (command.equalsIgnoreCase(“PRIVMSG”)) { // MESSAGE

IRCUser user = p.getUser();

String middle = p.getMiddle();

String trailing = p.getTrailing();

for (int i = listeners.length - 1; i >= 0; i–)

//调用listener的onPrivmsg方法

listeners[i].onPrivmsg(middle, user, trailing);

}

如上所示,每收到一条远端发来的消息,都会调用listener的onPrivmsg方法,这里的注册的linstener是WikipediaIrcChannelListener对象;

  1. 打开WikipediaIrcChannelListener的onPrivmsg方法,看看收到消息后做了什么:

@Override

public void onPrivmsg(String target, IRCUser user, String msg) {

LOG.debug(“[{}] {}: {}.”, target, user.getNick(), msg);

//根据消息构造一个WikipediaEditEvent对象,就是Flink的业务流程中用到的数据对象

WikipediaEditEvent event = WikipediaEditEvent.fromRawEvent(

System.currentTimeMillis(),

target,

msg);

if (event != null) {

//eidts是个阻塞队列,WikipediaEditEvent被放入队列

if (!edits.offer(event)) {

LOG.debug(“Dropping message, because of full queue.”);

}

}

}

上面的代码已经分析把主要逻辑展现出来了,从Socket读到的数据被解析成Flink实时计算时用到的WikipediaEditEvent对象后,被放入阻塞队列中,这也就是负责读取的子线程的主要工作了;

如何消费队列中的数据

前面的分析中我们得知:收到的数据被放入了阻塞队列中,现在回到WikipediaEditsSource的run方法再看看,这里面就有从阻塞队列取出数据的操作:

while (isRunning) {

//从阻塞队列中获取数据

WikipediaEditEvent edit = ircStream.getEdits().poll(100, TimeUnit.MILLISECONDS);

//如果取到了数据,就调用ctx.collect方法,将数据生产到Flink环境,给其他operator使用

if (edit != null) {

ctx.collect(edit);

}

}

如上所示,一个while循环不停的从阻塞队列中获取数据,取到了就调用SourceContext的collect,把一条数据生产到在Flink环境中,给后面的流程使用;

小结

至此,WikipediaEditsSource源码的分析就完成了,在此小结一下:

  1. 和irc.wikimedia.org这个网站建立Socket连接;

  2. 连接建立后,读写相关的内容都是基于IRC协议的,这是个应用层的协议,有自己的格式、关键字、命令字等约定,本次分析中我们没有花太多时间在这个协议上,有兴趣的读者在这里了解更多:https://en.wikipedia.org/wiki/Internet_Relay_Chat

  3. 启动一个子线程读取Socket信息,收到数据后,构造成WikipediaEditEvent对象,放入阻塞队列中;

  4. 原先的那个线程在一个while循环中从阻塞队列中取数据,如果取到了数据就调用ctx.collect方法,这样数据就生产到了Flink环境,其他operator就可以使用了;

以上就是拆解WikipediaEditsSource的过程,现在我们对Flink数据源有了更进一步的了解,后续在开发自定义数据源的时候也有了参考实现;

欢迎关注我的公众号:程序员欣宸

在这里插入图片描述

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
715676027788)]

[外链图片转存中…(img-GFWGvQrU-1715676027788)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值