消费者离开消费者组是向GroupCoordinator发送LeaveGroupRequest。
def handleLeaveGroup(groupId: String, consumerId: String, responseCallback: Short => Unit) {
if (!isActive.get) {
responseCallback(Errors.GROUP_COORDINATOR_NOT_AVAILABLE.code)
} else if (!isCoordinatorForGroup(groupId)) {
responseCallback(Errors.NOT_COORDINATOR_FOR_GROUP.code)
} else if (isCoordinatorLoadingInProgress(groupId)) {
responseCallback(Errors.GROUP_LOAD_IN_PROGRESS.code)
} else {
val group = groupManager.getGroup(groupId)
if (group == null) {
// if the group is marked as dead, it means some other thread has just removed the group
// from the coordinator metadata; this is likely that the group has migrated to some other
// coordinator OR the group is in a transient unstable phase. Let the consumer to retry
// joining without specified consumer id,
responseCallback(Errors.UNKNOWN_MEMBER_ID.code)
} else {
group synchronized {
if (group.is(Dead)) {
//如果遇到Group处于Dead、未知的memberID,就调用回调函数返回错误码
responseCallback(Errors.UNKNOWN_MEMBER_ID.code)
} else if (!group.has(consumerId)) {
responseCallback(Errors.UNKNOWN_MEMBER_ID.code)
} else {
val member = group.get(consumerId)
removeHeartbeatForLeavingMember(group, member)
// 移除memberMetadata对象并完成状态转化
onMemberFailure(group, member)
responseCallback(Errors.NONE.code)
}
}
}
}
}
private def onMemberFailure(group: GroupMetadata, member: MemberMetadata) {
trace("Member %s in group %s has failed".format(member.memberId, group.groupId))
group.remove(member.memberId)
group.currentState match {
case Dead =>
case Stable | AwaitingSync => maybePrepareRebalance(group)
case PreparingRebalance => joinPurgatory.checkAndComplete(GroupKey(group.groupId))
}
}