【RabbitMQ #3】 | Go 客户端 + SpringAMQP

一、RabbitMQ 基础概念

AMQP 协议

AMQP(高级消息队列协议):与语言、平台无关的消息协议,RabbitMQ 基于该协议。

Spring AMQP 简介

Spring AMQP 是基于 AMQP 协议封装的 API 规范,分为两部分:

  1. spring-amqp:基础抽象层
  2. spring-rabbit:底层 RabbitMQ 具体实现

二、Go 客户端安装

注意:这里有两套 Go 客户端

  1. 新版官方:rabbitmq-amqp-go-client(AMQP 1.0)
  2. 社区常用:streadway/amqp(AMQP 0-9-1,下面 Demo 用的这个,学习推荐)
复制代码
# 新版官方客户端安装
go get github.com/rabbitmq/rabbitmq-amqp-go-client

导入:

Go 复制代码
import (
	"context"
	"log"
	rmq "github.com/rabbitmq/rabbitmq-amqp-go-client/pkg/rabbitmqamqp"
)

下面示例代码使用的是 streadway/amqp(AMQP0-9-1,目前学习最简单,和 SpringAMQP 底层协议一致)

三、简单模型:生产者直接发消息到队列(Simple 模型)

流程:Publisher → Queue → Consumer 案例:simple.queue

  1. 在 RabbitMQ 控制台创建队列 simple.queue(代码里QueueDeclare是幂等,不存在自动创建)
  2. 生产者发送消息到队列
  3. 消费者监听队列,接收消息

SpringAMQP 开发步骤对照(方便 Java 转 Go 理解)

  1. 引入 RabbitMQ 依赖
  2. 配置 RabbitMQ 服务信息:host、port、virtual-host、username、password
  3. 发送消息:使用 RabbitTemplate
  4. 消费消息:使用 @RabbitListener 注解监听队列

Go 生产者代码(send.go)

等价 Spring rabbitTemplate.convertAndSend(queueName, msg)

Go 复制代码
package main

import (
	"fmt"
	"github.com/streadway/amqp"
)

func main() {
	// 1. 连接 rabbitmq
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	// 2. 创建通道
	ch, err := conn.Channel()
	if err != nil {
		panic(err)
	}
	defer ch.Close()

	queueName := "simple.queue"
	// 3. 声明队列:幂等。队列存在则不操作,不存在自动创建
	_, err = ch.QueueDeclare(
		queueName,
		false, // durable:是否持久化
		false, // autoDelete:是否自动删除
		false, // exclusive:独占队列
		false, // noWait
		nil,   // args:额外参数
	)
	if err != nil {
		panic(err)
	}

	msg := "hello, amqp!"
	// 4. 发布消息
	err = ch.Publish(
		"",          // exchange:空=默认交换机,和Spring行为一致
		queueName,   // routingKey:直接填队列名,消息直接路由到此队列
		false,       // mandatory
		false,       // immediate
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        []byte(msg),
		},
	)
	if err != nil {
		panic(err)
	}
	fmt.Printf("发送消息成功:%s\n", msg)
}

Go 消费者代码(consumer.go)

等价 Spring @RabbitListener(queues = "simple.queue"),持续监听队列

Go 复制代码
package main

import (
	"fmt"
	"github.com/streadway/amqp"
	"log"
)

func main() {
	// 1. 连接RabbitMQ
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	if err != nil {
		log.Fatalf("连接失败: %v", err)
	}
	defer conn.Close()

	// 2. 创建通道
	ch, err := conn.Channel()
	if err != nil {
		log.Fatalf("打开通道失败: %v", err)
	}
	defer ch.Close()

	queueName := "simple.queue"
	// 3. 声明队列(幂等)
	_, err = ch.QueueDeclare(
		queueName,
		false,
		false,
		false,
		false,
		nil,
	)
	if err != nil {
		log.Fatalf("声明队列失败: %v", err)
	}

	// 4. 注册消费者,开始消费消息
	msgs, err := ch.Consume(
		queueName, // 监听队列名
		"",        // consumer
		true,      // autoAck=true:收到消息自动确认,和Spring默认近似
		false,     // exclusive
		false,     // noLocal
		false,     // noWait
		nil,       // args
	)
	if err != nil {
		log.Fatalf("注册消费失败: %v", err)
	}

	fmt.Println("Go消费者启动,监听 simple.queue ...")
	// 循环读取消息,持续处理消息
	for d := range msgs {
		msg := string(d.Body)
		fmt.Printf("go 消费者接收到消息:[%s]\n", msg)
		fmt.Println("消息处理完成")
	}
}

四、核心要点总结

  1. 连接地址不要写错:amqp://账号:密码@ip:5672/
  2. QueueDeclare 幂等特性:重复调用不会报错,不存在则新建队列
  3. Simple 模型:空交换机,routingKey 直接写队列名,消息直接投递队列
  4. autoAck:自动确认,消息收到后 MQ 立刻删除消息;生产环境一般关闭,手动 ACK 保证可靠性
  5. SpringAMQP 和 Go streadway/amqp 底层都是 AMQP0-9-1,可以对照理解学习
相关推荐
利威尔xu1 小时前
Go map 底层崩溃:3 个 goroutine 并发写同一张 map,fatal error 崩掉整个服务
golang·源码·map·并发·后端开发
方方洛1 天前
ray教程-28-附录G-CICD与Slurm与云上调度
人工智能·分布式·机器学习
空奈qwq1 天前
【Kafka 从入门到实战】从手写一个队列到生产级消息中间件:架构、分区、消费组、零拷贝全解析
分布式·架构·kafka
利威尔xu1 天前
2026-11-08-Go-defer-panic-recover面试
面试·golang
JWASX2 天前
【Go】map 源码解析 - group
后端·golang·map·源码分析
山甫aa2 天前
锁一篇搞定:乐观锁、悲观锁、CAS、数据库锁与分布式锁【从零开始的 Web 后端学习】
java·数据库·分布式·后端·学习·web
联犀3 天前
纯 Go 的 CAD 开源库 go-cad:直接解析 DWG/DXF,现在也能导出 PDF
开发语言·golang·pdf
严肃小白兔3 天前
Cloudflare Durable Objects 支持自动重试:分布式调用如何避免重复执行?
分布式
FungLeo3 天前
成为全栈·Go 后端篇·三轮代码审阅之后:把可读性和证据做成工程规则
golang·go·ast·静态检查·成为全栈·代码审阅