不忘初心,砥砺前行
作者 | 陌无崖
转载请联系授权
导语
昨天的内容主要讲了RabbitMQ的发布订阅模式和路由模式,都很好的满足了我们的日志打印,但是如果说,我对日志的打印,希望可以过滤掉一些内容呢,比如说,在打印错误日志的时候,只打印login时的错误?这个时候,就需要我们使用主题订阅的模式,可以说,主题订阅模式可以完全代替路由模式,因为在主题订阅模式中,如果没有响应的关键词,便和路由模式完全一样。
主题交换器介绍
在使用主题交换器时需要注意以下几点
在使用routing_key,必须是有点分隔符进行分隔
*
可以代表代替一个单词#
可以代替0个或多个单词
案例
我们对我们之前的例子做修改,这次修改希望生产者可以在运行的时候指定路由需要增加下面这个函数
代码语言:javascript复制func severityFrom(args []string) string {
var s string
if (len(args) < 2) || os.Args[1] == "" {
s = "#"
} else {
s = os.Args[1]
}
fmt.Println(s)
return s
}
func bodyFrom(args []string) string {
var s string
if (len(args) < 3) || os.Args[2] == "" {
s = "hello"
} else {
s = strings.Join(args[2:], " ")
}
return s
}
现在来看我们的生产者 首先需要申请一个主题模式的交换器
代码语言:javascript复制err = ch.ExchangeDeclare(
"logs_topic", //交换器的名字
"topic", //交换器的类型、这里为广播类型
true, //是否持久
false, //无用的时候是否自动删除
false, //true表示是。客户端无法直接发送msg到内部交换器,只有交换器可以发送msg到内部交换器。
false, //no-wait
nil, //arguments
)
然后发送消息到交换器
代码语言:javascript复制err = ch.Publish(
"logs_topic", //发送到交换机的名字
severityFrom(os.Args), // routing key // 路由,即队列的名字
false, //mandatory
false, //immediate
amqp.Publishing{
DeliveryMode: amqp.Persistent, //消息的持久化
ContentType: "text/plain",
Body: []byte(body),
},
)
现在我们写两个消费者,消费者的路由不一样,消费者生产交换器和生产者完全一样,接着我们需要看第一个消费者绑定路由
代码语言:javascript复制err = ch.QueueBind(
q.Name, //队列的名字
"#.info.*", //routing key
"logs_topic", //所绑定的交换器
false,
nil,
)
第二个消费者绑定路由
代码语言:javascript复制err = ch.QueueBind(
q.Name, //队列的名字
"info.#", //routing key
"logs_topic", //所绑定的交换器
false,
nil,
)
运行
只有绑定了info.#收到了消息
现在你可以尝试以下运行以上查看是否info.#和info.*都收到了消息?
END