#一 网上也有停止SparkStreaming作业的方法,但是都不够优雅,不能够从程序内部实现停止SparkStreaming作业。我来介绍一种优雅的方式。
##1:思路
1: 程序出现异常后打一个标记,标记存放在可靠的外部系统如hdfs、redis等。
2:Driver 不断重复扫描标记,判断是否需要停止作业。
3: 把ssc.awaitTermination() 替换为 ssc.awaitTerminationOrTimeout(checkIntervalMillis),awaitTerminationOrTimeout()为阻塞回调函数。
代码如下:https://github.com/lanjiang/streamingstopgraceful
ssc.start()
val checkIntervalMillis = 1000
var isStopped = false
while (! isStopped) {
println("calling awaitTerminationOrTimeout")
isStopped = ssc.awaitTerminationOrTimeout(checkIntervalMillis)
if (isStopped)
println("confirmed! The streaming context is stopped. Exiting application...")
else
println("Streaming App is still running. Timeout...")
checkShutdownMarker
if (!isStopped && stopFlag) {
println("stopping ssc right now")
ssc.stop(true, true)
println("ssc is stopped!!!!!!!")
}
}
}
/*
* 扫描是否停止作业的标记
* */
def checkShutdownMarker = {
if (!stopFlag) {
val flag = jd.lpop("data_user_app_stop")
//
if( !( flag == null || flag == "") )
stopFlag = true
}
# 二 测试
模拟插入失败,然后更新标记,使其调用一下方法。
ssc.stop(true, true)