package rabbitmq import ( "encoding/json" "fmt" "github.com/streadway/amqp" "log" ) // RabbitMQ 声明队列类型 type RabbitMQ struct { conn *amqp.Connection channel *amqp.Channel Name string exchange string } // Connect 连接服务器 func Connect(s string) *RabbitMQ { //连接rabbitmq conn, e := amqp.Dial(s) failOnError(e, "连接Rabbitmq服务器失败!") ch, e := conn.Channel() failOnError(e, "无法打开频道!") mq := new(RabbitMQ) mq.conn = conn mq.channel = ch return mq } //New 初始化单个消息队列 //s: rabbitmq服务器的链接 name:队列名字 func New(s string, name string) *RabbitMQ { //连接rabbitmq conn, e := amqp.Dial(s) failOnError(e, "连接Rabbitmq服务器失败!") ch, e := conn.Channel() failOnError(e, "无法打开频道!") q, e := ch.QueueDeclare( name, //队列名 false, //是否开启持久化 false, //不使用时删除 false, //排他 false, //不等待 nil, //参数 ) failOnError(e, "初始化队列失败!") mq := new(RabbitMQ) mq.channel = ch mq.conn = conn mq.Name = q.Name return mq } // QueueDeclare 声明交换机 func (q *RabbitMQ) QueueDeclare(queue string) { _, e := q.channel.QueueDeclare(queue, false, false, false, false, nil) failOnError(e, "声明交换机!") } // QueueDelete 删除交换机 func (q *RabbitMQ) QueueDelete(queue string) { _, e := q.channel.QueueDelete(queue, false, true, false) failOnError(e, "删除队列失败!") } // Qos 配置队列参数 func (q *RabbitMQ) Qos(prefetchCount int) { e := q.channel.Qos(prefetchCount, 0, false) failOnError(e, "无法设置QoS") } //配置交换机参数 // NewExchange 初始化交换机 //s:rabbitmq服务器的链接,name:交换机名字,typename:交换机类型 func NewExchange(s string, name string, typename string) { //连接rabbitmq conn, e := amqp.Dial(s) failOnError(e, "连接Rabbitmq服务器失败!") ch, e := conn.Channel() failOnError(e, "无法打开频道!") e = ch.ExchangeDeclare( name, // name typename, // type true, // durable false, // auto-deleted false, // internal false, // no-wait nil, // arguments ) failOnError(e, "初始化交换机失败!") } // ExchangeDelete 删除交换机 func (q *RabbitMQ) ExchangeDelete(exchange string) { e := q.channel.ExchangeDelete(exchange, false, true) failOnError(e, "绑定队列失败!") } // Bind 绑定消息队列到哪个exchange func (q *RabbitMQ) Bind(exchange string, key string) { e := q.channel.QueueBind( q.Name, key, exchange, false, nil, ) failOnError(e, "绑定队列失败!") q.exchange = exchange } //Send 向消息队列发送消息 //可以往某个消息队列发送消息 func (q *RabbitMQ) Send(queue string, body interface{}) { str, e := json.Marshal(body) failOnError(e, "消息序列化失败!") e = q.channel.Publish( "", //交换 queue, //路由键 false, //必填 false, //立即 amqp.Publishing{ ReplyTo: q.Name, Body: []byte(str), }) msg := "向队列:" + q.Name + "发送消息失败!" failOnError(e, msg) } // Publish 向exchange发送消息 // 可以往某个exchange发送消息 func (q *RabbitMQ) Publish(exchange string, body interface{}, key string) { str, e := json.Marshal(body) failOnError(e, "消息序列化失败!") e = q.channel.Publish( exchange, key, false, false, amqp.Publishing{ReplyTo: q.Name, Body: []byte(str)}, ) failOnError(e, "向路由发送消息失败!") } // Consume 接收某个消息队列的消息 func (q *RabbitMQ) Consume() <-chan amqp.Delivery { c, e := q.channel.Consume( q.Name, // 指定从哪个队列中接收消息 "", // 用来区分多个消费者 false, // 是否自动应答 false, // 是否独有 false, // 如果设置为true,表示不能将同一个connection中发送的消息传递给这个connection中的消费者 false, // 列是否阻塞 nil, ) failOnError(e, "接收消息失败!") return c } //拉取某个消息队列的消息 func (q *RabbitMQ) Get() (messages amqp.Delivery, ok bool, err error) { messages, ok, err = q.channel.Get(q.Name, false) failOnError(err, "拉取消息失败!") return } // 关闭信道 func (q *RabbitMQ) CloseChannel() { q.channel.Close() } // 关闭连接 func (q *RabbitMQ) CloseConn() { q.conn.Close() } // 销毁(断开channel和connection) func (q *RabbitMQ) Destroy() { q.channel.Close() //关闭信道资源 q.conn.Close() //关闭链接资源 } //错误处理函数 func failOnError(err error, msg string) { if err != nil { log.Fatalf("%s: %s", msg, err) panic(fmt.Sprintf("%s:%s", msg, err)) } }