よるカフカサーバKafka.scala
主な機能のmain
方法が開始されます。KafkaServerStartable
クラスは読ん設定ファイル、起動方法/ストップサービスを提供しています。スタート/ストップサービスは、最終的な呼び出しである方法。KafkaServer
startup/shutdown
スタートプロセス
- ZKクライアントを起動します。
- 動的構成を開始します。
- スレッドプールをスケジュール起動します。
- ログを削除し、ログ、ログディスクブラシをクリーンアップ含め、ログマネージャのバックグラウンドスレッドを起動し、圧縮をログに記録します。
- NIOソケットサービスを開始します。
- シンクを初期化
Acceptor
、即ちNIOソケットを開始。 - 追加
num.network.threads
チャネル要求を受信しRequestChannel
、プロセッサ・キャッシュConcurrentHashMap
、鍵番号がインクリメントされ、プロセッサの値をProcessor
。 Acceptor
実行がCountDownLatch.await
開始する通知を待ちます。- キャッシュ
Acceptor
へのConcurrentHashMap
鍵は、あるEndPoint
値は、Acceptor
。
- シンクを初期化
- コピーマネージャを起動します。
- ZKに登録ブローカー。
- コントローラ。
- スタートアップグループのコーディネーター。
- トランザクション・コーディネーターを開始します。
- 初期化
KafkaApis
。 - プロセッサキャッシュの初期化スレッドプール。
- 開始
num.io.threads
要求処理スレッドをKafkaRequestHandler
。 - キューブロックから
ArrayBlockingQueue
呼び出し、取得要求をKafkaApis.handle
集中処理要求のための方法を、。
- 開始
- プロセッサスレッドを起動します。
- 最初の
CountDownLatch.countDown
通知は、目を覚ますAcceptor
のスレッドを。- 使用
NIO.select
ポーリング。 - イベントの準備ができて、その後、現在の受信可能な場合は
SocketChannel
、バッファキューの追加をConcurrentLinkedQueue
- 使用
- キューバッファから取り出し
SocketChannel
バインドするために、KafkaChannel
。 - キューの長さをブロックキャッシュ制限に受信した要求
ArrayBlockingQueue
- 最初の
要求処理の流れ
詳細なソースコード解析
アクセプタスレッド
def run() {
serverChannel.register(nioSelector, SelectionKey.OP_ACCEPT) // 注册接收事件
startupComplete() // 通知 Acceptor 线程
var currentProcessor = 0
while (isRunning) {
val ready = nioSelector.select(500) // 轮询事件
if (ready > 0) {
val keys = nioSelector.selectedKeys()
val iter = keys.iterator()
while (iter.hasNext && isRunning) {
val key = iter.next
iter.remove()
if (key.isAcceptable) { // 有可接受事件
val processor = synchronized {
currentProcessor = currentProcessor % processors.size
processors(currentProcessor) // 缓存 Processor
}
accept(key, processor) // 将 SocketChannel 缓存到队列
}
}
}
}
}
プロセッサのスレッド
override def run() {
startupComplete() // CountDownLatch.countDown 唤醒 Acceptor 线程。
while (isRunning) {
configureNewConnections() // 从缓存队列取出 SocketChannel,绑定到 KafkaChannel
processNewResponses() // 处理返回客户端的响应
poll() // Kafka.Selector 轮询读取/写入事件
processCompletedReceives() // 处理客户端的请求,放到阻塞队列
processCompletedSends() // 处理返回客户端响应后的回调
processDisconnected() // 断开连接后的处理
}
}
KafkaRequestHandlerスレッドブロッキングキュー
def run() {
while (!stopped) {
val startSelectTime = time.nanoseconds
// 从阻塞队列拉取请求
val req = requestChannel.receiveRequest(300)
req match {
case request: RequestChannel.Request =>
try {
apis.handle(request) // 调用`KafkaApis.handle`方法,进行集中处理请求。
}
}
}
}
KSelector
クライアントの参照元の分析。