目录
1、什么是消息中间件
消息(message)是指在应用间传送的数据。消息可以非常简单,也可以很复杂。
消息队列中间件(Message Queue Middleware,简称为MQ)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排列模型,它可以在分布式环境下扩展进程间的通信。
2、传统的http请求存在的缺点
1、Http请求基于请求与响应的模型,在高并发的情况下,客户端发送大量的请求达到服务器端有可能会导致我们服务器端处理请求堆积。
2、Tomcat服务器处理每个请求都有自己独立的线程,如果超过最大线程数会将该请求缓存到队列中,如果请求堆积过多的情况下,有可能会导致tomcat服务器崩溃的问题。所以一般都会在nginx入口实现限流,整合服务保护框架。
3、http请求处理业务逻辑如果比较耗时的情况下,容易造成客户端一直等待,阻塞等待过程中会导致客户端超时发生重试策略,有可能会引发幂等性问题。
注意事项:接口是为http协议的情况下,最好不要处理比较耗时的业务逻辑,耗时的业务逻辑应该单独交给多线程或者是mq处理。
3、多线程异步和mq异步区别
1、使用多线程,如果该机器宕机,则创建的线程就全部没了,会导致子线程任务丢失,MQ就不会丢失。
2、MQ具有削峰能力, 当巨量请求发送过来时,MQ可以存储到消息容器中。但如果使用多线程,会创建大量线程,Tomcat默认就200个线程,如果使用线程池,大量线程过来,会直接把线程池灌满。那再创建线程,会导致触发淘汰策略,直接拒绝了多线程会耗费CPU资源,但MQ会,可以配置消费一个再拿下一个,始终保持CPU,内存最佳状态服务集群配置时,MQ可以更均衡的分配到每个服务器,因为多个服务器会同时向MQ拿取消息。但多线程在哪台机器开启的,就会在哪台机器执行,会导致任务倾斜现象,使得某个服务器开启了大量线程,其他服务器却很空闲.
3、MQ可以实现异步/解耦/流量削峰问题;多线程也可以实现异步,但是消耗到cpu资源,没有实现解耦。
选择建议:大型项目还是推荐MQ,如果是并发不高,任务量不大,可以选择多线程
4、MQ的设计基础知识
1、多线程版本mq
public class ThreadMQ {
/**
* Broker
*/
private static LinkedBlockingDeque<JSONObject> broker = new LinkedBlockingDeque<JSONObject>();
public static void main(String[] args) {
// 创建生产者线程
Thread producer = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
JSONObject data = new JSONObject();
data.put("name", "RK");
broker.offer(data);
} catch (Exception e) {
}
}
}
}, "生产者");
producer.start();
Thread consumer = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
JSONObject data = broker.poll();
if (data != null) {
System.out.println(Thread.currentThread().getName() + ",获取到数据:" + data.toJSONString());
}
} catch (Exception e) {
}
}
}
}, "消费者");
consumer.start();
}
}
2、基于网络通讯版本mq netty实现
消费者netty客户端与nettyServer端MQ服务器端保持长连接,MQ服务器端保存消费者连接。
生产者netty客户端发送请求给nettyServer端MQ服务器端,MQ服务器端在将该消息内容发送给消费者。
生产者投递消息给MQ服务器端,MQ服务器端需要缓存该消息
如果mq服务器端宕机之后,消息如何保证不丢失
服务器将消息持久化到磁盘(持久化机制)
如果mq接收到生产者投递消息,如果消费者不在的情况下,该消息是否会丢失?
不会丢失,消息确认机制:必须要消费者消费该消息成功之后,在通知给mq服务器端删除该消息。
Mq如何实现抗高并发思想
Mq消费者根据自身能力情况 ,拉取mq服务器端消息消费。默认的情况下是取出一条消息。
缺点:存在延迟的问题,需要考虑mq消费者提高速率的问题:
如何消费者提高速率:消费者实现集群、消费者批量获取消息即可,避免消息堆积。
5、MQ如何保证消息不丢失
1、生产者角色
确保生产者投递消息到MQ服务器端成功。
Ack 消息确认机制
同步或者异步的形式
方式1:Confirms
方式2:事务消息
2、消费者角色
在rabbitmq情况下:
必须要将消息消费成功之后,才会将该消息从mq服务器端中移除。
在kafka中的情况下:
不管是消费成功还是消费失败,该消息都不会立即从mq服务器端移除。
3、Mq服务器端:在默认的情况下 都会对队列中的消息实现持久化 持久化硬盘。