每日一句
物是人非事事休,欲语泪先流。
概述
为了保证消息在发送过程中不丢失,RabbitMQ引入了消息应答机制,
消费者在接收到消息并且处理该消息后,告诉RabbitMQ它已经处理了,RabbitMQ可以把消息删除了。
自动应答
消息发送后立即被认为已经传送成功,这种模式需要在高吞吐量和数据传输安全性方面做权衡。
因为这种模式有两种情况会出问题:
1。如果消息在接收到之前,消费者那边出现连接或者channel关闭,那么消息就丢失了。
2。消费者这边由于接收太多还来不及处理的消息,导致这些消息的积压,最终使得内存耗尽,最终这些消费者线程会被操作系统杀死。
所以这种模式仅适用于在消费者可以高效并以某种速率能够处理这些消息的情况下使用。
消息应答的方法
A.Channel.basicAck(用于肯定确认) RabbitMQ 已知道该消息并且成功的处理消息,可以将其丢弃了
B.Channel.basicNack(用于否定确认)
C.Channel.basicReject(用于否定确认) 与 Channel.basicNack 相比少一个参数,不处理该消息了直接拒绝,可以将其丢弃了
Multiple 的解释
手动应答的好处是可以批量应答并且减少网络拥堵
multiple 的 true 和 false 代表不同意思
true 代表批量应答 channel 上未应答的消息
比如说 channel 上有传送 tag 的消息 5,6,7,8 当前 tag 是8 那么此时5-8 的这些还未应答的消息都会被确认收到消息应答
false 同上面相比只会应答 tag=8 的消息 5,6,7 这三个消息依然不会被确认收到消息应答
消息自动重新入队
如果消费者由于某些原因失去连接(其通道已关闭,连接已关闭或 TCP 连接丢失),导致消息未发送 ACK 确认,RabbitMQ 将了解到消息未完全处理,并将对其重新排队。如果此时其他消费者可以处理,它将很快将其重新分发给另一个消费者。这样,即使某个消费者偶尔死亡,也可以确保不会丢失任何消息。
消息手动应答代码
面试题
线程池工作原理?
JVM先根据用户给定的参数创建一定数量的可运行的线程任务,并将其放入队列中,在线程创建后启动这些任务。
1。通过execute 方法提交任务时,当线程池中的线程小于corePoolsize时,新提交的任务将通过创建一个新线程来执行,即使此时线程池中存在空闲线程。
2。通过execute方法提交任务时,当线程池中线程数量达到corePoolSize时,新提交的任务将被放入workQueue中,等待线程池中线程调度执行。
- 通过execute方法提交任务时,当workQueue已存满,且maximumPoolSize大于corePoolSize时,新提交的任务将通过创建新线程执行。
4。通过execute方法提交任务,当线程池中线程数达到maxmumPoolSize,并且workQueue也存满时,新提交的任务由RejectedExecutionHandler执行拒绝操作。
5。当线程池中线程数超过corePoolSize,并且未配置allowCoreThreadTimeOut=true,空闲时间超过keepAliveTime的线程会被销毁,保持线程池中线程数为corePoolSize。
6。当设置allowCoreThreadTimeOut=true时,任何空闲时间超过keepAliveTime的线程都会被销毁。
线程池(Thread Pool)是一种基于池化思想管理线程的工具,线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,同时也降低了计算机的整体性能。
线程池维护多个线程,等待监督管理者分配可并发执行的任务。
这种做法,一方面避免了处理任务时创建销毁线程开销的代价,另一方面避免了线程数量膨胀导致的过分调度问题,保证了对内核的充分利用。
线程池解决的核心问题就是资源管理问题。
【HashMap】HashMap中,当两个对象的hashcode相同会发生什么?如果两个键的hashcode相同,你如何获取值对象?
因为hashcode相同,所以它们的bucket位置相同,‘碰撞’会发生。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。
HashMap中,如果两个键的hashcode相同,你如何获取值对象?
当我们调用get()方法,HashMap会使用键对象的hashcode找到bucket位置,然后获取值对象。 找到bucket位置之后,会调用keys.equals()方法去找到链表中正确的节点,最终找到要找的值对象
【GC算法】为什么 JAVA 新生代使用复制算法、老年代使用标记清除算法比较好?三种算法对比?
-
新生代更新频繁,绝大部分都是垃圾对象,垃圾回收之后,只有极小的可用对象,采用复制算法,将这小部分的对象复制到S区,成本是比较小的。
-
老年代中的对象很多经过新生代之后,都是证明不好回收的对象,采用复制算法,那么需要复制对象的太多了,成本太高了。采用标记清除算法只需要删除标记对象就可以了,这样的成本是最低的。
-
CMS收集器关注延迟问题,有低延迟的特性,基于标记清除算法。因为该算法不需要移动对象,所以停顿时间短,但正是不需要移动对象,所以会有内存碎片化的问题
-
Parallel Old收集器,关注吞吐量,是基于标记整理算法,牺牲了一定的性能,但是对内存对象进行了一个压缩操作,所以吞吐量会大一点。
你好,我是yltrcc,日常分享技术点滴,欢迎关注我:ylcoder
网友评论