MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取队列中的消息。RabbitMQ是MQ的一种。RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。
1.创建RabbitMQ实例
package RabbitMQ import ( "fmt" "github.com/streadway/amqp" "log" ) const MQURL = "amqp://testuser:123456@127.0.0.1:5672/my_vhost" type RabbitMQ struct { conn *amqp.Connection channel *amqp.Channel //队列名称 QueueName string //交换机 Exchange string //key key string //连接信息 Mqurl string } //创建RabbitMQ结构体实例 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 } //断开channel和connection func (r *RabbitMQ) Destroy() { r.channel.Close() r.conn.Close() } //错误处理函数 func (r *RabbitMQ) failOnErr(err error, message string) { if err != nil { log.Fatalf("%s:%s", message, err) panic(fmt.Sprintf("%s,%s", message, err)) } }
2.Simple模式
//创建简单模式下RabbitMQ实例 func NewRabbitMQSimple(queueName string) *RabbitMQ { return NewRabbitMQ(queueName, "", "") } //简单模式下生产代码 func (r *RabbitMQ) PublishSimple(message string) { //1.申请队列,如果队列不存在会自动创建,如果存在则跳过创建 //保证队列存在,消息队列能发送到队列中 _, err := r.channel.QueueDeclare( r.QueueName, //是否持久化 false, //是否为自动删除 false, //是否具有排他性 false, //是否阻塞 false, //额外属性 nil, ) if err != nil { fmt.Println("QueueDeclare:", err) } //2.发送消息到队列中 err = r.channel.Publish( r.Exchange, r.QueueName, //如果为true,根据exchange类型和routekey规则,如果无法找到符合条件的队列那么会把发送的消息返回给发送者 false, //如果为true,当exchange发送消息队列到队列后发现队列上没有绑定消费者,则会把消息发还给发送者 false, amqp.Publishing{ ContentType: "text/plain", Body: []byte(message), }) if err != nil { fmt.Println("Publish:", err) } } //简单模式下消费代码 func (r *RabbitMQ) ConsumeSimple() { //1.申请队列,如果队列不存在会自动创建,如果存在则跳过创建 //保证队列存在,消息队列能发送到队列中 _, err := r.channel.QueueDeclare( r.QueueName, //是否持久化 false, //是否为自动删除 false, //是否具有排他性 false, //是否阻塞 false, //额外属性 nil) if err != nil { fmt.Println("QueueDeclare:", err) } //2.接受消息 msgs, err := r.channel.Consume( r.QueueName, //用来区分多个消费者 "", //是否自动应答 true, //是否具有排他性 false, //如果设置为true,表示不能将同一个connection中发送消息传递给这个connection中的消费者 false, //队列消费是否阻塞 false, nil) if err != nil { fmt.Println("Consume:", err) } forever := make(chan bool) //3.启用协程处理消息 go func() { for d := range msgs { //实现我们要处理的逻辑函数 log.Printf("Received a message:%s", d.Body) } }() log.Printf("[*] Waiting for messages,To exit press CTRL+C\n") <-forever }
简单模式publish
package main import ( "fmt" "go-rabbitmq/RabbitMQ" ) func main() { rabbitmq := RabbitMQ.NewRabbitMQSimple("testSimple") rabbitmq.PublishSimple("Hello test!") fmt.Println("发送成功!") }
简单模式recevie
package main import "go-rabbitmq/RabbitMQ" func main() { rabbitmq := RabbitMQ.NewRabbitMQSimple("testSimple") rabbitmq.ConsumeSimple() }
3.Work模式
work模式生产消费代码与simple模式相同
work模式publish
package main import ( "fmt" "go-rabbitmq/RabbitMQ" "strconv" "time" ) func main() { rabbitmq := RabbitMQ.NewRabbitMQSimple("testSimple") for i := 0; i <= 100; i++ { rabbitmq.PublishSimple("Hello test!" + strconv.Itoa(i)) time.Sleep(1 * time.Second) fmt.Println(i) } }
work模式receive1
package main import "go-rabbitmq/RabbitMQ" func main() { rabbitmq := RabbitMQ.NewRabbitMQSimple("testSimple") rabbitmq.ConsumeSimple() }
work模式receive2
package main import "go-rabbitmq/RabbitMQ" func main() { rabbitmq := RabbitMQ.NewRabbitMQSimple("testSimple") rabbitmq.ConsumeSimple() }