消费者与GroupCoordinator进行交互之前,首先会发送GroupCoordinatorRequest到负载较小的broker,目的是查询管理其所在ConsumerGroup对应的Coordinator的网络位置。之后,消费者会连接到GroupCoordinator,发送剩余的JoinGroupRequest和SyncGroupRequest。
handleGroupCoordinatorRequest负责GroupCoordinatorRequest的相关处理。
def handleGroupCoordinatorRequest(request: RequestChannel.Request) {
val groupCoordinatorRequest = request.body.asInstanceOf[GroupCoordinatorRequest]
val responseHeader = new ResponseHeader(request.header.correlationId)
if (!authorize(request.session, Describe, new Resource(Group, groupCoordinatorRequest.groupId))) {
val responseBody = new GroupCoordinatorResponse(Errors.GROUP_AUTHORIZATION_FAILED.code, Node.noNode)
requestChannel.sendResponse(new RequestChannel.Response(request, new ResponseSend(request.connectionId, responseHeader, responseBody)))
} else {
// 通过GroupID得到对应offsets Topic分区的id
val partition = coordinator.partitionFor(groupCoordinatorRequest.groupId)
// get metadata (and create the topic if necessary)
// 从Metadata中获取offset topic相关信息,如果__CONSUMER_OFFSETS还没有创建,这会在这里创建
val offsetsTopicMetadata = getOrCreateGroupMetadataTopic(request.securityProtocol)
val responseBody = if (offsetsTopicMetadata.error != Errors.NONE) {
new GroupCoordinatorResponse(Errors.GROUP_COORDINATOR_NOT_AVAILABLE.code, Node.noNode)
} else {
// 通过上述partition的ID获取它leader所在的node
val coordinatorEndpoint = offsetsTopicMetadata.partitionMetadata().asScala
.find(_.partition == partition)
.map(_.leader())
//创建GroupCoordinatorResponse
coordinatorEndpoint match {
case Some(endpoint) if !endpoint.isEmpty =>
new GroupCoordinatorResponse(Errors.NONE.code, endpoint)
case _ =>
new GroupCoordinatorResponse(Errors.GROUP_COORDINATOR_NOT_AVAILABLE.code, Node.noNode)
}
}
trace("Sending consumer metadata %s for correlation id %d to client %s."
.format(responseBody, request.header.correlationId, request.header.clientId))
// 把响应放在RequestChannels中等待发送
requestChannel.sendResponse(new RequestChannel.Response(request, new ResponseSend(request.connectionId, responseHeader, responseBody)))
}
}