这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
概念
消息队列是一种设计模式,用于在两个不同的应用程序之间传递消息。它是一种非常有用的工具,因为它可以帮助解决应用程序之间的耦合问题。通过消息队列,可以确保消息可以在应用程序之间被安全地传递,而不用担心应用程序之间的联系。
消息队列可以是任何类型的消息,例如字符串,数字,对象等。消息队列通常用于在不同的系统中进行通信,例如分布式系统,微服务等。它也可以用于在同一系统内进行通信,例如不同的应用程序模块之间的通信。
消息队列具有以下几个重要的特征:
- 异步:消息队列是异步的,因此消息可以在不同的时间传递。
- 顺序:消息在队列中以特定顺序传递。
- 可靠:消息队列具有可靠性,因此消息不会丢失。
- 无状态:消息队列是无状态的,因此不需要考虑消息是否已经被处理。
消息队列通常由以下几个组件组成:
- 生产者:生产者负责将消息放入队列。
- 消息队列:消息队列负责存储消息并维护消息的顺序。
- 消费者:消费者负责从队列中取出消息并对其进行处理。
有许多不同的消息队列实现可供选择,例如 RabbitMQ,Kafka,ActiveMQ 等。这些实现可以在本地环境或云环境中使用,并提供了丰富的特性,如高可用性,负载均衡等。
在使用消息队列时,有几个关键的概念需要考虑,如:
- 消息确认:消息确认是指消费者确认已经处理完消息。这是一个重要的特性,因为它可以确保消息不会丢失。
- 消息重试:消息重试是指在消息处理失败时,消息会重新放回队列以便再次尝试处理。
各种消息队列优缺点
- RabbitMQ:RabbitMQ 是一个开源的消息队列,支持 AMQP 协议。它提供了丰富的特性,如高可用性,负载均衡等。其优点是功能强大,支持多种协议,稳定性高。缺点是配置相对复杂,学习曲线较陡峭。
- Kafka:Kafka 是一个高性能的分布式消息队列,支持分区和复制。它具有高吞吐量,低延迟,高可用性的特点。其优点是性能高,适用于大规模数据处理场景。缺点是配置相对复杂,需要有一定的技术储备才能使用。
- ActiveMQ:ActiveMQ 是一个开源的消息队列,支持多种协议,如 JMS,STOMP 等。它提供了许多特性,如消息确认,消息重试等。其优点是易于使用,功能强大,社区活跃。缺点是性能不如 RabbitMQ 和 Kafka。
- Redis:Redis 是一个开源的内存数据库,也可以用作消息队列。它具有高速读写,低延迟的特点。其优点是性能高,易于使用。缺点是不支持分布式,不支持消息持久化。
Kafka在go的使用
docker部署Kafka
下面这个镜像集成了zookeeper和kafka aijishu.com/a/106000000… blog.csdn.net/weixin_4225… 连接不上解决方法: www.cnpython.com/java/668022
其中:
-d:表示容器在后台运行;--name kafka:为容器命名为kafka;-p 2181:2181:将容器中的2181端口映射到主机的2181端口;-p 9092:9092:将容器中的9092端口映射到主机的9092端口;--env ADVERTISED_HOST=<host_name>:指定Kafka集群的主机名,请替换为你的实际主机名;--env ADVERTISED_PORT=9092:指定Kafka集群的端口,默认为9092。
注意下面必须写主机IP,否则连接不上
# 1. 下载Kafka镜像:
docker pull spotify/kafka
# 2. 启动容器
docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=[主机IP] --env ADVERTISED_PORT=9092 spotify/kafka
配置
go get -u github.com/confluentinc/confluent-kafka-go/kafka
代码
工具类
package kafka_client
import (
"context"
"github.com/segmentio/kafka-go"
)
// KafkaClient 封装了kafka-go库中的生产者和消费者
type KafkaClient struct {
// producer 用于生产消息
producer *kafka.Writer
// consumer 用于消费消息
consumer *kafka.Reader
}
// NewKafkaClient 创建一个Kafka工具类
func NewKafkaClient(brokers []string, topic string) *KafkaClient {
kafkaClient := &KafkaClient{}
// 创建生产者
kafkaClient.producer = kafka.NewWriter(kafka.WriterConfig{
Brokers: brokers,
Topic: topic,
Balancer: &kafka.LeastBytes{},
})
// 创建消费者
kafkaClient.consumer = kafka.NewReader(kafka.ReaderConfig{
Brokers: brokers,
Topic: topic,
MinBytes: 10e3, // 10KB
MaxBytes: 10e6, // 10MB
})
return kafkaClient
}
// ProduceMessage 生产消息
func (k *KafkaClient) ProduceMessage(message string) error {
// 封装消息
kafkaMessage := kafka.Message{
Value: []byte(message),
}
// 发送消息
return k.producer.WriteMessages(context.Background(), kafkaMessage)
}
// ConsumeMessage 消费消息
func (k *KafkaClient) ConsumeMessage() (string, error) {
// 获取消息
m, err := k.consumer.FetchMessage(context.Background())
if err != nil {
return "", err
}
return string(m.Value), nil
}
// Close 关闭Kafka工具类,释放资源
func (k *KafkaClient) Close() {
k.producer.Close()
k.consumer.Close()
}