消息队列是什么?
消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式,软件的贮列用来处理一系列的输入,通常是来自用户。
消息队列提供了异步的通信协议,每一个贮列中的纪录包含详细说明的数据,包含发生的时间,输入设备的种类,以及特定的输入参数,也就是说:消息的发送者和接收者不需要同时与消息队列交互。消息会保存在队列中,直到接收者取回它。
“消息”是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串;也可以更复杂,可能包含嵌入对象。
消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
目前主流的消息队列技术
Kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色
RocketMQ: 低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广
Pulsar: 是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体.采用存算分离的架构设计
BMO:和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群
使用消息队列的流程
首先,需要创建集群,之后需要新增Topic,之后编写生产者逻辑,之后编写消费者逻辑
一些可以帮助Kafka提高吞吐或者稳定性的功能
Producer:批量发送、数据压缩
Broker: 顺序写,消息索引,零拷贝
Consumer: Rebalance
消息队列小实践
package main
import (
"time"
)
// MessageQueue define the interface for the message queue.
type MessageQueue interface {
// Send the message into the MessageQueue.
Send(message interface{})
// Pull the messages with the given size and timeout.
// size indicates the maximum number of messages pulled at one time
// timeout indicates the timeout when pulled the messages
// So, the number of messages returned depends on the maximum number of
// messages that can be pulled during the timeout period,
// which must be less than or equal to the given size.
Pull(size int, timeout time.Duration) []interface{}
// Size the current number of messages in MessageQueue.
Size() int
// Capacity the maximum number of messages in MessageQueue.
Capacity() int
}
type MyMessageQueue struct {
queue chan interface{}
capacity int
}
func (this *MyMessageQueue) Send(message interface{}) {
select {
case this.queue <- message:
default:
}
}
func (this *MyMessageQueue) Pull(size int, timeout time.Duration) []interface{} {
ret := make([]interface{}, 0)
for i := 0; i < size; i++ {
select {
case msg := <-this.queue:
ret = append(ret, msg)
case <-time.After(timeout):
return ret
}
}
return ret
}
func (this *MyMessageQueue) Size() int {
return len(this.queue)
}
func (this *MyMessageQueue) Capacity() int {
return this.capacity
}
func NewMessageQueue(capacity int) MessageQueue {
var mq MessageQueue
mq = &MyMessageQueue{
queue: make(chan interface{}, capacity),
capacity: capacity,
}
return mq
}