一、消息系统
1. 消息队列
消息
Message:网络中的两台计算机或者两个通讯设备之间传递的数据,如:文本、音频、视频等
队列Queue:一种特殊的线性表,特殊之处在于它只允许在首部删除元素(队首),在尾部添加元素(队尾)。
消息队列MQ:保存消息的队列,是消息在传输过程中的容器。主要提供生产和消费接口供外部调用,进行数据的存储和获取。
2. MQ分类
主要分为两类:点对点(PeertoPeer)、发布/订阅(Publish/Subscribe)
共同点
:消息生产者
(Producer)
生产消息发送到队列中,然后消息消费者
(Consumer)
从队列中读取并消费消 息。
不同点:
点对点
- 组成:消息队列(Queue)、发送者(Sender)、接收者(Receiver)
- 一个生产者生产的消息只能有一个消费者,消息一旦被消费,消息就不在消息队列中了,如:打电话 即发送到消息队列的消息能且只能被一个接收者接收
发布
/订阅
- 组成:消息队列(Queue)、发布者(Publisher)、订阅者(Subscriber)、主题(Topic)
- 每个消息可以有多个消费者,彼此互不影响,如:我发布一个微博,关注我的人都能看到
- 即发布到消息队列的消息能被多个接收者(订阅者)接收
3. 常见消息系统
- ActiveMQ:历史悠久,实现了JMS(Java Message Service)规范,支持性较好,性能相对不高
- RabbitMQ:可靠性高、安全
- Kafka:分布式、高性能、跨语言
- RocketMQ:阿里开源的消息中间件,纯Java实现
二、Kafka简介
1.介绍
Kafka是一个分布式的发布/订阅消息系统,最初由LinkedIn(领英)公司发布,使用Scala语言编写,后成为Apache的顶级项目。
主要用于
处理活跃的数据,如登录、浏览、点击、分享、喜欢等用户行为产生的数据。
特点
- 高吞吐量:可以满足每秒百万级别消息的生产和消费
- 持久性:有一套完善的消息存储机制,确保数据的高效安全的持久化
- 分布式:基于分布式的扩展和容错机制:Kafak的数据会复制到多台服务器上,当某一天发生故障失效时,生产者和消费者转而使用其它的机器。
2.架构
![](https://i-blog.csdnimg.cn/blog_migrate/e022d89ececc70a7d62295b8d824780c.png)
3.组成
- Broker:kafka集群中包含多个kafka服务节点,每一个kafka服务节点就称为一个broker
- Topic:主题,用来存储不同类别的消息(Kafka消息数据是存储在硬盘上的)
- Partition:分区,每个Topic包含一个或多个Partition,在创建Topic时指定包含的Partition数量(目的是为了进行分布式存储)
- Replication:副本,每个分区可以有多个副本,分布在不同的broker上,会选出一个副本作为Leader,所有的读写请求都会通过Leader完成,Follower只负责备份数据。所有的Follower会自动地从Leader中复制数据,当Leader宕机后,会从Follower中选出一个新的Leader继续提供服务,实现故障自动转移
- Message:消息,是通信的基本单位,每个消息都属于一个Partition
- Producer:消息的生产者,向Kafka的一个topic发布消息
- Consumer:消息的消费者,订阅topic并读取其发布的消息
- Consumer Group:每个Consumer属于一个特定的Consumer Group,多个Consumer可以属于同一个Consumer Group中
- Zookeeper:协调kafka的正常运行,Kafka将元数据信息保存在Zookeeper中,但发送给Topic本身的消息数据并不存储在ZK中,而是存储在磁盘文件中。
4.SpringBoot集成Kafka
SpringBoot提供了一个名为spring-kafka的strater用于在Spring项目里快速集成kafka
用法
(1)创建SpringBoot项目:勾选Spring Web Strater和Spring for Apache Kafka
(2)配置kafka,编辑application.yml
spring:
kafka:
bootstrap-servers: 192.168.7.40:9091,192.168.7.40:9092,192.168.7.40:9093
producer:
batch-size:65535
buffer-memory:524288
#key/value的序列化
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer:org.apache.kafka.common.serialization.StringSerializer
consumer:
# 指定一个默认的组名
group-id: test
# key/value的反序列化
key-deserializer:org.apache.kafka.common.serialization.StringDeserializer
valuede-serializer:org.apache.kafka.common.serialization.StringDeserializer
(3)创建生产者
@RestController
public class KafkaProducer{
@Autowired
private KafkaTemplate template;
@RequestMapping("/sendMsg")
public String sendMsg(String topic, String message){
template.send(topic, message);
return "success";
}
}
(4)创建消费者
@Component
public class KafkaConsumer{
@KafkaListener(topic={"hello", "world"})
public void listen(ConsumerRecord record){
System.out.println(record.topic() + "," + record.value());
}
}
(5)测试
访问:http://localhost:8080/sendMsg?topic =hello&message=aaaa