RabbitMQ学习| 青训营笔记

81 阅读4分钟

这是我参与「第五届青训营」笔记创作活动的第6天。

今天主要是对RabbitMQ进行了学习,主要学习了RabbitMQ的一些基本的操作:使用go语言调用了RabbitMQ的一些常用API,实现了生产者、消费者的demo。

RabbitMQ入门

今天使用的是RabbitMQ的最简单的工作模式,在这个工作模式中,生产者将消息发送到Queue中去,生产者将消息从Queue中取出来进行消费。

demo

实现一个简单的生产者模型:

func main() {
   conn, _ := amqp.Dial("amqp://admin:Qd20010701.@10.211.55.4:5672/")
   defer conn.Close()
   ch, _ := conn.Channel()
   defer ch.Close()
   argumentsMap := map[string]interface{}{}
   argumentsMap["x-max-length"] = 1
   argumentsMap["x-overflow"] = "reject-publish"
   q, err := ch.QueueDeclare(
      "message_current1", // name
      true,               // durable
      false,              // delete when unused
      false,              // exclusive
      false,              // no-wait
      argumentsMap,       // arguments
   )
   if err != nil {
      fmt.Println(err.Error())
   }
   body := "{"id":0,"to_id":1,"from_id":2,"content":"fgv","create_time":"2023-02-10 13:37:02"}"
   _ = ch.Publish(
      "",     // exchange
      q.Name, // routing key
      false,  // mandatory
      false,  // immediate
      amqp.Publishing{
         ContentType: "text/plain",
         Body:        []byte(body),
      })
}

实现一个简单的消费者模型:


type RespMessage struct {
   Id         int    `json:"id"`
   ToId       int    `json:"to_id"`
   FromId     int    `json:"from_id"`
   Content    string `json:"content"`
   CreateTime string `json:"create_time"`
}

func main() {
   conn, _ := amqp.Dial("amqp://admin:Qd20010701.@10.211.55.4:5672/")
   defer conn.Close()
   ch, _ := conn.Channel()
   defer ch.Close()
   argumentsMap := map[string]interface{}{}
   argumentsMap["x-max-length"] = 1
   argumentsMap["x-overflow"] = "reject-publish"
   q, _ := ch.QueueDeclare(
      "message_current1", // name
      true,               // durable
      false,              // delete when unused
      false,              // exclusive
      false,              // no-wait
      argumentsMap,       // arguments
   )
   msgs, _ := ch.Consume(
      q.Name, // queue
      "",     // consumer
      true,   // auto-ack
      false,  // exclusive
      false,  // no-local
      false,  // no-wait
      nil,    // args
   )
   messageList := []RespMessage{}
   message := RespMessage{}
   go func() {
      for d := range msgs {
         json.Unmarshal(d.Body, &message)
         messageList = append(messageList, message)
      }
   }()

}

注:

  1. 这里的x-max-length指的是声明队列的最大长度,x-overflow是当队列中消息满了以后,新消息的溢出策略,reject-publish是其中的一种策略:直接丢弃新消息。

  2. 队列在声明后才能被使用,如果声明的队列已经存在,并且属性完全相同,那么此次声明不会对原有队列产生任何影响,如果声明的队列属性与已存在的队列属性有差异,那么就会抛出{ Channel shutdown: channel error; protocol method: #method<channel.close>reply-code=406, reply-text…}

QueueDeclare参数的详细解释

  • Name:队列的名称
  • Durable:是否持久化(重启rabbitmq之后,队列是否还存在)
  • Exclusive:是否只被一个客户端连接使用,且当连接关闭后,删除队列
  • AutoDelete :是否自动删除(当最后一个消费者退订后即被删除)
  • Arguments:队列的其他属性参数,有如下可选项:

(1)x-message-ttl:消息的过期时间,单位:毫秒;

(2)x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;

(3)x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;

(4)x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;

(5)x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;

(6)x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;

(7)x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值

(8)x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,其他被忽略,false时消息循环分发给所有消费者(默认false)

(9)x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;

(10)x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;如果未设置,队列将保留内存缓存以尽可能快地传递消息;

(11)x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。

改变RabbitMQ对队列消息溢出的行为

RabbitMQ有两种对队列中消息溢出的策略可以通过对x-overflow的设置来实现,一种是默认,drop-head,即抛弃排在队列最前面的消息,另一种是拒绝发布,reject-publish,即丢弃最新发布的消息。

总结

经过今天的学习,对RabbitMQ的简单模式及常用参数基本掌握,并实现了一个小Demo。接下来还要继续深挖MQ。