Jafka Acceptor接受client而建立后的连接请求,Acceptor会将Socket连接交给Processor进行处理。Processor通过下面的处理步骤进行client请求的处理:

1. 读取client请求。

2. 依据client请求类型的不同,调用对应的处理函数进行处理。

Processor读取client请求是一个比較有意思的事情,须要考虑两个方面的事情:第一,请求规则(Processor须要依照一定的规则进行请求的解析)。第二,怎样确定一次请求的读取已经结束(由于是非堵塞连接,很有可能第一次读操作读取了请求的一部分数据,第二次到第N次读取才干把整个client请求读取完整)。以下我们具体解析一下client请求的格式。

client请求首先包括一个int,该int指明本次client请求的大小(size)。随后,请求包括一个两个byte(short)的请求类型(请求类型包括:CreaterRequest、DeleterRequest、FetchRequest、MultiFetchRequest、MultiProducerRequest、OffsetRequest和ProducerRequest。然后每种请求类型有固定的格式。下图具体说明了ProducerRequest的格式:

知道了上面的格式之后,问题二(怎样确定一次请求已经读取完毕)就非常easy攻克了。

首先为“请求长度”分配一个4byte的ByteBuffer,直到该Buffer读满,否则说明长度一直没有读取完毕。“请求长度”读取完毕后,为请求分配一个“请求长度”大小的ByteBuffer,直到该Buffer读满则说明一次请求读取完毕。读取完毕后,依据“请求类型”调用对应的处理函数(Handler)进行处理。在jafka中,上述的两个Buffer在类BoundedByteBufferReceive中进行声明和管理。Processor接收到Acceptor分配的socket连接后。会为socke连接建立一个BoundedByteBufferReceive并将其与socket连接进行绑定。每当该socket连接“可读”时。将BoundedByteBufferReceive拿出来从上次读取的基础上继续读取。直到一次请求彻底读取完毕,详细过程如以下代码(Processor.read)所看到的:

private void read(SelectionKey key) throws IOException {
SocketChannel socketChannel = channelFor(key);
Receive request = null;
request = new BoundedByteBufferReceive(maxRequestSize);
key.attach(request);
} else {
request = (Receive) key.attachment();
}
int read = request.readFrom(socketChannel);
stats.recordBytesRead(read);
if (read < 0) {
close(key);
} else if (request.complete()) {
Send maybeResponse = handle(key, request);
key.attach(null);
// if there is a response, send it, otherwise do nothing
if (maybeResponse != null) {
key.attach(maybeResponse);
key.interestOps(SelectionKey.OP_WRITE);
}
} else {
// more reading to be done
key.interestOps(SelectionKey.OP_READ);
getSelector().wakeup();
if (logger.isTraceEnabled()) {
logger.trace("reading request not been done. " + request);
}
}
}

BoundedByteBufferReceive.readFrom的实现详细例如以下:主要是申请两个Buffer并不断的读取数据。

public int readFrom(ReadableByteChannel channel) throws IOException {
expectIncomplete();
int read = 0;
if (sizeBuffer.remaining() > 0) {
read += Utils.read(channel, sizeBuffer);
}
if (contentBuffer == null && !sizeBuffer.hasRemaining()) {
sizeBuffer.rewind();
int size = sizeBuffer.getInt();
if (size <= 0) {
throw new InvalidRequestException(...);
}
if (size > maxRequestSize) {
final String msg = "Request of length %d is not valid, it is larger than the maximum size of %d bytes.";
throw new InvalidRequestException(format(msg, size, maxRequestSize));
}
contentBuffer = byteBufferAllocate(size);
}
//
if (contentBuffer != null) {
read = Utils.read(channel, contentBuffer);
//
if (!contentBuffer.hasRemaining()) {
contentBuffer.rewind();
setCompleted();
}
}
return read;
}

读取完毕后,Processor会解析“请求类型”,依据请求类型的不同调用不同的Handler处理对应于该请求。

版权声明:本文博主原创文章,博客,未经同意不得转载。

Jafka来源分析——Processor的更多相关文章

  1. Jafka来源分析——文章

    Kafka它是一个分布式消息中间件,我们可以大致分为三个部分:Producer.Broker和Consumer.当中,Producer负责产生消息并负责将消息发送给Kafka:Broker能够简单的理 ...

  2. 【JUnit4.10来源分析】6 Runner

    org.junit.runner.Runner它是JUnit作业引擎.它在许多类型的支持下的.处理试验和生产(Description).Failure和Result和其它输出. Runner参见图主类 ...

  3. 【JUnit4.10来源分析】0导航

    JUnit靠GOF 中的一个Erich Gamma和 Kent Beck 单元测试框架编写一个开源,yqj2065分析JUnit的主要目的是源 中学习对设计模式的运用. JUnit也是一个学习Java ...

  4. SDL2来源分析3:渲染(SDL_Renderer)

    ===================================================== SDL源代码分析系列文章上市: SDL2源码分析1:初始化(SDL_Init()) SDL2 ...

  5. SDL2来源分析7:演出(SDL_RenderPresent())

    ===================================================== SDL源代码分析系列文章上市: SDL2源码分析1:初始化(SDL_Init()) SDL2 ...

  6. AsyncTask来源分析(一)

    于android开发过程AsyncTask我会经常处理它.在网上,也有很多的其描述,因此,这里是不是说的用法,直接写自己的学习经验,以及它的一些浅显的认识,忘记错批评. AsyncTask它是一个抽象 ...

  7. JUnit4.8.2来源分析-2 org.junit.runner.Request

    JUnit4.8.2源代码,最为yqj2065兴趣是org.junit.runner.Request,现在是几点意味着它? ①封装JUnit的输入 JUnit4作为信息处理单元,它的输入是单元測试类- ...

  8. ftp server来源分析20140602

    ftp  server学习位和源代码分析片 记录自己的第一个开源的分析过程: 从源代码:野狐灯(我接下来的几篇文章是从源头:野狐灯,每个以下哪项不是他们设置.) 20140602 Ftp的源码目录例如 ...

  9. C语言编程学习:链表的来源分析

    C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构.C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现 ...

随机推荐

  1. poj1679(最小生成树)

    传送门:The Unique MST 题意:判断最小生成树是否唯一. 分析:先求出原图的最小生成树,然后枚举删掉最小生成树的边,重做kruskal,看新的值和原值是否一样,一样的话最小生成树不唯一. ...

  2. POJ2155:Matrix(二维树状数组,经典)

    Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the ...

  3. 搜索树SVN的树的时候遇到的乱码问题

    public void listDirectoryNode(SVNRepository repository, String dirUrl, FileNode node) { String curre ...

  4. NPOI 创建Excel,数据读取与写入

    <1> using System; using System.Collections.Generic; using System.Linq; using System.Web; using ...

  5. 解决Android Device Chooser 找不到设备问题

    第一种情况: 已经启动了官方的模拟器也进入了Android手机界面,可是在Android Device Chooser 看不到设备,怎么办? 例如以下图所看到的,使用Reset adb 或者在adb所 ...

  6. Windows phone 8 学习笔记(5) 图块与通知

    原文:Windows phone 8 学习笔记(5) 图块与通知 基于metro风格的Windows phone 8 应用提到了图块的概念,它就是指启动菜单中的快速启动图标.一般一个应用必须有一个默认 ...

  7. 【cocos2d-x制作别踩白块儿】第一期:游戏介绍

    这一系类文章.我们将来分析时下最火的一款游戏 -- 别踩白块儿. 无图无真相,先上图 这就是我们终于要完毕项目的效果图. 游戏刚開始的最以下有一栏为黄色,紧接着上面每一行都是有一个黑色块,其余为白色块 ...

  8. [Unity3D]Unity3D游戏开发之飞机大战项目解说

    大家好,我是秦元培,欢迎大家继续关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei. 首先感谢大家对我博客的关注,今天我想和大家分享的是一个飞机大战的项目.这是一个比較综合的 ...

  9. 使用装饰器模式动态设置Drawable的ColorFilter

    使用装饰器模式动态设置Drawable的ColorFilter 欢迎各位关注我的新浪微博:微博 转载请标明出处(kifile的博客) 非常多时候我们都希望Android控件点击的时候,有按下效果,选中 ...

  10. 二十7天 春雨滋润着无形 —Spring依赖注入

    6月11日,明确."夏条绿已密,朱萼缀明鲜.炎炎日正午,灼灼火俱燃." IT人习惯把详细的事物加工成的形状一致的类.正是这种一致,加上合适的规范.才干彰显对象筋道的牙感和bean清 ...