https://blog.csdn.net/z3551906947/article/details/140438121?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22140438121%22%2C%22source%22%3A%22z3551906947%22%7D
在上面的这篇总结中,主要是分析了mq到底是具备什么要素,redis中的stream为什么可以适应这些问题,接下来的代码主要也就是为了更好的去理清楚整个的逻辑,在代码中,会挑选一些比较重要,并且是关乎全局的去重点分析。
GitHub - XiChenServer/redisMq at redisMq
上面是我的git,里面有代码是去学习其他人了,但是我们主要的是要学习一下整体的思路,还有就是代码书写上存在的问题。
总概述
redis中使用stream实现mq(代码)
首先从整体的代码文件上面来分析到底使用到了什么,这些是怎么串联起来的。
- log
- log.go 主要的是整个消息队列启动之后,需要记录日志函数的封装
- redis 对与redis命令的封装
- config.go 在使用redis之后。需要对于redis有一些信息的配置
- redis.go 主要使用的redis命令封装
- redis_test.go
- test
- defer_test.go
- config.go 对于所编写的生产者,消费者队列的配置
- consumer.go 消费者
- dead_letter.go 死信队列
- go.mod
- producer.go 生产者
以上这些,就主要是大致的轮廓,现在主要是来分析一下代码的实现
redis
下面的是可以根据自己的需求去配置redis的数据
const (
// DefaultIdleTimeoutSeconds 默认连接池超过 10 秒释放连接
DefaultIdleTimeoutSeconds = 10
// DefaultMaxActive 默认最大激活连接数
DefaultMaxActive = 100
// DefaultMaxIdle 默认最大空闲连接数
DefaultMaxIdle = 20
)
// 对于封装的redis进行
type ClientOptions struct {
maxIdle int //最大空闲连接数
idleTimeoutSeconds int //最大空闲超时时间
maxActive int //最大激活连接数
wait bool //连接池等待模式
// 必填参数
// 下面就是普通平常时候对于redis的一些连接选项
network string
address string
password string
}
这里的是用来修复的,在很多时候都可以使用到,将redis的数据初始化到默认值的一次完美封装
// repairClient 修复 ClientOptions 中的无效值,设置为默认值
func repairClient(c *ClientOptions) {
if c.maxIdle < 0 {
c.maxIdle = DefaultMaxIdle
}
if c.idleTimeoutSeconds < 0 {
c.idleTimeoutSeconds = DefaultIdleTimeoutSeconds
}
if c.maxActive < 0 {
c.maxActive = DefaultMaxActive
}
}
需要注意的是,等待我们使用完一次redis的连接之后,将这个实例返回到pool里面,这个时候是不需要进行清除里面配置的,等下一次取出来进行使用的时候,是需要进行清理,恢复的。从下面的代码中,可以清楚的看到。
// NewClient 连接一个redis的客户端
func NewClient(network, address, password string, opts ...ClientOption) *Client {
c := Client{
opts: &ClientOptions{
network: network,
address: address,
password: password,
},
}
//对于其他的配置
for _, opt := range opts {
opt(c.opts)
}
//修复中间的无效值
repairClient(c.opts)
//上面的都是进行配置,这里获取
pool := c.getRedisPool()
return &Client{
pool: pool,
}
}
这里是获取实例,在这里可以看到,是通过配置好的数据,获取连接。然后完成后面的整体数据信息
// 创建并返回一个新的 redis.Pool 实例
func (c *Client) getRedisPool() *redis.Pool {
return &redis.Pool{
MaxIdle: c.opts.maxIdle,
IdleTimeout: time.Duration(c.opts.idleTimeoutSeconds) * time.Second,
Dial: func() (redis.Conn, error) {
c, err := c.getRedisConn()
if err != nil {
return nil, err
}
return c