我们可以有两种方式来更加优雅的停止流程序,分别是通过http暴露服务,和通过HDFS做消息中转来定时扫描mark文件是否存在来触发关闭服务。
下面我们先来看下通过http暴露服务的核心代码:
/****
* 负责启动守护的jetty服务
* @param port 对外暴露的端口号
* @param ssc Stream上下文
*/
def daemonHttpServer(port:Int,ssc: StreamingContext)={
val server=new Server(port)
val context = new ContextHandler();
context.setContextPath( "/close" );
context.setHandler( new CloseStreamHandler(ssc) )
server.setHandler(context)
server.start()
}
/*** 负责接受http请求来优雅的关闭流
* @param ssc Stream上下文
*/
class CloseStreamHandler(ssc:StreamingContext) extends AbstractHandler {
override def handle(s: String, baseRequest: Request, req: HttpServletRequest, response: HttpServletResponse): Unit ={
log.warn("开始关闭......")
ssc.stop(true,true)//优雅的关闭
response.setContentType("text/html; charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
val out = response.getWriter();
out.println("close success");
baseRequest.setHandled(true);
log.warn("关闭成功.....")
}
}
然后在来看下另一种方式扫描HDFS文件的方式:
/***
* 通过一个消息文件来定时触发是否需要关闭流程序
* @param ssc StreamingContext
*/
def stopByMarkFile(ssc:StreamingContext):Unit= {
val intervalMills = 10 * 1000 // 每隔10秒扫描一次消息是否存在
var isStop = false
val hdfs_file_path = "/spark/streaming/stop" //判断消息文件是否存在,如果存在就
while (!isStop) {
isStop = ssc.awaitTerminationOrTimeout(intervalMills)
if (!isStop && isExistsMarkFile(hdfs_file_path)) {
log.warn("2秒后开始关闭sparstreaming程序.....")
Thread.sleep(2000)
ssc.stop(true, true)
}
}
}
/***
* 判断是否存在mark file
* @param hdfs_file_path mark文件的路径
* @return
*/
def isExistsMarkFile(hdfs_file_path:String):Boolean={
val conf = new Configuration()
val path=new Path(hdfs_file_path)
val fs =path.getFileSystem(conf);
fs.exists(path)
}
上面是两种方式的核心代码,最后提下触发停止流程序:
第一种需要在启动服务的机器上,执行下面封装的脚本:
## tx.log是提交spark任务后的输出log重定向的log
## &> tx.log &
#!/bin/bash
driver=`cat tx.log | grep ApplicationMaster | grep -Po '\d+.\d+.\d+.\d+'`
echo $driver
curl http://$driver:port/close/
echo "stop finish"
第二种方式,找到一个拥有HDFS客户端机器,向HDFS上写入指定的文件:
#生成文件后,10秒后程序就会自动停止
hadoop fs -touch /spark/streaming/stop
#下次启动前,需要清空这个文件,否则程序启动后就会停止
hadoop fs -rm -r /spark/streaming/stop