一、阻塞队列
BlockingQueue接口
- 解决线程通信的问题。
- 阻塞方法:put、take。
生产者消费者模式
- 生产者:产生数据的线程。
- 消费者:使用数据的线程。
实现类
- ArrayBlockingQueue
- LinkedBlockingQueue
- PriorityBlockingQueue
- SynchronousQueue
- DelayQueue
阻塞队列测试:
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class BlockingQueueTest {
public static void main(String[] args) {
BlockingQueue<Integer> queue = new LinkedBlockingDeque<>(10);
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}
// 消费者线程
class Consumer implements Runnable {
// 阻塞队列
private BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while(true){
Thread.sleep(new Random().nextInt(1000));
queue.take(); // 将数据从队列中取出,队列空时该线程阻塞
System.out.println(Thread.currentThread().getName()+"消费了:" + queue.size());
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 生产者线程
class Producer implements Runnable{
private BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> queue){
this.queue = queue;
}
@Override
public void run() {
try {
for (int i = 0; i < 100; i++) {
Thread.sleep(20); // 睡眠20ms
queue.put(i); // 将数据存入队列中,队列满时该线程阻塞
System.out.println(Thread.currentThread().getName()+"生产了:" + queue.size());
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
二、Kafka入门
Kafka简介
Kafka是一个分布式的流媒体平台。
应用:消息系统、日志收集、用户行为追踪、流式处理。
Kafka特点
高吞吐量、消息持久化、高可靠性、高扩展性。
Kafka术语解释
- Broker:Kafka的服务器
- Zookeeper:管理集群,Kafka中内置Zookeeper
- Topic:点对点模式中每个消费者拿到的消息都不同,发布订阅模式中消费者可能拿到同一份消息。Kafka采用发布订阅模式,生产者把消息发布到的空间(位置)就叫Topic
- Partition:是对Topic位置的分区,如下图:
- Offset:就是消息在分区中的索引
- Leader Replica:主副本,可以处理请求
- Follower Replica:从副本,只是用作备份。主副本宕机后,会从从副本选出新的主副本
三、Spring整合Kafka
引入依赖spring-kafka
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.5.0.RELEASE</version>
</dependency>
配置Kafka
配置server、consumer
application.properties:
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=test-consumer-group
# 是否自动提交
spring.kafka.consumer.enable-auto-commit=true
# 自动提交的频率3000ms
spring.kafka.consumer.auto-commit-interval=3000
访问Kafka
生产者
通过spring整合的kafkaTemplate进行开发,send(topic, data)中topic为主题,data为要发送的数据。
kafkaTemplate.send(topic, data);
消费者
消费者是由一个注解实现的,@KafkaListener(topics = {“test”}),表示下面的handleMessage方法需要监听test的主题。当主题有消息传入时,会调用方法获取消息并通过ConsumerReco