java基于线程停止服务,“致命药丸”在kafka 源码服务端请求处理中的使用

致命药丸:一个可识别的对象,置于队列中意味着当你得到他的时候,停止一切服务,在先进先出队列中致命药丸可以保证之前的请求都被处理完毕,生产者不应该在提交致命药丸之后提交任何工作。
kafka服务端请求处理的大体流程:Acceptor线程接受客户端的请求并建立socket channel,然后将channel分发给Processor线程,Processor 线程消费阻塞队列中的socket channel并与之建立连接接受request,再将request放到request channel当中,之后KafkaRequestHandler将消费request channel中的request并对其进行下一步的处理。
其中包含一个典型的生产者消费者模型(其实是两个),Processor为生产者,KafkaRequestHandler为消费者,那么如何停止这个基于线程的服务呢?

KafkaRequestHandler的run方法,处理方法见注释

  def run() {
    while (!stopped) {
      val startSelectTime = time.nanoseconds

      val req = requestChannel.receiveRequest(300)
      val endTime = time.nanoseconds
      val idleTime = endTime - startSelectTime
      aggregateIdleMeter.mark(idleTime / totalHandlerThreads.get)

      req match {
      	//处理致命药丸,退出该线程
        case RequestChannel.ShutdownRequest =>
          debug(s"Kafka request handler $id on broker $brokerId received shut down command")
          shutdownComplete.countDown()
          return

        case request: RequestChannel.Request =>
          try {
            request.requestDequeueTimeNanos = endTime
            trace(s"Kafka request handler $id on broker $brokerId handling request $request")
            apis.handle(request)
          } catch {
            case e: FatalExitError =>
              shutdownComplete.countDown()
              Exit.exit(e.statusCode)
            case e: Throwable => error("Exception when handling request", e)
          } finally {
            request.releaseBuffer()
          }

        case null => // continue
      }
    }
    shutdownComplete.countDown()
  }

RequestChannel中用来停止服务的方法,处理方法见注释

  //发送致命药丸
  def sendShutdownRequest(): Unit = requestQueue.put(ShutdownRequest)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值