Golang连接rabbitmq导致channel不断增加的解决方案

2023-08-31 12:47:24 浏览数 (2)

背景

项目中所有的智能终端产生的事件都会通过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
}

致此系统运行良好,再无事件丢失情况发生

0 人点赞