我们一起来学RabbitMQ 二:RabbiMQ 的 6 种模式的基本应用

本文详细介绍了RabbitMQ的六种工作模式,包括single、work、publish/subscribe、routing、topic和rpc模式,结合代码示例阐述了每种模式的特点和应用场景,帮助读者理解如何在实际开发中应用RabbitMQ。
摘要由CSDN通过智能技术生成

我们一起来学RabbitMQ 二:RabbiMQ 的 6 种模式的基本应用

嗨,大家好,我是小魔童哪吒,咱们从今天开始进入开源组件的学习,一边学习一边总结一边分享

文章提纲如下:

  • RabbitMQ 成员组成
  • RabbitMQ 的六种工作模式编码

RabbitMQ 成员组成

  • 生产者 producer
  • 消费者 consumer
  • 交换机 exchange

用于接受、分配消息

  • 消息 message
  • 队列 queue

用于存储生产者的消息

  • 信道 channel AMQP

消息推送使用的通道

  • 连接 connections

生成者或者消费者与Rabbit 建立的TCP 连接

  • 路由键 routingKey

用于把生成者的数据分配到交换器上

  • 绑定键 BindingKey

用于把交换器的消息绑定到队列上

  • 连接管理器 ConnectionFactory

应用程序与 Rabbit 之间建立连接的管理器,程序代码中使用

RabbitMQ 的六种工作模式编码

single 模式

  • 消息产生者将消息放入队列
  • 消息的消费者监听消息队列,如果队列中有消息就消费掉

目录如下:

.
├── consumer.go
├── go.mod
├── go.sum
├── main.go
└── xmtmq
    └── xmtmq.go

实际编码如下:

每种模式的编码思路如下:

生产者 / 消费者

  • 连接 RabbitMQ 的 server
  • 初始化连接 connection
  • 初始化通道 channel
  • 初始化交换机 exchange
  • 初始化队列 queue
  • 使用路由key,绑定队列 bind , key
  • 生产消息 / 消费消息 produce , consume

消息xmtmq.go

package xmtmq

import (
   "github.com/streadway/amqp"
   "log"
)
// single 模式
// 定义 RabbitMQ 的数据结构
// go get github.com/streadway/amqp

type RabbitMQ struct {
   
   conn      *amqp.Connection // 连接
   channel   *amqp.Channel    // 通道
   QueueName string           // 队列名
   Exchange  string           // 交换机
   Key       string           // 路由键
   MQUrl     string           // MQ的虚拟机地址
}

// New 一个 RabbitMQ
func NewRabbitMQ(rbt *RabbitMQ) {
   
   if rbt == nil || rbt.QueueName == ""  || rbt.MQUrl == "" {
   
      log.Panic("please check QueueName,Exchange,MQUrl ...")
   }

   conn, err := amqp.Dial(rbt.MQUrl)
   if err != nil {
   
      log.Panicf("amqp.Dial error : %v", err)
   }
   rbt.conn = conn

   channel, err := rbt.conn.Channel()
   if err != nil {
   
      log.Panicf("rbt.conn.Channel error : %v", err)
   }
   rbt.channel = channel
}


func RabbitMQFree(rbt *RabbitMQ){
   
   if rbt == nil{
   
      log.Printf("rbt is nil,free failed")
      return
   }
   rbt.channel.Close()
   rbt.conn.Close()
}
func (rbt *RabbitMQ) Init() {
   
   // 申请队列
   _, err := rbt.channel.QueueDeclare(
      rbt.QueueName, // 队列名
      true,          // 是否持久化
      false,         // 是否自动删除
      false,         // 是否排他
      false,         // 是否阻塞
      nil,           // 其他参数
   )
   if err != nil {
   
      log.Printf("rbt.channel.QueueDeclare error : %v", err)
      return
   }
}


// 生产消息

func (rbt *RabbitMQ) Produce(data []byte) {
   

   // 向队列中加入数据
   err := rbt.channel.Publish(
      rbt.Exchange,        // 交换机
      rbt.QueueName,       // 队列名
      false,    // 若为true,根据自身exchange类型和routekey规则无法找到符合条件的队列会把消息返还给发送者
      false,    // 若为true,当exchange发送消息到队列后发现队列上没有消费者,则会把消息返还给发送者
      amqp.Publishing{
   
         ContentType: "text/plain",
         Body:        data,
      },
   )
   if err != nil {
   
      log.Printf("rbt.channel.Publish error : %v", err)
      return
   }
   return
}

// 消费消息
func (rbt *RabbitMQ) Consume() {
   

   // 消费数据
   msg, err := rbt.channel.Consume(
      rbt.QueueName,    // 队列名
      "xmt",    // 消费者的名字
      true,     // 是否自动应答
      false,    // 是否排他
      false,    // 若为true,表示 不能将同一个Conenction中生产者发送的消息传递给这个Connection中 的消费者
      false,    // 是否阻塞
      nil,         // 其他属性
   )

   if err != nil {
   
      log.Printf("rbt.channel.Consume error : %v", err)
      return
   }

   for data := range msg {
   
      log.Printf("received data is %v", string(data.Body))
   }

}

main.go

package main

import (
   "fmt"
   "log"
   "time"
   "xmt/xmtmq"
)

/*
RabbimtMQ single 模式 案例
应用场景:简单消息队列的使用,一个生产者一个消费者
生产消息
*/

func main() {
   
	// 设置日志
   log.SetFlags(log.Llongfile | log.Ltime | log.Ldate)

   rbt := &xmtmq.RabbitMQ{
   
      QueueName: "xmtqueue",
      MQUrl:     "amqp://guest:guest@127.0.0.1:5672/xmtmq",
   }
    
   xmtmq.NewRabbitMQ(rbt)

   var index = 0

   for {
   
       // 生产消息
      rbt.Produce([]byte(fmt.Sprintf("hello wolrd %d ", index)))
      log.Println("发送成功 ", index)
      index++
      time.Sleep(1 * time.Second)
   }

}

consumer.go

package main

import (
   "log"
   "xmt/xmtmq"
)

func main() {
   

   log.SetFlags(log.Llongfile | log.Ltime | log.Ldate)

   rbt := &xmtmq.RabbitMQ{
   
      QueueName: "xmtqueue",
      MQUrl:     "amqp://guest:guest@127.0.0.1:5672/xmtmq",
   }

   xmtmq.NewRabbitMQ(rbt)
   rbt.Consume()
}

运行的时候,打开2个终端

终端1:go run main.go

终端2:go run consumer.go

work 模式

多个消费端消费同一个队列中的消息,队列采用轮询的方式将消息是平均发送给消费者,此处的资源是竞争关系

当生产者生产消息的速度大于消费者消费的速度,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值