golang基础:go操作redis,操作rabbitmq | 青训营笔记

377 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第8篇笔记;

整合redis相关操作

首先下载并导入相关依赖

首先下载第三方开源redis库:

go get github.com/garyburd/redigo/redis

导入:"github.com/garyburd/redigo/redis" 创建链接:

c, err := redis.Dial("tcp", "124.70.84.192:6380", redis.DialPassword("12345ssdlh"))
if err != nil {
   fmt.Println(err)
   return
}
//c即为链接
...

参数3用于进行一些普通的redis设置,如选择几号redis库,或者填写redis密码等,如下部分源码:

image.png

基本操作:

例如:操作set数据类型

defer c.Close()
//插入set类型值
_, err = c.Do("sadd", "1526676", "100", "ssw", "245", "109")
if err != nil {
   fmt.Println(err)
   return
}
//get得到set类型值
result, err := redis.Strings(c.Do("smembers", "1526676"))
//redis.Strings(...):redis对查询到的值进行相应的转换操作,有同样功能的还有redis.Float64s(),redis.Ints(),redis.Int()等等
if err != nil {
   fmt.Println(err)
   return
}

对于redis的操作都封装在了Do方法内,只要懂得一些基础的redis命令就可操作,还是非常具有灵活性的;其中Do方法第一个参数填写操作名值,之后的参数根据具体操作而调整;

其他数据类型参照以上,依此类推;

设置过期时间

同样也是用.Do()方法进行操作的,直接上代码:

c.Do("expire", "1526676", 30) //设置key为1526676的值30s后过期
r, err := redis.Int(c.Do("ttl", "1526676"))
fmt.Println("还有" + strconv.Itoa(r) + "秒该值过期")
//strconv.Itoa(r)将int类型转换为string

redis连接池

同mysql一样,进行连接最好还是用连接池,具体实现如下:

var redispool *redis.Pool
func init() {
   redispool = &redis.Pool{
      MaxIdle:     10,  //设置最初连接数量
      MaxActive:   0,   //连接池最大连接数量,不确定用0(0表示按需分配)
      IdleTimeout: 300, //超时时间,单位秒
      Dial: func() (redis.Conn, error) { //配置要连接的数据库
         return redis.Dial("tcp", "124.70.84.192:6380", redis.DialPassword("12345ssdlh"))
      },
   }
}
func main() {
   c := redispool.Get() //从连接池获取一个连接
   defer c.Close()
   results, err := c.Do("sadd", "front", "123", "234", "278")
   if err != nil {
      fmt.Println(err)
      return
   }
   fmt.Println(results)
}

操作rabbitmq

RabbitMQ的基本结构:

image.png 组成部分说明:

  1. Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue
  2. Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。
  3. Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消息队列
  4. Producer:消息生产者,即生产方客户端,生产方客户端将消息发送
  5. Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。 简单队列示例:
package main

import (
   "fmt"
   "github.com/streadway/amqp"
)

//连接信息
//格式“amqp://用户名:密码@ip:端口/路径”
const MQURL = "amqp://root:root@124.70.84.192:5672"

//构建rabbitmq结构体
type RabbitMQ struct {
   conn    *amqp.Connection
   channel *amqp.Channel
   //队列名称
   QueryName string
   //交换机名称
   Exchange string
   Key      string
   mqurl    string
}

//创建rabbit结构体实例
func NewRabbitMQ(queueName string, exchange string, key string) *RabbitMQ {
   return &RabbitMQ{QueryName: queueName, Exchange: exchange, Key: key}
}

//断开channel和connection
func (r *RabbitMQ) Destory() {
   r.channel.Close()
   r.conn.Channel()
}

//创建简单模式下RabbitMQ实例
func NewRabbitMQSimple(queueName string) *RabbitMQ {
   //创建Rabbit实例
   rabbitmq := NewRabbitMQ(queueName, "", "")
   var err error
   //获取连接,并将连接赋值到rabbit实例中
   rabbitmq.conn, err = amqp.Dial(MQURL)
   if err != nil {
      fmt.Print("获取连接出错")
      fmt.Println(err)
      return nil
   }
   //获取channel,并将连接赋值到rabbit实例中
   rabbitmq.channel, err = rabbitmq.conn.Channel()
   if err != nil {
      fmt.Print("获取channel失败")
      fmt.Println(err)
      return nil
   }
   return rabbitmq
}

//直接模式队列生产
func (r *RabbitMQ) PublishSimple(message string) {
   //申请队列,如果存在则跳过,不存在则创建
   _, err := r.channel.QueueDeclare(
      r.QueryName,
      false, //是否持久化
      false, //是否自动删除
      false, //是否具有排他性
      false, //是否阻塞处理
      nil,   //额外属性
   )
   if err != nil {
      fmt.Println(err)
      return
   }
   //调用channel发送消息到队列中
   r.channel.Publish(
      r.Exchange,
      r.QueryName,
      false,
      //如果为true,根据自身exchange类型和routekey规则
      //无法找到符合条件的队列会把消息返还给发送者
      false,
      //如果为true,当exchange发送消息到队列后发现队列上没有消费者,则会把消息返还给发送者
      amqp.Publishing{
         ContentEncoding: "text/plain",
         Body:            []byte(message),
      })
}

//simple模式消费者
func (r *RabbitMQ) ConsumerSimple() {
   //申请队列,如果存在则跳过,不存在则创建
   q, err := r.channel.QueueDeclare( //返回1个Queue
      r.QueryName,
      false, //是否持久化
      false, //是否自动删除
      false, //是否具有排他性
      false, //是否阻塞处理
      nil,   //额外属性
   )
   if err != nil {
      fmt.Println(err)
      return
   }
   //接收消息
   message, err := r.channel.Consume(
      q.Name, //指定队列名
      "",     //consumer string
      true,   //是否自动应答
      false,  //是否独有
      false,  //设置为true,表示不能将同一个Conenction中生产者发送的消息传递给这个Connection中的消费者
      false,  //列是否阻塞
      nil,    //其他参数
   )
   if err != nil {
      fmt.Println(err)
      return
   }
   for d := range message {
      fmt.Printf("消息是:%s", d.Body)
   }
}

//主程序测试发送
func main() {
   rabbitmq := NewRabbitMQSimple("apple")
   rabbitmq.PublishSimple("hello,boy")
   fmt.Println("已发送")
}

主程序测试接收:

//主程序测试消费者接收消息
func main() {
   rabbitmq := NewRabbitMQSimple("apple")
   rabbitmq.ConsumerSimple()
}