2017-07-25 26 views
0

最近我发现我的Clojure/Ring/Jetty服务器反复进入NoClassDefFoundError,当我cider-connect进入它并做一些事情。我想这是因为线程池被一些死线程耗尽。我可以在重复运行的计划任务中执行“阻止订阅”吗?

然后我发现其中一个定义clojurewerkz.quartzite.scheduler工作在每天一次的服务器这一功能:

(defn consumer-msgs-announcement 
    [rabbitmq queue-name & args] 
    (with-open [conn (lc/connect rabbitmq)] 
    (let [ch (lch/open conn)] 
     (lq/declare ch queue-name {:durable false :auto-delete false}) 
     (println " [*] Waiting for messages. To exit press CTRL+C") 
     ;; (lcons/blocking-subscribe ch queue-name msg-queue/post-wxmsg-handle-delivery {:auto-ack true}) 
     (lcons/blocking-subscribe ch queue-name handle-delivery-announcement {:auto-ack true}) 
    ))) 

其中包含的包被定义为:

[langohr.core :as lc] 
    [langohr.channel :as lch] 
    [clojure.string :as str] 
    [langohr.queue :as lq] 
    [langohr.consumers :as lcons] 

我怀疑blocking-subscribe将导致它永远被阻塞的线程耗尽JVM的线程池并最终导致NoClassDefFoundError错误。

我不确定这个问题,但是我可以在重复运行的计划任务中执行blocking-subscribe吗?

我上面描述的事情可能吗?或者我的演绎有什么问题吗?

谢谢。

+0

这里有什么问题吗? – theMayer

+0

是的,我不知道我的演绎。你能帮助我吗?我更新了这个问题。谢谢。 – cmal

回答

1

根据我的经验blocking-subscribe确实会无限期地阻塞线程。你可以快速检查sourceblocking-subscribe,看看它是否可能是一个潜在的无休止的seq的do-seq。

看起来您只想让自己的工作收集自上次运行以来已备份在队列中的所有现有邮件。这里有几个选项可以帮助我理解这种访问模式。

  1. 您可以使用langohr.basic/get为了处理队列中的消息,直到收到一个nil

  2. 您可以使用langohr.consumers/subscribe创建一个简单的无阻塞消费者

    • 启动消费
    • 保持消费者标签你
    • 睡眠的时间预定量
    • 取消消费者使用langohr.basic /取消

P.S.我无法将链接发布到subscribe/cancel文档,但在源代码和langohr API参考中很容易找到。

+0

谢谢。从你的回答中学到了很多东西。 – cmal