背景
项目中所有的智能终端产生的事件都会通过rabbitmq进行推送,项目运行初期并未发现事件丢失情况,但运行一段时间,就会出现事件无法推送,经排查,发现是由rabbitmq的channel超过系统最大限制引起的。
代码片段
代码语言:javascript复制// 创建mq服务
// getCh提供发送和订阅所需的channel
func (q *Mq) getCh(ex, extype string) *amqp.Channel {
ch, err := q.Conn.Channel()
if err != nil {
fmt.Println("创建channel失败", err)
}
// defer ch.Close()
err = ch.ExchangeDeclare(
ex,
extype,
true,
false,
false,
false,
nil,
)
if err != nil {
fmt.Println("创建Exchange失败", err)
}
return ch
}
getCh会不断创建新的连接,导致超过系统限制。直觉告诉我们,ch.Close即可,但是这会带来系统开销。我的解决方案是,创成一个sync.Map,将channel存放在内存中,这样可以不必重复创建channel,最大程度复用channel.
优化代码
代码语言:javascript复制impore ("sync")
var channelMap sync.Map
func (q *Mq) getCh(ex, extype string) *amqp.Channel {
// 增加代码 1
if c,ok:=channelMap.Load(Exchange);ok && c!=nil{
return c.(*amqp.Channel)
}
ch, err := q.Conn.Channel()
if err != nil {
fmt.Println("创建channel失败", err)
}
// defer ch.Close()
err = ch.ExchangeDeclare(
ex,
extype,
true,
false,
false,
false,
nil,
)
if err != nil {
fmt.Println("创建Exchange失败", err)
}
// 增加代码 2
channelMap.Store(Exchange,ch)
return ch
}
致此系统运行良好,再无事件丢失情况发生