这里用kakfa 3.0版本做源码演示
首先看一下kafka-server-start.sh
中的最后一行
exec $base_dir/kafka-run-class.sh $EXTRA_ARGS kafka.Kafka "$@"
我们知道了执行的是core/src/main/scala/kafka/Kafka.scala
下的main方法
def main(args: Array[String]): Unit = {
try {
//获得配置文件中的参数
val serverProps = getPropsFromArgs(args)
//build server,非常重要,因为你要确定到底执行的是哪种server
val server = buildServer(serverProps)
try {
if (!OperatingSystem.IS_WINDOWS && !Java.isIbmJdk)
new LoggingSignalHandler().register()
} catch {
case e: ReflectiveOperationException =>
warn("Failed to register optional signal handler that logs a message when the process is terminated " +
s"by a signal. Reason for registration failure is: $e", e)
}
// attach shutdown handler to catch terminating signals as well as normal termination
//附加关闭处理程序以捕获终止信号以及正常终止
Exit.addShutdownHook("kafka-shutdown-hook", {
try server.shutdown()
catch {
case _: Throwable =>
fatal("Halting Kafka.")
// Calling exit() can lead to deadlock as exit() can be called multiple times. Force exit.
Exit.halt(1)
}
})
//执行server的 startup
try server.startup()
catch {
case _: Throwable =>
// KafkaServer.startup() calls shutdown() in case of exceptions, so we invoke `exit` to set the status code
//KafkaServer.startup() 调用 shutdown() 以防异常,所以我们调用 `exit` 来设置状态码
fatal("Exiting Kafka.")
Exit.exit(1)
}
server.awaitShutdown()
}
catch {
case e: Throwable =>
fatal("Exiting Kafka due to fatal exception", e)
Exit.exit(1)
}
Exit.exit(0)
}
//生成server
private def buildServer(props: Properties): Server = {
val config = KafkaConfig.fromProps(props, false)
if (config.requiresZookeeper) { //是否在properties中有process.roles=broker,controller配置
//没有则构造KafkaServer
new KafkaServer(
config,
Time.SYSTEM,
threadNamePrefix = None,
enableForwarding = false
)
} else {
//存在则构造KafkaRaftServer
new KafkaRaftServer(
config,
Time.SYSTEM,
threadNamePrefix = None
)
}
}
其中config.requiresZookeeper
就是判断/config/kraft/server.properties
中是否有下面的配置
参考Kafka2.8无Zookeeper模式下集群部署
# The role of this server. Setting this puts us in KRaft mode
process.roles=broker,controller
# The node id associated with this instance's roles
node.id=1
# The connect string for the controller quorum
controller.quorum.voters=1@master:9093,2@slave1:9093,3@slave2:9093
class KafkaRaftServer(
config: KafkaConfig,
time: Time,
threadNamePrefix: Option[String]
) extends Server with Logging {
KafkaMetricsReporter.startReporters(VerifiableProperties(config.originals))
KafkaYammerMetrics.INSTANCE.configure(config.originals)
private val (metaProps, offlineDirs) = KafkaRaftServer.initializeLogDirs(config)
private val metrics = Server.initializeMetrics(
config,
time,
metaProps.clusterId
)
private val controllerQuorumVotersFuture = CompletableFuture.completedFuture(
RaftConfig.parseVoterConnections(config.quorumVoters))
private val raftManager = new KafkaRaftManager[ApiMessageAndVersion](
metaProps,
config,
new MetadataRecordSerde,
KafkaRaftServer.MetadataPartition,
KafkaRaftServer.MetadataTopicId,
time,
metrics,
threadNamePrefix,
controllerQuorumVotersFuture
)
//这里需要注意,new BrokerServer
private val broker: Option[BrokerServer] = if (config.processRoles.contains(BrokerRole)) {
Some(new BrokerServer(
config,
metaProps,
raftManager,
time,
metrics,
threadNamePrefix,
offlineDirs,
controllerQuorumVotersFuture,
Server.SUPPORTED_FEATURES
))
} else {
None
}
private val controller: Option[ControllerServer] = if (config.processRoles.contains(ControllerRole)) {
Some(new ControllerServer(
metaProps,
config,
raftManager,
time,
metrics,
threadNamePrefix,
controllerQuorumVotersFuture
))
} else {
None
}
//这个是实际的执行,上面的server.startup就是执行的这个
override def startup(): Unit = {
Mx4jLoader.maybeLoad()
//初始化raftManager
raftManager.startup()
//执行ControllerServer,这里面有raft的管理,这里不做细致的写
controller.foreach(_.startup())
//broker实际上是BrokerServer.startup,可以看一下 private val broker这个方法
broker.foreach(_.startup())
AppInfoParser.registerAppInfo(Server.MetricsPrefix, config.brokerId.toString, metrics, time.milliseconds())
info(KafkaBroker.STARTED_MESSAGE)
}
//关机
override def shutdown(): Unit = {
broker.foreach(_.shutdown())
raftManager.shutdown()
controller.foreach(_.shutdown())
CoreUtils.swallow(AppInfoParser.unregisterAppInfo(Server.MetricsPrefix, config.brokerId.toString, metrics), this)
}
//等待关机
override def awaitShutdown(): Unit = {
broker.foreach(_.awaitShutdown())
controller.foreach(_.awaitShutdown())
}
}
之后就执行了BrokerServer.scala
中的startup
方法