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