rabbitmq / amqp直接回复并返回通知

时间:2019-11-26 15:42:52

标签: go rabbitmq rpc amqp

我使用Rabbitmq从各种输入源(websocket,rest等)向我的工作人员传递消息。每个工作人员在共享交换机上侦听一堆不同的路由键。

现在,workerA可能会处理“ routeA”。当我的输入源将某些东西发送到routeA时,workerA拿起它并使用它。

但是,如果没有routeA-“消费者”会怎样?在那种情况下,我希望输入源“知道”该请求没有人。并且由于没有“兔子使用者”使用此消息,因此将其丢弃。 (对不起,如果用语不正确),据我了解,控制消息(?)的处理就是NotifyReturn()(amqp的golang库)加入的地方,以便发布者可以了解这一事实,它的消息被丢弃了。

这是我的代码的一个剥离示例。这种方法适用于我一个简单的“仅发布此消息方案”。我不喜欢RPC。 RPC总是触发case returnNotification := <-returnChannel:情况。

我的问题:

  • 我错了吗? /这不是检查邮件可传递性的方法吗?

谢谢!

编辑:忘记提及:在“答复”上引发错误。因此,请求已发送,但答复(通过“仅发布”发送)得到了NO_ROUTE returnNotification

只需发布

    // error handling omitted for example code
    tC, _ := rabbitConnection.Channel()
    defer tC.Close()

    tC.Confirm(false)

    var ack = make(chan uint64)
    var nack = make(chan uint64)
    tC.NotifyConfirm(ack, nack)

    returnChannel := make(chan amqp.Return)
    tC.NotifyReturn(returnChannel)

    p := someFunctionGeneratingAPublishing()

    tC.Publish(
        exchange,
        e.GetRoutingKey(),
        true,
        false,
        *p,
    )

    select {
    case returnNotification := <-returnChannel:
        if returnNotification.ReplyCode == amqp.NoRoute {
            return fmt.Errorf("no amqp route for %s", e.GetRoutingKey())
        }

    case <-ack:
        return nil

    case <-nack:
        return fmt.Errorf("basic nack for %s", e.GetRoutingKey())
    }

RPC

    publishing := someFunctionGeneratingAPublishing()
    publishing.ReplyTo = "amq.rabbitmq.reply-to"

    con := GetConnection()
    directChannel, _ := con.Channel()
    defer directChannel.Close()

    directChannel.Confirm(false)

    var ack = make(chan uint64)
    var nack = make(chan uint64)
    directChannel.NotifyConfirm(ack, nack)

    returnChannel := make(chan amqp.Return)
    directChannel.NotifyReturn(returnChannel)

    // consume direct-reply to pattern queue
    deliveryChan, _ := directChannel.Consume(
        "amq.rabbitmq.reply-to",
        "",
        true,
        false,
        false,
        false,
        nil,
    )


    directChannel.Publish(
        exchange,
        e.GetRoutingKey(),
        true,
        false,
        *publishing,
    )

    select {
    case returnNotification := <-returnChannel:
        if returnNotification.ReplyCode == amqp.NoRoute {
            return fmt.Errorf("no amqp route for %s", e.GetRoutingKey())
        }

    case <-ack:
        return nil

    case <-nack:
        return fmt.Errorf("basic nack for %s", e.GetRoutingKey())
    }

1 个答案:

答案 0 :(得分:0)

好吧,在黑暗中徘徊了很多之后,我终于意识到了我的基本错误:没有仔细阅读文档:

  

如果RPC服务器发布带有强制标志的设置,则将amq.rabbitmq.reply-to。*视为不是队列;即,如果服务器仅以该名称发布,则该邮件将被视为“未路由”;如果设置了强制标志,则将发送basic.return。   RabbitMQ Direct-Reply-To Article

根据设计,在我配置的情况下,答复消息被视为“未路由”。