Scala 为什么Spark流媒体应用程序在使用sbt运行时工作良好,但在Tomcat(作为web应用程序)上却不工作?

Scala 为什么Spark流媒体应用程序在使用sbt运行时工作良好,但在Tomcat(作为web应用程序)上却不工作?,scala,tomcat,apache-spark,apache-kafka,spark-streaming,Scala,Tomcat,Apache Spark,Apache Kafka,Spark Streaming,我在Scala中有一个Spark应用程序,它每10秒从Kafka获取一次记录并将其保存为文件。这是SBT项目,我使用SBT run命令运行我的应用程序。在我将应用程序部署到Tomcat上之前,一切正常。我设法用生成了WAR文件,但在Tomcat上部署时,我的应用程序似乎没有任何作用。 这是我的代码: object SparkConsumer { def main (args: Array[String]) { val conf = new SparkConf().setMaster

我在Scala中有一个Spark应用程序,它每10秒从Kafka获取一次记录并将其保存为文件。这是SBT项目,我使用
SBT run
命令运行我的应用程序。在我将应用程序部署到Tomcat上之前,一切正常。我设法用生成了WAR文件,但在Tomcat上部署时,我的应用程序似乎没有任何作用。
这是我的代码:

object SparkConsumer {
  def main (args: Array[String]) {

    val conf = new SparkConf().setMaster("local[*]").setAppName("KafkaReceiver")
    val ssc = new StreamingContext(conf, Seconds(10))


    val kafkaParams = Map[String, Object](
      "bootstrap.servers" -> "localhost:9092",
      "key.deserializer" -> classOf[StringDeserializer],
      "value.deserializer" -> classOf[StringDeserializer],
      "group.id" -> "group_id",
      "auto.offset.reset" -> "latest",
      "enable.auto.commit" -> (false: java.lang.Boolean)
    )
    val topics = Array("mytopic")
    val stream = KafkaUtils.createDirectStream[String, String](
      ssc,
      PreferConsistent,
      Subscribe[String, String](topics, kafkaParams)
    )

    stream.map(record => (record.key, record.value)).print

    val arr = new ArrayBuffer[String]();

    val lines = stream.map(record => (record.key, record.value));

    stream.foreachRDD { rdd =>

      if (rdd.count() > 0 ) {
            val date = System.currentTimeMillis()
            rdd.saveAsTextFile ("/tmp/sparkout/mytopic/" + date.toString)
            rdd.foreach { record => println("t=" + record.topic + " m=" + record.toString()) }
      }

      println("Stream had " + rdd.count() + " messages")

      val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
        rdd.foreachPartition { iter =>
        val o: OffsetRange = offsetRanges(TaskContext.get.partitionId)
        println(s"${o.topic} ${o.partition} ${o.fromOffset} ${o.untilOffset}")
        println(o)
      }
    }

    stream.saveAsTextFiles("/tmp/output")


    ssc.start()
    ssc.awaitTermination()
  }
}
奇怪的是,当通过
sbt run
命令运行时,该应用程序运行完全正常。它正确地读取卡夫卡的记录,并将其保存为所需目录中的文件。我不知道发生了什么事。我尝试使用
log4j
启用日志记录,但在Tomcat上它甚至不记录任何内容。我一直在寻找答案,但还没有找到解决办法

总之

我的Scala Spark应用程序(是SBT项目)应该每隔10秒从Kafka读取记录并将其保存为文件。它在通过
sbt run
命令运行时工作,但在Tomcat上部署时不工作

其他信息:

  • Scala 2.12
  • 雄猫7
  • SBT 0.13.15
  • 要求更多

Q:有什么问题

tl;dr独立应用程序
SparkConsumer
在Tomcat上正常运行,Tomcat本身也正常运行

读到这个问题我感到非常惊讶,因为您的代码不是我期望在Tomcat上工作的东西。对不起

Tomcat是一个servlet容器,因此在web应用程序中需要servlet

即使您设法创建了WAR并将其部署到Tomcat,您也没有从这个web应用程序“触发”任何东西来启动Spark流应用程序(方法
main
中的代码)

Spark Streaming应用程序在使用
sbt run
执行时工作正常,因为这是
sbt run
的目标,即在sbt管理的项目中执行独立应用程序

鉴于您的sbt项目中只有一个独立的应用程序,
sbt run
已设法找到
SparkConsumer
并执行其
main
输入方法。这并不奇怪

但是,它在Tomcat上不起作用。您必须将应用程序公开为POST或GET端点,并使用HTTP客户端(一种浏览器或命令行工具,如curl、wget或httpie)来执行它


Spark不支持Scala 2.12,所以…您是如何使用Spark的Scala版本的?!不可能

我推测类路径中可能缺少库。你调试远程应用程序了吗?