Kafka服务端

本文详细介绍了Kafka服务端的网络架构,包括Acceptor线程负责接收新连接,Processor线程处理单个连接的请求,RequestChannel类管理请求队列,KafkaRequestHandlerPool和KafkaRequestHandler类用于处理消息。文章深入剖析了Kafka网络初始化、Acceptor、Processor以及RequestHandler的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kafka服务端源码之网络

网络传输关键类及流程图:

在这里插入图片描述

上图可以看出有如下几个关键线程和关键类:

  • Acceptor线程:接受并配置新连接的线程。 每个端点中有一个。
  • **Processor线程:**处理来自单个连接的所有请求的线程。 其中有N个并行运行,每个都有自己的选择器
  • **RequestChannel类:**处理请求,并将请求缓存在该类的requestQueue中,发送响应等功能
  • KafkaRequestHandlerPool类: 线程处理池,有多个handler处理消息
  • **KafkaRequestHandler类:**真正处理消息的类

Kafka网络之初始化

​ kafka启动过程主要是各个线程的准备工作,包括Accecptor线程启动成功并监听所有连接该服务器的生产者。

​ 各个Processor启动轮询SocketChannel的消息;

​ RequestHandlerPool初始化,并开启各个RequestHanler轮询RequestChannel中的RequestQueue中是否有消息可以消费

​ 启动Acceptor和Processor的入口类为SocketServer,启动的方法是startup():这里粘贴主要代码

 /**
   * 启动套接字服务器。 启动所有侦听器的接受器。
   * 如果startupProcessors为true,则启动处理器。 如果不是,则仅在调用kafka.network.SocketServer.startDataPlaneProcessors()
   * 或kafka.network.SocketServer.startControlPlaneProcessor()时启动处理器。
   * 处理器的延迟启动用于延迟对客户端连接的处理,直到服务器完全初始化为止,
   * 例如,以确保在执行身份验证之前已加载所有凭据。
   * 接收器始终在启动过程中启动,因此即使使用临时端口,此方法完成后,绑定端口也将是已知的。
   * 当处理器启动并调用org.apache.kafka.common.network.Selector.poll时,将处理此服务器上的传入连接。
   */
 def startup(startupProcessors: Boolean = true): Unit = {
   
    this.synchronized {
   
      //连接的一些配额信息
      connectionQuotas = new ConnectionQuotas(config, time)
      /**创建控制Acceptor以及Processor
      -control-plane : 
		      - 处理来自控制器的请求。 这是可选的,可以通过指定“ control.plane.listener.name”进行配置。 如果未配置,则控制器请求由数据平面处理。 
	       - 线程模型是处理新连接的1个Acceptor线程。Acceptor具有1个处理器线程,该线程具有自己的选择器并从套接字读取请求。 1处理程序线程,用于处理请求并向处理器线程返回响应以进行写入。 
      */
      createControlPlaneAcceptorAndProcessor(config.controlPlaneListener)
      /**
       -data-plane: 
       		 - 处理来自客户端和集群中其他代理的请求。 
	         - 线程模型是每个侦听器1个Acceptor线程,用于处理新连接。 通过在KafkaConfig中为“侦听器”指定多个“,”分隔的端点,可以配置多个数据平面。 接受者有N个处理器线程,每个线程都有自己的选择器并从套接字读取请求。M个处理程序线程处理请求并向处理器线程返回响应以进行写入。
       */
      //Acceptor会在该方法中启动
      createDataPlaneAcceptorsAndProcessors(config.numNetworkThreads, config.dataPlaneListeners)
      if (startupProcessors) {
   
        //启动Processor
        startControlPlaneProcessor(Map.empty)
        startDataPlaneProcessors(Map.empty)
      }
    }
  }


//createDataPlaneAcceptorsAndProcessors(config.numNetworkThreads,config.dataPlaneListeners)

private def createDataPlaneAcceptorsAndProcessors(dataProcessorsPerListener: Int,
                                                    endpoints: Seq[EndPoint]): Unit = synchronized {
   
    endpoints.foreach {
    endpoint =>
      connectionQuotas.addListener(config, endpoint.listenerName)
      //创建Acceptor
      val dataPlaneAcceptor = createAcceptor(endpoint, DataPlaneMetricPrefix)\
      //向Acceptor中添加Processor
      addDataPlaneProcessors(dataPlaneAcceptor, endpoint, dataProcessorsPerListener)
      //启动Acceptor线程
      KafkaThread.nonDaemon(s"data-plane-kafka-socket-acceptor-${endpoint.listenerName}-${endpoint.securityProtocol}-${endpoint.port}", dataPlaneAcceptor).start()
      dataPlaneAcceptor.awaitStartup()
      dataPlaneAcceptors.put(endpoint, dataPlaneAcceptor)
      info(s"Created data-plane acceptor and processors for endpoint : $endpoint")
    }
  }

//addDataPlaneProcessors
private def addDataPlaneProcessors(acceptor: Acceptor, endpoint: EndPoint, newProcessorsPerListener: Int): Unit = synchronized {
   
    val listenerName: ListenerName = endpoint.listenerName
    val securityProtocol: SecurityProtocol = endpoint.securityProtocol
    val listenerProcessors = new ArrayBuffer[Processor]()
    for (_ <- 0 until newProcessorsPerListener) {
   
      //创建Processor线程
      val processor
要配置Apache Kafka 服务器以在ARM架构上运行,特别是在使用Docker时,你可以按照以下步骤操作: 1. **设置基础配置**[^1]: - 配置`broker.id`为服务器的唯一标识(如 `broker.id=3`)。 - 设置`zookeeper.connect`,连接到ZooKeeper集群,这里使用的是IP地址和端口(如`zookeeper.connect=192.168.44.128:2181,192.168.44.129:2181,192.168.44.130:2181`)。 - 定义`advertised.listeners`,指定对外公开的监听端口(如`advertised.listeners=PLAINTEXT://192.168.44.130:9092`)。 - 指定日志目录(如`log.dirs=/data/kafka/kafka-logs`)。 2. **启动Kafka容器**[^2],如果使用Docker-Compose,可以创建一个新的`docker-compose.yml`文件,定义Kafka服务和依赖项,可能类似于这样: ```yaml version: '3' services: kafka: image: confluentinc/cp-kafka:latest environment: KAFKA_BROKER_ID: 3 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 volumes: - ./kafka-data:/var/lib/kafka/data ``` 确保替换`image`为所需的Kafka版本(如`confluentinc/cp-kafka:latest`),并使用本地主机名或实际IP替换`localhost`。 3. **启动服务**: - 使用`docker-compose up -d`命令启动Kafka服务(`-d`表示后台运行)。 4. **验证服务状态**: - 可以通过`netstat -tna | grep -e 9092 -e 2181`来检查Kafka和ZooKeeper的端口是否正在监听。 请注意,如果你使用的是新版本的Kafka(3.3及以上),可能会跳过ZooKeeper的部署,因为KRaft取代了部分功能。然而,在生产环境中,通常还是推荐保留ZooKeeper。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值