Skip to content
12 changes: 12 additions & 0 deletions clients/src/main/java/org/apache/kafka/common/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,18 @@ public static void closeAll(Closeable... closeables) throws IOException {
throw exception;
}

public static void swallow(
Logger log,
String what,
Runnable runnable
) {
try {
runnable.run();
} catch (Throwable e) {
log.warn("{} error", what, e);
}
}

/**
* An {@link AutoCloseable} interface without a throws clause in the signature
*
Expand Down
45 changes: 16 additions & 29 deletions core/src/main/scala/kafka/server/BrokerServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,18 @@ import java.util
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.locks.ReentrantLock
import java.util.concurrent.{CompletableFuture, ExecutionException, TimeUnit, TimeoutException}

import kafka.cluster.Broker.ServerInfo
import kafka.coordinator.group.{GroupCoordinator, GroupCoordinatorAdapter}
import kafka.coordinator.transaction.{ProducerIdManager, TransactionCoordinator}
import kafka.log.LogManager
import kafka.network.{DataPlaneAcceptor, SocketServer}
import kafka.raft.RaftManager
import kafka.security.CredentialProvider
import kafka.server.KafkaRaftServer.ControllerRole
import kafka.server.metadata.BrokerServerMetrics
import kafka.server.metadata.{BrokerMetadataListener, BrokerMetadataPublisher, BrokerMetadataSnapshotter, ClientQuotaMetadataManager, KRaftMetadataCache, SnapshotWriterBuilder}
import kafka.utils.{CoreUtils, KafkaScheduler}
import org.apache.kafka.common.feature.SupportedVersionRange
import org.apache.kafka.common.message.ApiMessageType.ListenerType
import org.apache.kafka.common.message.BrokerRegistrationRequestData.{Listener, ListenerCollection}
import org.apache.kafka.common.metrics.Metrics
import org.apache.kafka.common.network.ListenerName
import org.apache.kafka.common.security.auth.SecurityProtocol
import org.apache.kafka.common.security.scram.internals.ScramMechanism
Expand All @@ -46,11 +42,9 @@ import org.apache.kafka.common.utils.{AppInfoParser, LogContext, Time, Utils}
import org.apache.kafka.common.{ClusterResource, Endpoint}
import org.apache.kafka.metadata.authorizer.ClusterMetadataAuthorizer
import org.apache.kafka.metadata.{BrokerState, VersionRange}
import org.apache.kafka.raft.RaftConfig.AddressSpec
import org.apache.kafka.raft.{RaftClient, RaftConfig}
import org.apache.kafka.server.authorizer.Authorizer
import org.apache.kafka.server.common.ApiMessageAndVersion
import org.apache.kafka.server.fault.FaultHandler
import org.apache.kafka.server.metrics.KafkaYammerMetrics
import org.apache.kafka.snapshot.SnapshotWriter

Expand All @@ -72,19 +66,14 @@ class BrokerSnapshotWriterBuilder(raftClient: RaftClient[ApiMessageAndVersion])
* A Kafka broker that runs in KRaft (Kafka Raft) mode.
*/
class BrokerServer(
val config: KafkaConfig,
val metaProps: MetaProperties,
val raftManager: RaftManager[ApiMessageAndVersion],
val time: Time,
val metrics: Metrics,
val brokerMetrics: BrokerServerMetrics,
val threadNamePrefix: Option[String],
val jointServer: JointServer,
val initialOfflineDirs: Seq[String],
val controllerQuorumVotersFuture: CompletableFuture[util.Map[Integer, AddressSpec]],
val fatalFaultHandler: FaultHandler,
val metadataLoadingFaultHandler: FaultHandler,
val metadataPublishingFaultHandler: FaultHandler
) extends KafkaBroker {
val threadNamePrefix = jointServer.threadNamePrefix
val config = jointServer.config
val time = jointServer.time
val metrics = jointServer.metrics
val raftManager = jointServer.raftManager

override def brokerState: BrokerState = Option(lifecycleManager).
flatMap(m => Some(m.state)).getOrElse(BrokerState.NOT_RUNNING)
Expand Down Expand Up @@ -144,7 +133,7 @@ class BrokerServer(

@volatile var brokerTopicStats: BrokerTopicStats = _

val clusterId: String = metaProps.clusterId
val clusterId: String = jointServer.metaProps.clusterId

var metadataSnapshotter: Option[BrokerMetadataSnapshotter] = None

Expand Down Expand Up @@ -180,6 +169,8 @@ class BrokerServer(
override def startup(): Unit = {
if (!maybeChangeStatus(SHUTDOWN, STARTING)) return
try {
jointServer.startForBroker()

info("Starting broker")

config.dynamicConfig.initialize(zkClientOpt = None)
Expand Down Expand Up @@ -211,7 +202,7 @@ class BrokerServer(
tokenCache = new DelegationTokenCache(ScramMechanism.mechanismNames)
credentialProvider = new CredentialProvider(ScramMechanism.mechanismNames, tokenCache)

val controllerNodes = RaftConfig.voterConnectionsToNodes(controllerQuorumVotersFuture.get()).asScala
val controllerNodes = RaftConfig.voterConnectionsToNodes(jointServer.controllerQuorumVotersFuture.get()).asScala
val controllerNodeProvider = RaftControllerNodeProvider(raftManager, config, controllerNodes)

clientToControllerChannelManager = BrokerToControllerChannelManager(
Expand Down Expand Up @@ -320,8 +311,8 @@ class BrokerServer(
threadNamePrefix,
config.metadataSnapshotMaxNewRecordBytes,
metadataSnapshotter,
brokerMetrics,
metadataLoadingFaultHandler)
jointServer.brokerMetrics,
jointServer.metadataLoaderFaultHandler)

val networkListeners = new ListenerCollection()
config.effectiveAdvertisedListeners.foreach { ep =>
Expand Down Expand Up @@ -349,7 +340,7 @@ class BrokerServer(
lifecycleManager.start(
() => metadataListener.highestMetadataOffset,
brokerLifecycleChannelManager,
metaProps.clusterId,
jointServer.metaProps.clusterId,
networkListeners,
featuresRemapped
)
Expand Down Expand Up @@ -439,8 +430,8 @@ class BrokerServer(
clientQuotaMetadataManager,
dynamicConfigHandlers.toMap,
authorizer,
fatalFaultHandler,
metadataPublishingFaultHandler)
jointServer.initialBrokerMetadataLoadFaultHandler,
jointServer.metadataPublishingFaultHandler)

// Tell the metadata listener to start publishing its output, and wait for the first
// publish operation to complete. This first operation will initialize logManager,
Expand Down Expand Up @@ -567,17 +558,13 @@ class BrokerServer(

if (socketServer != null)
CoreUtils.swallow(socketServer.shutdown(), this)
if (metrics != null)
CoreUtils.swallow(metrics.close(), this)
if (brokerTopicStats != null)
CoreUtils.swallow(brokerTopicStats.close(), this)

// Clear all reconfigurable instances stored in DynamicBrokerConfig
config.dynamicConfig.clear()

isShuttingDown.set(false)

CoreUtils.swallow(lifecycleManager.close(), this)
jointServer.stopForBroker()

CoreUtils.swallow(AppInfoParser.unregisterAppInfo(MetricsPrefix, config.nodeId.toString, metrics), this)
info("shut down completed")
Expand Down
60 changes: 31 additions & 29 deletions core/src/main/scala/kafka/server/ControllerServer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,31 @@

package kafka.server

import java.util
import java.util.OptionalLong
import java.util.concurrent.locks.ReentrantLock
import java.util.concurrent.{CompletableFuture, TimeUnit}
import kafka.cluster.Broker.ServerInfo
import kafka.metrics.{KafkaMetricsGroup, LinuxIoMetricsCollector}
import kafka.network.{DataPlaneAcceptor, SocketServer}
import kafka.raft.RaftManager
import kafka.raft.KafkaRaftManager
import kafka.security.CredentialProvider
import kafka.server.KafkaConfig.{AlterConfigPolicyClassNameProp, CreateTopicPolicyClassNameProp}
import kafka.server.KafkaRaftServer.BrokerRole
import kafka.server.QuotaFactory.QuotaManagers
import kafka.utils.{CoreUtils, Logging}
import org.apache.kafka.clients.ApiVersions
import org.apache.kafka.common.message.ApiMessageType.ListenerType
import org.apache.kafka.common.metrics.Metrics
import org.apache.kafka.common.security.scram.internals.ScramMechanism
import org.apache.kafka.common.security.token.delegation.internals.DelegationTokenCache
import org.apache.kafka.common.utils.{LogContext, Time}
import org.apache.kafka.common.utils.LogContext
import org.apache.kafka.common.{ClusterResource, Endpoint}
import org.apache.kafka.controller.{Controller, ControllerMetrics, QuorumController, QuorumFeatures}
import org.apache.kafka.controller.{Controller, QuorumController, QuorumFeatures}
import org.apache.kafka.metadata.KafkaConfigSchema
import org.apache.kafka.raft.RaftConfig
import org.apache.kafka.raft.RaftConfig.AddressSpec
import org.apache.kafka.server.authorizer.Authorizer
import org.apache.kafka.server.common.ApiMessageAndVersion
import org.apache.kafka.common.config.ConfigException
import org.apache.kafka.metadata.authorizer.ClusterMetadataAuthorizer
import org.apache.kafka.metadata.bootstrap.BootstrapMetadata
import org.apache.kafka.server.fault.FaultHandler
import org.apache.kafka.server.metrics.KafkaYammerMetrics
import org.apache.kafka.server.policy.{AlterConfigPolicy, CreateTopicPolicy}

Expand All @@ -57,22 +52,19 @@ import scala.compat.java8.OptionConverters._
* A Kafka controller that runs in KRaft (Kafka Raft) mode.
*/
class ControllerServer(
val metaProperties: MetaProperties,
val config: KafkaConfig,
val raftManager: RaftManager[ApiMessageAndVersion],
val time: Time,
val metrics: Metrics,
val controllerMetrics: ControllerMetrics,
val threadNamePrefix: Option[String],
val controllerQuorumVotersFuture: CompletableFuture[util.Map[Integer, AddressSpec]],
val jointServer: JointServer,
val configSchema: KafkaConfigSchema,
val raftApiVersions: ApiVersions,
val bootstrapMetadata: BootstrapMetadata,
val metadataFaultHandler: FaultHandler,
val fatalFaultHandler: FaultHandler,
) extends Logging with KafkaMetricsGroup {

import kafka.server.Server._

val config = jointServer.config
val time = jointServer.time
val metrics = jointServer.metrics
val threadNamePrefix = jointServer.threadNamePrefix.getOrElse("")
def raftManager: KafkaRaftManager[ApiMessageAndVersion] = jointServer.raftManager

config.dynamicConfig.initialize(zkClientOpt = None)

val lock = new ReentrantLock()
Expand Down Expand Up @@ -111,7 +103,7 @@ class ControllerServer(
new DynamicMetricReporterState(config.nodeId, config, metrics, clusterId)
}

def clusterId: String = metaProperties.clusterId
def clusterId: String = jointServer.metaProps.clusterId

def startup(): Unit = {
if (!maybeChangeStatus(SHUTDOWN, STARTING)) return
Expand Down Expand Up @@ -171,15 +163,18 @@ class ControllerServer(
throw new ConfigException("No controller.listener.names defined for controller")
}

val threadNamePrefixAsString = threadNamePrefix.getOrElse("")
jointServer.startForController()

createTopicPolicy = Option(config.
getConfiguredInstance(CreateTopicPolicyClassNameProp, classOf[CreateTopicPolicy]))
alterConfigPolicy = Option(config.
getConfiguredInstance(AlterConfigPolicyClassNameProp, classOf[AlterConfigPolicy]))

val controllerNodes = RaftConfig.voterConnectionsToNodes(controllerQuorumVotersFuture.get())
val quorumFeatures = QuorumFeatures.create(config.nodeId, raftApiVersions, QuorumFeatures.defaultFeatureMap(), controllerNodes)
val controllerNodes = RaftConfig.voterConnectionsToNodes(jointServer.controllerQuorumVotersFuture.get())
val quorumFeatures = QuorumFeatures.create(config.nodeId,
jointServer.raftManager.apiVersions,
QuorumFeatures.defaultFeatureMap(),
controllerNodes)

val controllerBuilder = {
val leaderImbalanceCheckIntervalNs = if (config.autoLeaderRebalanceEnable) {
Expand All @@ -190,9 +185,9 @@ class ControllerServer(

val maxIdleIntervalNs = config.metadataMaxIdleIntervalNs.fold(OptionalLong.empty)(OptionalLong.of)

new QuorumController.Builder(config.nodeId, metaProperties.clusterId).
new QuorumController.Builder(config.nodeId, jointServer.metaProps.clusterId).
setTime(time).
setThreadNamePrefix(threadNamePrefixAsString).
setThreadNamePrefix(threadNamePrefix).
setConfigSchema(configSchema).
setRaftClient(raftManager.client).
setQuorumFeatures(quorumFeatures).
Expand All @@ -204,13 +199,13 @@ class ControllerServer(
setSnapshotMaxIntervalMs(config.metadataSnapshotMaxIntervalMs).
setLeaderImbalanceCheckIntervalNs(leaderImbalanceCheckIntervalNs).
setMaxIdleIntervalNs(maxIdleIntervalNs).
setMetrics(controllerMetrics).
setMetrics(jointServer.controllerMetrics).
setCreateTopicPolicy(createTopicPolicy.asJava).
setAlterConfigPolicy(alterConfigPolicy.asJava).
setConfigurationValidator(new ControllerConfigurationValidator()).
setStaticConfig(config.originals).
setBootstrapMetadata(bootstrapMetadata).
setFatalFaultHandler(fatalFaultHandler)
setFatalFaultHandler(jointServer.quorumControllerFaultHandler)
}
authorizer match {
case Some(a: ClusterMetadataAuthorizer) => controllerBuilder.setAuthorizer(a)
Expand All @@ -223,15 +218,18 @@ class ControllerServer(
doRemoteKraftSetup()
}

quotaManagers = QuotaFactory.instantiate(config, metrics, time, threadNamePrefix.getOrElse(""))
quotaManagers = QuotaFactory.instantiate(config,
metrics,
time,
threadNamePrefix)
controllerApis = new ControllerApis(socketServer.dataPlaneRequestChannel,
authorizer,
quotaManagers,
time,
controller,
raftManager,
config,
metaProperties,
jointServer.metaProps,
controllerNodes.asScala.toSeq,
apiVersionManager)
controllerApisHandlerPool = new KafkaRequestHandlerPool(config.nodeId,
Expand Down Expand Up @@ -265,6 +263,9 @@ class ControllerServer(
if (!maybeChangeStatus(STARTED, SHUTTING_DOWN)) return
try {
info("shutting down")
// Ensure that we're not the Raft leader prior to shutting down our socket server, for a
// smoother transition.
jointServer.ensureNotRaftLeader()
if (socketServer != null)
CoreUtils.swallow(socketServer.stopProcessingRequests(), this)
if (controller != null)
Expand All @@ -283,6 +284,7 @@ class ControllerServer(
createTopicPolicy.foreach(policy => CoreUtils.swallow(policy.close(), this))
alterConfigPolicy.foreach(policy => CoreUtils.swallow(policy.close(), this))
socketServerFirstBoundPortFuture.completeExceptionally(new RuntimeException("shutting down"))
jointServer.stopForController()
} catch {
case e: Throwable =>
fatal("Fatal error during controller shutdown.", e)
Expand Down
Loading