<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rabbitmq &#8211; 有意与无意之间</title>
	<atom:link href="https://zhangxihai.cn/archives/tag/rabbitmq/feed" rel="self" type="application/rss+xml" />
	<link>https://zhangxihai.cn</link>
	<description>千淘万漉虽辛苦 吹尽狂沙始到金 - 生命不息 编程不止</description>
	<lastBuildDate>Fri, 05 Mar 2021 08:42:53 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.11</generator>
	<item>
		<title>RabbitMQ面试题汇总</title>
		<link>https://zhangxihai.cn/archives/152</link>
					<comments>https://zhangxihai.cn/archives/152#respond</comments>
		
		<dc:creator><![CDATA[胖爷]]></dc:creator>
		<pubDate>Fri, 22 Feb 2019 05:46:29 +0000</pubDate>
				<category><![CDATA[其它]]></category>
		<category><![CDATA[MQ]]></category>
		<category><![CDATA[Rabbitmq]]></category>
		<category><![CDATA[面试题]]></category>
		<guid isPermaLink="false">https://zhangxihai.cn/?p=152</guid>

					<description><![CDATA[1 为什么要使用MQ？MQ和Redis模拟消息队列相比有什么优点？ 为什么要使用MQ 解耦，系统与系统之间的耦合。 异步，非必要的业务逻辑可以以异步方式运行，加快响应速度 消峰，减少并发 对比Redis消息队列 消息消费的可靠性 Redis没有相应的机制保证消息的消费，当消费者消费失败的时候，消息体丢失，需要手动处理, 例如用数据库、File等进行存储，以保...]]></description>
										<content:encoded><![CDATA[<h4>1 为什么要使用MQ？MQ和Redis模拟消息队列相比有什么优点？</h4>
<p><strong>为什么要使用MQ</strong></p>
<ol>
<li>解耦，系统与系统之间的耦合。</li>
<li>异步，非必要的业务逻辑可以以异步方式运行，加快响应速度</li>
<li>消峰，减少并发</li>
</ol>
<p><strong>对比Redis消息队列</strong></p>
<ol>
<li>消息消费的可靠性<br />
Redis没有相应的机制保证消息的消费，当消费者消费失败的时候，消息体丢失，需要手动处理, 例如用数据库、File等进行存储，以保证队列可以重新处理；</li>
</ol>
<p>MQ一般都有消费确认机制，即使消费失败，也会自动使得消息体返回原队列，同时可全程持久化，保证消息体被正确消费；</p>
<ol start="2">
<li>
<p>发布的可靠性<br />
Redis不提供发布确认，需要自行实现，而MQ通常都有发布确认功能，保证消息被发布到服务器；</p>
</li>
<li>
<p>高可用<br />
Redis故障转移方案不够完美，而MQ集群通常采用磁盘、内存节点，任意单带那故障都不会影响整个队列的操作；</p>
</li>
<li>
<p>持久化<br />
Redis是数据持久化到磁盘，并不是单独针对消息队列。MQ通常队列、消息都可以单独选择是否持久化到磁盘。</p>
</li>
<li>
<p>消费者负载均衡<br />
Redis不提供，需要自行实现，MQ通常根据消费者情况，进行消息的均衡分发；</p>
</li>
<li>
<p>队列监控<br />
Redis不提供，需要自行实现，,Q可以兼容某个队列的所有信息（内存、磁盘、消费者、生产者、速率等）。</p>
</li>
<li>
<p>流量控制<br />
不提供，需要自行实现，MQ通常早服务器过载的情况下，对生产者速率进行限制，保证服务可靠性</p>
</li>
<li>
<p>出入对性能<br />
高并发下，MQ的入队性能通常高于Redis。</p>
</li>
</ol>
<h4>2 RabbitMQ中Broker指什么，cluster又是指什么？</h4>
<p>broker是指一个或多个erlong node的逻辑分组，且node导航运行着rabbitma的应用程序。</p>
<p>cluster是再broker基础之上，增加node之间共享元数据的约束；</p>
<h4>3 RabbitMQ的消息基于什么传输?</h4>
<p>由于TCP连接的创建和小会开销较大，且并发数受系统资源限制，会造成性能瓶颈，RabbitMQ使用信道的方式来传输数据。信道是建立在真实的TCP内的虚拟连接，且每条TCP连接上的信道数量没有限制；</p>
<h4>4 RabbitMQ的消息时如何分发的？</h4>
<p>如果队列至少有一个消费者订阅，消息将以循环的方式发送给消费者。每条消息只会分发给一个订阅的消费者（前提是消费者能够正常处理消息并进行确认）；</p>
<h4>5 消息怎么路由？</h4>
<p>消息理由有三部分：交换器、路由、绑定。生产者把消息发布到交换器上，绑定决定了消息如何从路由器器路由到特定的队列；消息最终到达队列，并被消费者接收；</p>
<p>消息发布到交换器时，消息将用于一个路由键，在消息创建时设定。</p>
<p>通过队列路由键，可以把队列绑定到交换器上。</p>
<p>消息到达交换器后，RabbitMQ会将消息的路由键与队列的路由键进行匹配，如果能够匹配到队列，则消息会投递到相应的队列中； 如果不能匹配到任何队列，消息将进入黑洞。</p>
<p>常用交换器有三种：</p>
<ul>
<li><strong>direct</strong>：如果路由键完全匹配，消息就诶投递到相应的队列；</li>
<li><strong>fanout</strong>: 如果交换器收到消息，将会广播到所有绑定的队列上；</li>
<li><strong>topic</strong> 可以使来自不同源头的消息能够匹配到达同一个队列。</li>
</ul>
<h4>6 如何确保消息正确地发送至RabbitMQ</h4>
<p>Rabiitmq使用发送确认模式，确保消息正确地发送到RabbitMQ.<br />
发送确认模式：将信道设置成confirm模式（发送方确认模式），则所有在信道上发布的消息都会被指派一个唯一ID。一旦消息被投递到目的队列后，或者消息被写入磁盘后，信道会发送一个确认给生产者（包含消息唯一ID）。如果RabbitMQ内部错误从而导致消息丢失，会发送一跳未确认消息。发送方确认模式是异步的，生产者应用程序在等待确认的同事，可以继续发送消息。当确认消息到达生产者应用程序，生产者应用程序的回调方法就会被处罚来处理确认消息。</p>
<h4>7 如何保证消息接收方消费了消息？</h4>
<p>消费者接受每一条消息后都必须进行确认（消息接收和消息确认是两个不同操作）。只有消费者确认了消息，RabbitMQ才能安全第把消息从队列中删除。这里并没用用到超时机制，RabbitMQ仅通过Consumer的链接中断来确认会否需要重新发送消息。也就是说，只要链接不中断，Rabbitmq给了Consumer足够长的时间来处理消息。</p>
<p>特殊情况：</p>
<ul>
<li>如果消费者接收到消息，在确认之前断开了连接或取消订阅，RabbitMQ会认为消息没有被分发，然后重新分发给下一个订阅的消费者；</li>
<li>吐过消费者接收到消息却没有确认消息，连接也未断开，则RabbitMQ认为该消费者繁忙，将不会给消费者分发更多的消息;</li>
</ul>
<h4>8 如何避免消息重复投递或重复消费？</h4>
<p>在消息生产时，MQ内部针对每条生产者发送的消息生成一个inner-msg-id，做为去重和幂等的依据，避免重复的消息进入队列。在消息消费时，要求消息体重必须要有一个bizId做为去重和幂等的依据，避免同一消息被重复消费。</p>
<h4>9 如何解决丢数据的问题？</h4>
<p><strong>生产者丢数据</strong><br />
开启transaction和confirm模式来保证生产者不丢消息。</p>
<p>transaction类似于数据库事务，发送过程中发送异常事务就会回滚。</p>
<p>confirm是确认机制，投递成功则发一条ACK给生产者，投递失败则发一条NACK给生产者，以便重试。</p>
<p>如果是rabbitmq断连，程序员异常，则需要进行异常处理，进行本地端记录，但由于无法保证全部异常都处理， 也可以将投递的消息全部存于本地后，投递成功则标记。</p>
<p><strong>消息队列丢数据</strong><br />
开启持久化磁盘配置，配合comfirm机制，rabbitmq在持久话后，才会给生产者发送ACK。</p>
<p><strong>消费者丢数据</strong><br />
启用手动确认模式</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zhangxihai.cn/archives/152/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
