kafka 服务端-网络-processor如何接收和处理请求

Processor.run()
  override def run() {
    startupComplete()
    while (isRunning) {
      try {
        // setup any new connections that have been queued up
        //读取每个SocketChannel,把每个SocketChannel
        //都往Selector上面注册OP_READ事件。
        configureNewConnections()

        // register any new responses for writing
        //TODO 看起来像是处理响应的。绑定 OP_WRITE
        processNewResponses()

        //我们大胆的猜测,根据我们之前的了解
        //读取和发送请求的代码应该都是在这个方法里面完成的。
        //TODO 再次进去
        poll()
        //TODO 用来处理接收到当的请求
        processCompletedReceives()
        //todo 处理我们已经发送出去的响应
        processCompletedSends()
        processDisconnected()

-> poll() -> selector.poll(300)
-> pollSelectionKeys(){
if (channel.ready() && key.isReadable() && !hasStagedReceive(channel)) {
        NetworkReceive networkReceive;

        //接受服务端发送回来的响应(请求)
        //networkReceive 代表的就是一个服务端发送
        //回来的响应

        //里面不断的读取数据,读取数据的代码我们之前就已经分析过
        //里面还涉及到粘包和拆包的一些问题。
        while ((networkReceive = channel.read()) != null)
            addToStagedReceives(channel, networkReceive);
    }
}

//TODO 对stagedReceives里面的数据要进行处理
addToCompletedReceives();
    private void addToCompletedReceives() {
        if (!this.stagedReceives.isEmpty()) {
            Iterator<Map.Entry<KafkaChannel, Deque<NetworkReceive>>> iter = this.stagedReceives.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<KafkaChannel, Deque<NetworkReceive>> entry = iter.next();
                KafkaChannel channel = entry.getKey();
                if (!channel.isMute()) {
                    //获取到每个连接对应的 请求队列
                    Deque<NetworkReceive> deque = entry.getValue();
                    //获取到响应

                    //对于我们服务端来说,这儿接收到的是请求
                    NetworkReceive networkReceive = deque.poll();
                    //把响应存入到completedReceives 数据结构里面
                    this.completedReceives.add(networkReceive);
                    this.sensors.recordBytesReceived(channel.id(), networkReceive.payload().limit());
                    if (deque.isEmpty())
                        iter.remove();
                }
            }
        }
    }

处理接收到当的请求  request请求放入队列 RequestQueue
SocketServer.Processor.run()  processCompletedReceives()
  private def processCompletedReceives() {
    //遍历每一个请求 Scala,函数式编程
    selector.completedReceives.asScala.foreach { receive =>
      try {
        val channel = selector.channel(receive.source)
        val session = RequestChannel.Session(new KafkaPrincipal(KafkaPrincipal.USER_TYPE, channel.principal.getName),
          channel.socketAddress)
        //对于获取到的请求按照协议进行解析,解析出来就是一个一个Request
        val req = RequestChannel.Request(processor = id, connectionId = receive.source, session = session, buffer = receive.payload, startTimeMs = time.milliseconds, securityProtocol = protocol)

        //TODO 把request请求放入队列
        requestChannel.sendRequest(req)
        //TODO 取消OP_READ事件
        selector.mute(receive.source)
      } catch {
        case e @ (_: InvalidRequestException | _: SchemaException) =>
          // note that even though we got an exception, we can assume that receive.source is valid. Issues with constructing a valid receive object were handled earlier
          error(s"Closing socket for ${receive.source} because of error", e)
          close(selector, receive.source)
      }
    }
  }

处理我们已经发送出去的响应
SocketServer.Processor.run() processCompletedSends()
  private def processCompletedSends() {
    selector.completedSends.asScala.foreach { send =>
      //移除数据结构里面的一些数据信息
      val resp = inflightResponses.remove(send.destination).getOrElse {
        throw new IllegalStateException(s"Send for ${send.destination} completed, but not in `inflightResponses`")
      }
      resp.request.updateRequestMetrics()
      selector.unmute(send.destination)
    }
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值