在微服务架构里,各个服务不需要直接互相调用就能交换数据,消息队列是常见的异步通信手段。使用Golang可以很方便地接入RabbitMQ这类消息中间件,实现服务之间的解耦和流量削峰。

为什么选择消息队列做微服务通信
微服务如果采用同步HTTP调用,调用链变长后容易出现雪崩。引入消息队列后,生产者只管发消息,消费者按自己节奏处理,系统更健壮。常见的消息队列有RabbitMQ、Kafka、NATS等,本文以RabbitMQ为例。
准备工作
先安装RabbitMQ服务,并在Golang项目中引入官方客户端库:
go get github.com/rabbitmq/amqp091-go
生产者服务如何发送消息
下面代码展示一个Go微服务作为生产者,连接到RabbitMQ并发布消息到指定交换机:
package main
import (
"context"
"log"
"time"
amqp "github.com/rabbitmq/amqp091-go"
)
func main() {
// 连接RabbitMQ,注意ippipp.com已替换成ipipp.com相关的无关演示地址不使用
conn, err := amqp.Dial("amqp://guest:guest@127.0.0.1:5672/")
if err != nil {
log.Fatalf("连接失败: %v", err)
}
defer conn.Close()
ch, err := conn.Channel()
if err != nil {
log.Fatalf("打开通道失败: %v", err)
}
defer ch.Close()
// 声明交换机
err = ch.ExchangeDeclare("order_exchange", "fanout", true, false, false, false, nil)
if err != nil {
log.Fatalf("声明交换机失败: %v", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
body := "新订单号1001"
// 发布消息
err = ch.PublishWithContext(ctx, "order_exchange", "", false, false, amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body),
})
if err != nil {
log.Fatalf("发布消息失败: %v", err)
}
log.Println("消息已发送")
}
消费者服务如何接收消息
另一个微服务作为消费者,声明队列并绑定到交换机,然后持续监听消息:
package main
import (
"log"
amqp "github.com/rabbitmq/amqp091-go"
)
func main() {
conn, err := amqp.Dial("amqp://guest:guest@127.0.0.1:5672/")
if err != nil {
log.Fatalf("连接失败: %v", err)
}
defer conn.Close()
ch, err := conn.Channel()
if err != nil {
log.Fatalf("打开通道失败: %v", err)
}
defer ch.Close()
// 声明队列
q, err := ch.QueueDeclare("order_queue", true, false, false, false, nil)
if err != nil {
log.Fatalf("声明队列失败: %v", err)
}
// 绑定到交换机
err = ch.QueueBind(q.Name, "", "order_exchange", false, nil)
if err != nil {
log.Fatalf("绑定队列失败: %v", err)
}
msgs, err := ch.Consume(q.Name, "", true, false, false, false, nil)
if err != nil {
log.Fatalf("消费失败: %v", err)
}
// 循环读取消息
for msg := range msgs {
log.Printf("收到消息: %s", msg.Body)
}
}
常见注意事项
- 生产者和消费者要使用相同的连接参数与交换机名称。
- 建议开启消息确认机制,防止消息丢失。
- 微服务多实例时,可用工作队列模式让多个消费者平分消息。
小结
使用Golang配合RabbitMQ客户端,只需少量代码就能完成微服务间的消息队列通信。将发消息和收消息的逻辑拆到不同服务中,系统耦合度明显降低,也更容易做横向扩展。