【Golang】RabbitMq使用

创建一个简单的 Go 项目来学习 RabbitMQ 的基本操作。我们将创建一个生产者和消费者的示例。

项目结构:

mq-demo/
├── docker-compose.yml
├── go.mod
├── producer/
│   └── main.go
└── consumer/
    └── main.go

1. 创建项目并初始化*

mkdir mq-demo
cd mq-demo
go mod init mq-demo
go get github.com/streadway/amqp

2. 生产者代码 (producer/main.go)

`go:producer/main.go

package main

import (
    "fmt"
    "log"

    "github.com/streadway/amqp"
)

func main() {
    // 连接 RabbitMQ
    conn, err := amqp.Dial("amqp://admin:admin@localhost:5672/")
    if err != nil {
        log.Fatalf("无法连接到 RabbitMQ: %v", err)
    }
    defer conn.Close()

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

    // 声明队列
    q, err := ch.QueueDeclare(
        "hello", // 队列名称
        false,   // 持久性
        false,   // 自动删除
        false,   // 排他性
        false,   // 非阻塞
        nil,     // 其他参数
    )
    if err != nil {
        log.Fatalf("无法声明队列: %v", err)
    }

    // 发送消息
    body := "Hello World!"
    err = ch.Publish(
        "",     // exchange
        q.Name, // routing key
        false,  // mandatory
        false,  // immediate
        amqp.Publishing{
            ContentType: "text/plain",
            Body:        []byte(body),
        })
    if err != nil {
        log.Fatalf("发送失败: %v", err)
    }
    fmt.Printf("发送消息: %s\n", body)
}

3. 消费者代码 (consumer/main.go)
go:consumer/main.go

package main

import (
    "fmt"
    "log"

    "github.com/streadway/amqp"
)

func main() {
    // 连接 RabbitMQ
    conn, err := amqp.Dial("amqp://admin:admin@localhost:5672/")
    if err != nil {
        log.Fatalf("无法连接到 RabbitMQ: %v", err)
    }
    defer conn.Close()

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

    // 声明队列
    q, err := ch.QueueDeclare(
        "hello", // 队列名称
        false,   // 持久性
        false,   // 自动删除
        false,   // 排他性
        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)
    }

    forever := make(chan bool)

    go func() {
        for d := range msgs {
            fmt.Printf("收到消息: %s\n", d.Body)
        }
    }()

    fmt.Println("等待消息中... 按 CTRL+C 退出")
    <-forever
}

4. 使用方法

首先启动 RabbitMQ:

docker-compose up -d

然后在两个不同的终端窗口运行:

# 终端1:运行消费者
go run consumer/main.go

# 终端2:运行生产者
go run producer/main.go

运行结果

这个示例展示了 RabbitMQ 的基本概念:
- 连接(Connection)
- 通道(Channel)
- 队列(Queue)
- 生产者(Producer)
- 消费者(Consumer)

进阶学习建议:
1. 尝试使用不同的交换机类型(direct, fanout, topic)
2. 实现消息确认机制
3. 尝试消息持久化
4. 实现发布/订阅模式
5. 实现死信队列
6. 实现延迟队列

### GolangRabbitMQ 的封装 在 Go 语言中,`amqp` 库被广泛用于连接和操作 RabbitMQ。为了提高代码的可维护性和重用性,通常会创建一个自定义包来封装与 RabbitMQ 相关的功能。 #### 创建 RabbitMQ 客户端结构体 ```go package rabbitmq import ( "fmt" "github.com/streadway/amqp" ) type Client struct { conn *amqp.Connection channel *amqp.Channel } ``` 此部分定义了一个 `Client` 结构体,它保存了到 RabbitMQ 的连接以及通道指针[^1]。 #### 初始化客户端并建立连接 ```go func NewRabbitMQClient(uri string) (*Client, error) { client := &Client{} var err error if client.conn, err = amqp.Dial(uri); err != nil { return nil, fmt.Errorf("dial: %s", err) } if client.channel, err = client.conn.Channel(); err != nil { return nil, fmt.Errorf("channel: %s", err) } return client, nil } ``` 上述函数实现了对 RabbitMQ 实例的安全连接,并返回一个新的 `Client` 对象实例。 #### 发布消息的方法 ```go func (c *Client) Publish(exchange, key string, body []byte) error { err := c.channel.Publish( exchange, key, false, false, amqp.Publishing{ DeliveryMode: amqp.Persistent, ContentType: "text/plain", Body: body, }) if err != nil { return fmt.Errorf("publish: %s", err) } return nil } ``` 这段代码展示了如何向指定交换机发送一条持久化消息。 #### 关闭资源释放 ```go func (c *Client) Close() error { if err := c.channel.Close(); err != nil { return fmt.Errorf("close channel: %v", err) } if err := c.conn.Close(); err != nil { return fmt.Errorf("close connection: %v", err) } return nil } ``` 该方法负责关闭之前打开的所有网络连接和AMQP信道,防止内存泄漏和其他潜在问题的发生。 通过这种方式构建起来的基础类可以帮助简化应用程序中的 RabbitMQ 使用逻辑,同时也便于后续扩展更多高级特性支持,比如事务管理、确认机制等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值