Go Rabbitmq 使用

994914376發表於2020-01-19

Rabbitmq 學習使用樣例

使用說明需要本機安裝好rabbitmq才行

  • 目錄結構
├── RabbitMQ
│   └── rabbitmq.go   # rabbitmq實現方法
├── go.mod
├── go.sum
├── mainSimplePublish.go    // 釋出檔案
└── mainSimpleRecieve.go // 消費檔案

1、建立rabbitmq例項 rabbitmq.go

package RabbitMQ

import (
    "fmt"
    "log"

    "github.com/streadway/amqp"
)

// MQURL 格式 amqp://賬號:密碼@rabbitmq伺服器地址:埠號/vhost
const MQURL = "amqp://goshop:123456@127.0.0.1:5672/shop"

type RabbitMQ struct {
    conn    *amqp.Connection
    channel *amqp.Channel
    // 佇列名稱
    QueueName string
    // 交換機
    Exchange string
    // Key
    Key string
    // 連線資訊
    Mqurl string
}

// NewRabbitMQ 建立結構體例項
func NewRabbitMQ(queueName, exchange, key string) *RabbitMQ {
    rabbitmq := &RabbitMQ{
        QueueName: queueName,
        Exchange:  exchange,
        Key:       key,
        Mqurl:     MQURL,
    }
    var err error
    // 建立rabbitmq連線
    rabbitmq.conn, err = amqp.Dial(rabbitmq.Mqurl)
    rabbitmq.failOnErr(err, "建立連線錯誤!")

    rabbitmq.channel, err = rabbitmq.conn.Channel()
    rabbitmq.failOnErr(err, "獲取channel失敗!")

    return rabbitmq
}

// Destory 斷開channel和connection
func (r *RabbitMQ) Destory() {
    _ = r.channel.Close()
    _ = r.conn.Close()
}

// failOnErr 錯誤處理函式
func (r *RabbitMQ) failOnErr(err error, message string) {
    if err != nil {
        log.Fatalf("%s:%s", message, err)
        panic(fmt.Sprintf("%s:%s", message, err))
    }
}

// NewRabbitMQSimple
// 簡單模式Step 1.建立簡單模式下的RabbitMq例項
func NewRabbitMQSimple(queueName string) *RabbitMQ {
    return NewRabbitMQ(queueName, "", "")
}

// 簡單模式Step 2:簡單模式下生產程式碼
func (r *RabbitMQ) PublishSimple(message string) {
    // 1. 申請佇列,如果佇列不存在會自動建立,如何存在則跳過建立
    // 保證佇列存在,訊息能傳送到佇列中
    _, err := r.channel.QueueDeclare(
        r.QueueName,
        // 是否持久化
        false,
        // 是否為自動刪除
        false,
        // 是否具有排他性
        false,
        // 是否阻塞
        false,
        // 額外屬性
        nil,
    )
    if err != nil {
        fmt.Println(err)
    }

    // 2.傳送訊息到佇列中
    r.channel.Publish(
        r.Exchange,
        r.QueueName,
        // 如果為true, 會根據exchange型別和routkey規則,如果無法找到符合條件的佇列那麼會把傳送的訊息返回給傳送者
        false,
        // 如果為true, 當exchange傳送訊息到佇列後發現佇列上沒有繫結消費者,則會把訊息發還給傳送者
        false,
        amqp.Publishing{
            ContentType: "text/plain",
            Body:        []byte(message),
        },
    )
}

// ConsumeSimple 使用 goroutine 消費訊息
func (r *RabbitMQ) ConsumeSimple() {
    // 1. 申請佇列,如果佇列不存在會自動建立,如何存在則跳過建立
    // 保證佇列存在,訊息能傳送到佇列中
    _, err := r.channel.QueueDeclare(
        r.QueueName,
        // 是否持久化
        false,
        // 是否為自動刪除
        false,
        // 是否具有排他性
        false,
        // 是否阻塞
        false,
        // 額外屬性
        nil,
    )
    if err != nil {
        fmt.Println(err)
    }

    // 接收訊息
    msgs, err := r.channel.Consume(
        r.QueueName,
        // 用來區分多個消費者
        "",
        // 是否自動應答
        true,
        // 是否具有排他性
        false,
        // 如果設定為true,表示不能將同一個connection中傳送的訊息傳遞給這個connection中的消費者
        false,
        // 佇列消費是否阻塞
        false,
        nil,
    )

    if err != nil {
        fmt.Println(err)
    }

    forever := make(chan bool)
    // 啟用協和處理訊息
    go func() {
        for d := range msgs {
            // 實現我們要實現的邏輯函式
            log.Printf("Received a message: %s", d.Body)
            fmt.Println(d.Body)
        }
    }()
    log.Printf("[*] Waiting for message, To exit press CTRL+C")
    <-forever
}

2、建立消費檔案和生產檔案

  • 消費檔案 mainSimpleRecieve.go
package main

import "go-shop/RabbitMQ"

func main() {
    rabbitmq := RabbitMQ.NewRabbitMQSimple("imoocSimple")

    rabbitmq.ConsumeSimple()
}
  • 釋出檔案 mainSimplePublish.go
import (
    "fmt"
    "go-shop/RabbitMQ"
)

func main() {
    rabbitmq := RabbitMQ.NewRabbitMQSimple("imoocSimple")
    rabbitmq.PublishSimple("Hello goFrame!")
    fmt.Println("傳送成功")
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章