spark 源码学习之打印线程堆栈

spark页面中有个打印executor的堆栈的,很好用,最近自己的web项目也想把堆栈用servlet的方式去展现出来,于是跟了下spark源码

SparkContext中:

  /**
   * Called by the web UI to obtain executor thread dumps.  This method may be expensive.
   * Logs an error and returns None if we failed to obtain a thread dump, which could occur due
   * to an executor being dead or unresponsive or due to network issues while sending the thread
   * dump message back to the driver.
   */
  private[spark] def getExecutorThreadDump(executorId: String): Option[Array[ThreadStackTrace]] = {
    try {
      if (executorId == SparkContext.DRIVER_IDENTIFIER) {
        Some(Utils.getThreadDump())
      } else {
        val endpointRef = env.blockManager.master.getExecutorEndpointRef(executorId).get
        Some(endpointRef.askWithRetry[Array[ThreadStackTrace]](TriggerThreadDump))
      }
    } catch {
      case e: Exception =>
        logError(s"Exception getting thread dump from executor $executorId", e)
        None
    }
  }

于是依葫芦画瓢 :


package com.scalatoy.studycase.thread

import java.lang.management.ManagementFactory
import java.util.concurrent.locks.ReentrantLock

/**
  * @author todd.chen at 12/12/2016 20:48.
  *         email : todd.chen@ximalaya.com
  */
object ManagementFactoryCase {
  private val logger = org.slf4j.LoggerFactory.getLogger(this.getClass)


  val lock = new ReentrantLock()

  def main(args: Array[String]): Unit = {
    new Thread(new Runnable {
      override def run() = {
        lock.lock()
        logger.info(s"${Thread.currentThread().getName} get lock")
        Thread sleep 10000
        lock.unlock()
        logger.info(s"${Thread.currentThread().getName} unlock")
      }
    }).start()

    new Thread(new Runnable {
      override def run() = {
        logger.info(s"${Thread.currentThread().getName} want to get lock")
        while (!lock.tryLock()) {
          Thread sleep 1000
          logger.info("retry get lock")
        }
        logger.info(s"${Thread.currentThread().getName} get lock")
        lock.unlock()
      }
    }).start()

    ManagementFactory.getThreadMXBean.dumpAllThreads(true,true).foreach(println)
  }


}

日志输出

21:04:44.163 [Thread-2] INFO  c.s.s.thread.ManagementFactoryCase$ - 1 loop dump thread
21:04:44.163 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - Thread-1 want to get lock
21:04:44.163 [Thread-0] INFO  c.s.s.thread.ManagementFactoryCase$ - Thread-0 get lock
"DestroyJavaVM" Id=13 RUNNABLE


"Thread-2" Id=12 RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:454)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$3$$anonfun$run$1.apply$mcVI$sp(ManagementFactoryCase.scala:60)
    at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:160)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$3.run(ManagementFactoryCase.scala:58)
    at java.lang.Thread.run(Thread.java:745)


"Thread-1" Id=11 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$2.run(ManagementFactoryCase.scala:47)
    at java.lang.Thread.run(Thread.java:745)


"Thread-0" Id=10 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$1.run(ManagementFactoryCase.scala:37)
    at java.lang.Thread.run(Thread.java:745)

    Number of locked synchronizers = 1
    - java.util.concurrent.locks.ReentrantLock$NonfairSync@1e38eccd


"Monitor Ctrl-Break" Id=9 RUNNABLE (in native)
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:79)
    at java.lang.Thread.run(Thread.java:745)


"Signal Dispatcher" Id=4 RUNNABLE


"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@6b505041
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.ReferenceQueue$Lock@6b505041
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)


"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@7b1bf96e
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.Reference$Lock@7b1bf96e
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)


21:04:45.172 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:46.176 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:47.180 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:48.186 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:49.189 [Thread-2] INFO  c.s.s.thread.ManagementFactoryCase$ - 2 loop dump thread
21:04:49.189 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
"DestroyJavaVM" Id=13 RUNNABLE


"Thread-2" Id=12 RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:454)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$3$$anonfun$run$1.apply$mcVI$sp(ManagementFactoryCase.scala:60)
    at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:160)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$3.run(ManagementFactoryCase.scala:58)
    at java.lang.Thread.run(Thread.java:745)


"Thread-1" Id=11 RUNNABLE
    at ch.qos.logback.classic.pattern.TargetLengthBasedClassNameAbbreviator.computeLengthArray(TargetLengthBasedClassNameAbbreviator.java:96)
    at ch.qos.logback.classic.pattern.TargetLengthBasedClassNameAbbreviator.abbreviate(TargetLengthBasedClassNameAbbreviator.java:52)
    at ch.qos.logback.classic.pattern.NamedConverter.convert(NamedConverter.java:53)
    at ch.qos.logback.classic.pattern.NamedConverter.convert(NamedConverter.java:18)
    at ch.qos.logback.core.pattern.FormattingConverter.write(FormattingConverter.java:37)
    at ch.qos.logback.core.pattern.PatternLayoutBase.writeLoopOnConverters(PatternLayoutBase.java:119)
    at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:149)
    at ch.qos.logback.classic.PatternLayout.doLayout(PatternLayout.java:39)
    ...

    Number of locked synchronizers = 1
    - java.util.concurrent.locks.ReentrantLock$FairSync@48032d99


"Thread-0" Id=10 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$1.run(ManagementFactoryCase.scala:37)
    at java.lang.Thread.run(Thread.java:745)

    Number of locked synchronizers = 1
    - java.util.concurrent.locks.ReentrantLock$NonfairSync@1e38eccd


"Monitor Ctrl-Break" Id=9 RUNNABLE (in native)
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:79)
    at java.lang.Thread.run(Thread.java:745)


"Signal Dispatcher" Id=4 RUNNABLE


"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@6b505041
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.ReferenceQueue$Lock@6b505041
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)


"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@7b1bf96e
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.Reference$Lock@7b1bf96e
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)


21:04:50.198 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:51.204 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:52.208 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:53.211 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:54.173 [Thread-0] INFO  c.s.s.thread.ManagementFactoryCase$ - Thread-0 unlock
21:04:54.200 [Thread-2] INFO  c.s.s.thread.ManagementFactoryCase$ - 3 loop dump thread
"DestroyJavaVM" Id=13 RUNNABLE


"Thread-2" Id=12 RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:454)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$3$$anonfun$run$1.apply$mcVI$sp(ManagementFactoryCase.scala:60)
    at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:160)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$3.run(ManagementFactoryCase.scala:58)
    at java.lang.Thread.run(Thread.java:745)


"Thread-1" Id=11 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at com.scalatoy.studycase.thread.ManagementFactoryCase$$anon$2.run(ManagementFactoryCase.scala:47)
    at java.lang.Thread.run(Thread.java:745)


"Monitor Ctrl-Break" Id=9 RUNNABLE (in native)
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:79)
    at java.lang.Thread.run(Thread.java:745)


"Signal Dispatcher" Id=4 RUNNABLE


"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@6b505041
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.ReferenceQueue$Lock@6b505041
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)


"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@7b1bf96e
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.Reference$Lock@7b1bf96e
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)


21:04:54.216 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - retry get lock
21:04:54.216 [Thread-1] INFO  c.s.s.thread.ManagementFactoryCase$ - Thread-1 get lock

效果还可以,妈妈再也不用担心运维不给我打堆栈了

my github

你可能感兴趣的:(scala)