1
但是这里的sendRequest只是将它放到一个队列中,而不是通过TCP发送给其它线程处理
而这个队列里面的消息会由
KafkaRequestHandler进行处理,
到这里,就可以看到了handle的处理方式了
Kafka在启动的时候,会启动Processor线程负责监听消息端口,当有消息接收时,调用read函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
def
read(key
:
SelectionKey) {
... ...
if
(read <
0
) {
... ...
}
else
if
(receive.complete) {
val
req
=
RequestChannel.Request(processor
=
id, requestKey
=
key, buffer
=
receive.buffer, startTimeMs
=
time.milliseconds, remoteAddress
=
address)
//当消息接收完成后,调用sendRequest
requestChannel.sendRequest(req)
key.attach(
null
)
// explicitly reset interest ops to not READ, no need to wake up the selector just yet
key.interestOps(key.interestOps & (~SelectionKey.OP
_
READ))
}
else
{
... ...
wakeup()
}
}
|
1
2
3
|
def
sendRequest(request
:
RequestChannel.Request) {
requestQueue.put(request)
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
def
run() {
while
(
true
) {
try
{
... ...
//这里的receiveRequest()就是负责从前面的requestQueue队列中获取消息
req
=
requestChannel.receiveRequest(
300
)
... ...
//消息获取之后,就是处理消息了
apis.handle(req)
}
catch
{
case
e
:
Throwable
=
> error(
"Exception when handling request"
, e)
}
}
}
|
1
2
3
4
5
6
7
8
9
10
11
|
def
handle(request
:
RequestChannel.Request) {
... .,,
//从这里可以年到它会根据不同的requestId来选择不同的handle来处理,而这个requestId,它是从ByteBuffer中
//调用getShort()获取的第一个参数。查看producer生成Bytebuffer的定义,可以看到,写入的第一个参数就是
//requestId,因此前后就可以连接起来
request.requestId
match
{
case
RequestKeys.ProduceKey
=
> handleProducerOrOffsetCommitRequest(request)
.. ...
}
|