项目MQ设计 | 青训营笔记

71 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 10 天

本文简单介绍一下抖音极简版项目中消息队列的使用思路

在之前的redis设计中,对于流媒体软件普遍的分布式操作,如点赞、关注、评论,使用了redis作为内存来存储喜欢列表、关注列表、评论列表等,而对于多用户的并发操作等,可以使用消息队列来优化服务性能

对于已经构建的redis组件,其本身的高并发特点作为缓存已经足够,而对于最终需要写入Mysql数据库的内容,使用消息队列作为中间件,将对数据库修改的分布式操作作为消息生产方,最终执行sql语句类别作为消息消费方

项目使用rabbitMQ作为消息队列服务,消息生产分为点赞队列、评论队列、关注队列;消息消费分为点赞/取消点赞、评论/删除评论、关注/取消关注这几种方式

以下以点赞为例:

// NewLiketMQ 获取点赞队列。
func NewLiketMQ(queueName string) *LikeMQ {
	likeMQ := &LikeMQ{
		RabbitMQ:  *Rmq,
		queueName: queueName,
	}
	cha, err := likeMQ.conn.Channel()
	likeMQ.channel = cha
	Rmq.failOnErr(err, "channel failed")
	return likeMQ
}

// 点赞发布操作的发布配置。
func (l *LikeMQ) Publish(message string) {
	_, err := l.channel.QueueDeclare(l.queueName,false,false,false,false,nil,)
	if err != nil {
		panic(err)
	}
	err1 := l.channel.Publish(
		l.exchange,
		l.queueName,
		false,
		false,
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        []byte(message),
		})
	if err1 != nil {
		panic(err)
	}

}

// 点赞关系的消费逻辑。
func (l *LikeMQ) Consumer() {

	_, err := l.channel.QueueDeclare(l.queueName, false, false, false, false, nil)
	if err != nil {
		panic(err)
	}
        //接收消息
	messages, err1 := l.channel.Consume(l.queueName,"",true,false,false,false,nil,)
	if err1 != nil {
		panic(err1)
	}

	forever := make(chan bool)
	switch l.queueName {
	case "like_add":
		//点赞消费队列
		go l.consumerLikeAdd(messages)
	case "like_del":
		//取消赞消费队列
		go l.consumerLikeDel(messages)
	}
	log.Printf("[*] Waiting for messagees,To exit press CTRL+C")
        <-forever

}

其中,可通过修改channel参数实现持久化、阻塞异常、排他性、自动应答或者保证消息消费一对一关系等功能,具体功能仍在完善中

对于消息消费后的操作,需要继续构建接口通过gorm对mysql数据库进行操作