go语言实现消息队列 | 青训营笔记

274 阅读2分钟

1. 简介

今天尝试用最近新学的go语言实现一个基础的消息队列

在这个例子中,创建了一个名为MessageQueue的结构体,其中包含了一个用于存储消息的通道(messages)和一个用于停止队列的信号通道(done)。

Enqueue方法用于将消息放入队列中,而Dequeue方法是一个无限循环,从队列中读取消息并进行处理。通过select语句,它可以同时处理来自messages通道和done通道的消息,以实现对消息的消费和队列的停止。

main函数中,创建了一个MessageQueue实例,并通过两个协程模拟了生产者和消费者的行为。生产者每隔一秒向队列中放入一个消息,消费者从队列中读取消息并进行处理。等待一段时间后,停止消息队列。

不过这只是一个简单的示例,用于演示如何使用Go语言实现一个基本的消息队列。实际使用中,可能需要考虑更多的功能和性能优化,如消息持久化、并发处理等。

通过这个实现,我对于go语法以及消息队列有了更加深刻的认识。

2. 代码

package main

import (
	"fmt"
	"time"
)

// MessageQueue 表示一个消息队列。
type MessageQueue struct {
	messages chan string // 存储消息的通道
	done     chan bool   // 用于标识何时停止消费消息的通道
}

// NewMessageQueue 创建一个新的 MessageQueue 实例。
func NewMessageQueue() *MessageQueue {
	return &MessageQueue{
		messages: make(chan string), // 初始化消息通道
		done:     make(chan bool),   // 初始化完成通道
	}
}

// Enqueue 将消息添加到消息队列。
func (mq *MessageQueue) Enqueue(message string) {
	mq.messages <- message // 将消息添加到消息通道
}

// Dequeue 从消息队列中消费消息。
func (mq *MessageQueue) Dequeue() {
	for {
		select {
		case message := <-mq.messages:
			fmt.Println("Dequeued:", message)
		case <-mq.done:
			return
		}
	}
}

// Stop 停止消息队列的消费。
func (mq *MessageQueue) Stop() {
	mq.done <- true // 发送停止信号到完成通道
}

func main() {
	messageQueue := NewMessageQueue()

	// Producer 生产者
	go func() {
		for i := 1; i <= 10; i++ {
			message := fmt.Sprintf("Message %d", i)
			messageQueue.Enqueue(message)
			fmt.Println("Enqueued:", message)
			time.Sleep(time.Second)
		}
	}()

	// Consumer 消费者
	go messageQueue.Dequeue()

	// 等待一段时间以允许消息被消费
	time.Sleep(5 * time.Second)

	// 停止消息队列
	messageQueue.Stop()
}