如何解决Go-Stomp读取超时问题

时间:2016-10-07 09:41:43

标签: go stomp apollo

尝试使用Go-Stomp订阅ActiveMQ(Apollo),但我有读取超时错误。我的应用程序应该每天24小时处于活动状态以处理传入消息。

问题

  1. 虽然队列中不再存在消息,但有没有办法保留订阅?试图将ConnOpt.HeartBeat放入也似乎不起作用
  2. 为什么在readTimeout之后,似乎我仍然接受另外一条消息?
  3. 以下是我的步骤:

    • 我在inputQueue
    • 中输入了1000条消息进行测试
    • 运行订阅者,下面提供的代码
    • 订阅者读完1000条消息2-3秒后,看到错误“2016/10/07 17:12:44订阅1:/ queue / hflc-in:ERROR消息:读取超时”。
    • 添加另外1000条消息,但似乎订阅已经关闭,因此没有消息未被处理

    我的代码:

      var(
       serverAddr   = flag.String("server", "10.92.10.10:61613", "STOMP server    endpoint")
       messageCount = flag.Int("count", 10, "Number of messages to send/receive")
       inputQ       = flag.String("inputq", "/queue/hflc-in", "Input queue")
    )
    
    var options []func(*stomp.Conn) error = []func(*stomp.Conn) error{
       stomp.ConnOpt.Login("userid", "userpassword"),
       stomp.ConnOpt.Host("mybroker"),
       stomp.ConnOpt.HeartBeat(360*time.Second, 360*time.Second), // I put this but seems no impact
    }
    
    func main() {
      flag.Parse()
      jobschan := make(chan bean.Request, 10)
      //my init setup
      go getInput(1, jobschan)
    }
    
    func getInput(id int, jobschan chan bean.Request) {
       conn, err := stomp.Dial("tcp", *serverAddr, options...)
    
       if err != nil {
          println("cannot connect to server", err.Error())
          return
       }
       fmt.Printf("Connected %v \n", id)
    
       sub, err := conn.Subscribe(*inputQ, stomp.AckClient)
       if err != nil {
         println("cannot subscribe to", *inputQ, err.Error())
         return
       }
    
       fmt.Printf("Subscribed %v \n", id)
       var messageCount int
       for {
        msg := <-sub.C
        //expectedText := fmt.Sprintf("Message #%d", i)
        if msg != nil {
    
            actualText := string(msg.Body)
    
            var req bean.Request
            if actualText != "SHUTDOWN" {
                messageCount = messageCount + 1
                var err2 = easyjson.Unmarshal([]byte(actualText), &req)
                if err2 != nil {
                    log.Error("Unable unmarshall", zap.Error(err))
                    println("message body %v", msg.Body) // what is [0/0]0x0 ?
                } else {
                    fmt.Printf("Subscriber %v received message, count %v \n  ", id, messageCount)
                    jobschan <- req
                }
            } else {
                logchan <- "got some issue"
            }
        }
       }
      }
    

    错误:

      

    2016/10/07 17:12:44订阅1:/ queue / hflc-in:ERROR消息:读取超时
      [E] 2016-10-07T09:12:44Z un unrsrshall
      消息体%v [0/0] 0x0

1 个答案:

答案 0 :(得分:0)

通过添加以下行来解决:

在Apollo中,注意到队列在几秒后被清空后被删除,所以在apollo.xml中将auto_delete_after放到几个小时,例如:

<queue id="hflc-in" dlq="dlq-in" nak_limit="3" auto_delete_after="7200"/>
<queue id="hflc-log" dlq="dlq-log" nak_limit="3" auto_delete_after="7200"/>
<queue id="hflc-out" dlq="dlq-out" nak_limit="3" auto_delete_after="7200"/>
Go中的

注意到go-stomp会在队列中找不到任何消息后立即放弃,所以在conn选项中添加HeartBeat错误

var options []func(*stomp.Conn) error = []func(*stomp.Conn) error{
   //.... original configuration
   stomp.ConnOpt.HeartBeatError(360 * time.Second),
}

然而仍然对第2号问题感到困惑。