RabbitMQ 归纳总结
Rabbit MQ 归纳总结
文章目录
- Rabbit MQ 归纳总结
- 前言
- 一、消息中间件概述
- 1.1.MQ 概述
- 1.2.MQ 优势
- 1.2.1 应用解耦
- 1.2.2 任务异步处理
- 1.2.3 削峰填谷
- 1.3. MQ 劣势
- 二、常见的MQ 产品
- 三、RabbitMQ 简介
- 2.2.安装与配置RabbitMQ
- 2.3. Rabbit MQ 的几种模式
- 2.3.1简单模式 simple
- 2.3.2 工作队列模式 workQueue
- 2.3.3 发布订阅模式 Publish/subscribe
- 2.3.4.路由模式 Routing
- 2.3.5 通配符模式 topic
- 2.4 Spring 整合 RabbitMQ
前言
MQ 是什么,MQ 有哪些模式,MQ是如何和spring 整合的?
提示:以下是本篇文章正文内容,下面案例可供参考
一、消息中间件概述
1.1.MQ 概述
MQ 全称 Message Queue(消息队列),是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。
1.2.MQ 优势
1.2.1 应用解耦
MQ 相当于一个中介,生成方通过MQ 与 消费方进行交互,它将应用程序进行解耦合
系统的耦合性越高,容错性就越低,可维护性就越差
使用MQ使得应用间解耦,提升容错性和可维护性
1.2.2 任务异步处理
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间
1.2.3 削峰填谷
如订单系统,在下单的时候就会往数据库写数据。但是数据库只能支撑每秒1000左右的并发写入,并发量再高就容易宕机。低峰期的时候并发也就100多个,但是在高峰期时候,并发量会突然激增到5000以上,这个时候数据库肯定卡死了
1.3. MQ 劣势
1. 系统的可用性降低
系统引入的外部依赖越多,系统的稳定性就越差。一旦MQ 宕机就会对系统的业务造成影响。如何保证MQ 的高可用?
2. 系统复杂度提高
QM 的加入增加了系统的复杂度,以前系统间是同步的远程调用,现在是MQ 进行异步调用,如何保证消息没有被重复消费?怎么处理消息丢失情况?怎么保证消息传递的顺序性?
3. 一致性问题
A 系统处理完任务,通过MQ 给B、C、D 三个系统发消息,如果B系统、C系统处理成功,D系统处理失败。如何保证消息处理的一致性?
二、常见的MQ 产品
目前市场有很多的MQ 产品,例如 RabbitMQ 、RocketMQ、ActiveMQ、kafka、ZeroMQ、MetaMQ 等,也有直接用Redis 充当消息队列的案例,而这些消息队列产品各有侧重,在实际选型时,需要结合自身需求以及MQ产品特征,综合考虑
实现MQ 的常见的两种方式:
AMQP、JMS
AMQP:
AMQP,即 Advanced Message Queuing Protocol(高级消息队列协议),是一个网络协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,遵循此协议,不收客户端和中间件产品和开发语言限制。2006年,AMQP 规范发布。类比HTTP。
JMS:
JMS 即 Java 消息服务(JavaMessage Service)应用程序接口,是一个 Java 平台中关于面向消息中间件的APIJMS 是 JavaEE 规范中的一种,类比JDBC很多消息中间件都实现了JMS规范,例如:ActiveMQ。RabbitMQ 官方没有提供 JMS 的实现包,但是开源社区有
AMQP 与 JMS 区别:
JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
JMS规定了两种消息模式;而AMQP的消息模式更加丰富
三、RabbitMQ 简介
RabbitMQ官方地址:http://www.rabbitmq.com/
2007年,Rabbit 技术公司基于 AMQP 标准开发的 RabbitMQ 1.0 发布。RabbitMQ 采用 Erlang 语言开发。Erlang 语言专门为开发高并发和分布式系统的一种语言,在电信领域使用广泛。
RabbitMQ 基础架构如下图:
RabbitMQ 中的相关概念:
- Broker 接收和分发消息 ,RabbitMQ Server 就是 Message Broker
- Virtual host : 出于多租户和安全因素考虑设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中的namespace 概念。当多个不同的用户使用同一个RabbitMQ Server 提供的服务时,可以划分出多个vhost,每个用户在自己的vhost 创建 exchange 和 queue 等
- Connection: publisher / consumer 和 broker 之间的TCP 连接
- Channel : 如果每一次访问RabbitMQ 都建立一个Connection,在消息量大的时候建立多个Connection 的开销是巨大的,效率也很低。 Channel 是在Connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个Thread 创建单独的Channel 进行通信,AMQP Method 包含了 channel ID 帮助客户端和 message Broker 识别Channel ,所以Channel 之间是完全隔离的。Channel 作为轻量级的 Connection,极大的减少操作系统建立TCP Connection 的开销。
- Exchange: message 到达 Broker 的第一站,根据分发规则,匹配查询表中的 routing key ,分发消息到 queue 中去。 常用的类型有: direct(point-to-point) , topic(publish-subscrib) and fanout (multicast)
- Queue : 消息最终被送到这里等待Consumer 取走
- Binding: exchange 和 queue 之间的虚拟连接,binding 中可以包含routing key。Binding 信息被保存到 Exchange 中的查询表中,用于Message 的分发依据。
RabbitMQ 提供了6 种模式:简单模式、work 模式,Publish/ Subscrib 发布与订阅模式,Routing 路由模式,Topics 主题模式,RPC 远程调用模式。
官网对应模式介绍:https://www.rabbitmq.com/getstarted.html
2.2.安装与配置RabbitMQ
这里使用docker 安装:
- 查找 rabbitmq:management 镜像
docker search rabbitmq:management
- 拉取 rabbitmq 镜像
# management 不可省略(否则打不开 管理端)
docker pull rabbitmq:management
- 创建容器 rabbitmq 容器
docker run -id --name=rabbitmq
-p 5671:5671 \
-p 5672:5672 \
-p 15672:15672 \
rabbitmq:management
创建成功! 打开浏览器输入 http://ip:15672 即可访问 ,默认用户名:guest,密码:guest
2.3. Rabbit MQ 的几种模式
2.3.1简单模式 simple
一个生产者,一个消费者,不需要设置交换机(使用默认的交换机)
// 将获取连接的代码封装
package com.geng.utils;import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ConnectionUtils {public static Connection getConnection() throws IOException, TimeoutException {//1. 创建连接工厂ConnectionFactory connectionFactory = new ConnectionFactory();//1.1设置主机地址:默认为localhostconnectionFactory.setHost("192.168.43.6");//1.2 设置连接端口,默认为 5672connectionFactory.setPort(5672);//1.3 设置虚拟主机名称,默认为 /connectionFactory.setVirtualHost("/gjt");//1.4 设置连接用户名,默认为 guestconnectionFactory.setUsername("guest");//1.5 设置连接密码,默认为 guestconnectionFactory.setPassword("guest");//2. 创建连接return connectionFactory.newConnection();}
}
package com.geng.rabbitmq.simple;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;
//生产者
public class Produce {public static String QUEUE_KEY = "simple-queue" ;public static void main(String[] args) throws IOException, TimeoutException {Connection connection = ConnectionUtils.getConnection();//3. 创建频道Channel channel = connection.createChannel();//4. 声明队列/*** 参数1: 队列名称* 参数2:是否定义持久化队列* 参数3:是否独占本次连接* 参数4:是否在不使用的时候自动删除队列* 其他参数*/channel.queueDeclare(QUEUE_KEY,true,false,false,null);//5. 要发送的消息/*** 参数1:交换机的名称,如果没有则用默认的 default exchange* 参数2:路由key ,简单模式可以传递队列名称* 参数3:消息其他属性* 参数4:消息内容*/String message = "good night,耿俊廷";/****/channel.basicPublish("", QUEUE_KEY,null,message.getBytes());//6. 关闭资源channel.close();connection.close();}
}
package com.geng.rabbitmq.simple;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ConsumerTest {public static void main(String[] args) throws IOException, TimeoutException {//2. 获得连接Connection connection = ConnectionUtils.getConnection();//3. 创建通道Channel channel = connection.createChannel();//4. 声明队列channel.queueDeclare(Produce.QUEUE_KEY,true,false,false,null);//5.消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("路由key为:" + envelope.getRoutingKey()); //交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id为:" + envelope.getDeliveryTag());//收到的消息System.out.println("接收到的消息为:" + new String(body, "utf-8"));}};channel.basicConsume(Produce.QUEUE_KEY,true,consumer);}
}
2.3.2 工作队列模式 workQueue
一个生产者,多个消费者(竞争关系),不需要设置交换机(使用默认交换机)
package com.geng.rabbitmq.workQueue;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Produce {public static String QUEUE_KEY = "simple-queue" ;public static void main(String[] args) throws IOException, TimeoutException {//2. 获得连接Connection connection = ConnectionUtils.getConnection();//3. 创建频道Channel channel = connection.createChannel();//4. 声明队列/*** 参数1: 队列名称* 参数2:是否定义持久化队列* 参数3:是否独占本次连接* 参数4:是否在不使用的时候自动删除队列* 其他参数*/channel.queueDeclare(QUEUE_KEY,true,false,false,null);//5. 要发送的消息/*** 参数1:交换机的名称,如果没有则用默认的 default exchange* 参数2:路由key ,简单模式可以传递队列名称* 参数3:消息其他属性* 参数4:消息内容*/String message = "good night,耿俊廷";/****/for(int i = 0; i < 10; i++){channel.basicPublish("", QUEUE_KEY,null,(message+i).getBytes());}//6. 关闭资源channel.close();connection.close();}
}
package com.geng.rabbitmq.workQueue;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ConsumerTest {public static void main(String[] args) throws IOException, TimeoutException {//或得连接Connection connection = ConnectionUtils.getConnection();//3. 创建通道Channel channel = connection.createChannel();//4. 声明队列channel.queueDeclare(Produce.QUEUE_KEY,true,false,false,null);//5.消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("路由key为:" + envelope.getRoutingKey()); //交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id为:" + envelope.getDeliveryTag());//收到的消息System.out.println("接收到的消息为:" + new String(body, "utf-8"));}};channel.basicConsume(Produce.QUEUE_KEY,true,consumer);}
}
package com.geng.rabbitmq.workQueue;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ConsumerTest2 {public static void main(String[] args) throws IOException, TimeoutException {//或得连接Connection connection = ConnectionUtils.getConnection();//3. 创建通道Channel channel = connection.createChannel();//4. 声明队列channel.queueDeclare(Produce.QUEUE_KEY,true,false,false,null);//5.消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("路由key为:" + envelope.getRoutingKey()); //交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id为:" + envelope.getDeliveryTag());//收到的消息System.out.println("接收到的消息为:" + new String(body, "utf-8"));}};channel.basicConsume(Produce.QUEUE_KEY,true,consumer);}
}
2.3.3 发布订阅模式 Publish/subscribe
需要设置类型为fanout 的交换机,并且交换机和队列进行绑定,当消息发送到交换机后,交换机会将消息发送到绑定的队列
package com.geng.rabbitmq.ps;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Produce {public static String EXCHANGE = "ps-exchange";public static String QUEUE_KEY1 = "ps-queue1";public static String QUEUE_KEY2 = "ps-queue2" ;public static void main(String[] args) throws IOException, TimeoutException {//2. 获得连接Connection connection = ConnectionUtils.getConnection();//3. 创建频道Channel channel = connection.createChannel();//4. 声明队列 和 交换机 exchange/*** 参数1: 队列名称* 参数2:是否定义持久化队列* 参数3:是否独占本次连接* 参数4:是否在不使用的时候自动删除队列* 其他参数*/channel.queueDeclare(QUEUE_KEY1,true,false,false,null);channel.queueDeclare(QUEUE_KEY2,true,false,false,null);channel.exchangeDeclare(EXCHANGE, BuiltinExchangeType.FANOUT);//队列绑定交换机channel.queueBind(QUEUE_KEY1, EXCHANGE, "");channel.queueBind(QUEUE_KEY2, EXCHANGE, "");//5. 要发送的消息/*** 参数1:交换机的名称,如果没有则用默认的 default exchange* 参数2:路由key ,简单模式可以传递队列名称* 参数3:消息其他属性* 参数4:消息内容*/String message = "good night,耿俊廷";/****/for(int i = 0; i < 10; i++){channel.basicPublish(EXCHANGE, "",null,(message+i).getBytes());}//6. 关闭资源channel.close();connection.close();}
}
package com.geng.rabbitmq.ps;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ConsumerTest {public static void main(String[] args) throws IOException, TimeoutException {//或得连接Connection connection = ConnectionUtils.getConnection();//3. 创建通道Channel channel = connection.createChannel();//4. 声明队列channel.queueDeclare(Produce.QUEUE_KEY1,true,false,false,null);channel.queueBind(Produce.QUEUE_KEY1,Produce.EXCHANGE,"");//5.消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("路由key为:" + envelope.getRoutingKey()); //交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id为:" + envelope.getDeliveryTag());//收到的消息System.out.println("接收到的消息为:" + new String(body, "utf-8"));}};channel.basicConsume(Produce.QUEUE_KEY1,true,consumer);}
}
package com.geng.rabbitmq.ps;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class ConsumerTest2 {public static void main(String[] args) throws IOException, TimeoutException {//或得连接Connection connection = ConnectionUtils.getConnection();//3. 创建通道Channel channel = connection.createChannel();//4. 声明队列channel.queueDeclare(Produce.QUEUE_KEY2,true,false,false,null);//队列绑定交换机channel.queueBind(Produce.QUEUE_KEY2,Produce.EXCHANGE,"");//5.消费消息DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("路由key为:" + envelope.getRoutingKey()); //交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id为:" + envelope.getDeliveryTag());//收到的消息System.out.println("接收到的消息为:" + new String(body, "utf-8"));}};channel.basicConsume(Produce.QUEUE_KEY2,true,consumer);}
}
2.3.4.路由模式 Routing
需要设置类型为 direct 的交换机,交换机和队列进行绑定,当消息到达交换机后,交换机会根据路由规则(routing key),将消息发送到绑定的对应的队列
package com.geng.rabbitmq.routing;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Produce {public static String EXCHANGE_ROUTE = "route-exchange";public static String QUEUE_INSERT = "queue-insert";public static String QUEUE_UPDATE = "queue-update";public static void main(String[] args) throws IOException, TimeoutException {//获得连接Connection connection = ConnectionUtils.getConnection();//获得通道Channel channel = connection.createChannel();/*** 声明交换机* 参数1 :交换机名称* 参数2 :交换机类型 fanout ,direct, topic ,headers*/channel.exchangeDeclare(EXCHANGE_ROUTE, BuiltinExchangeType.DIRECT);/*** 声明队列* 参数1: 队列名称* 参数2: 是否定义持久化队列* 参数3: 是否独占本次连接* 参数4: 是否在不使用的时候独占本次连接* 参数5: 队列其他参数*/channel.queueDeclare(QUEUE_INSERT,true,false,false,null);channel.queueDeclare(QUEUE_UPDATE,true,false,false,null);//队列绑定交换机(exchange)channel.queueBind(QUEUE_UPDATE,EXCHANGE_ROUTE,"update");channel.queueBind(QUEUE_INSERT,EXCHANGE_ROUTE,"insert");// 发送消息,插入String message = "新增。路由模式 routing key 为 insert";/*** 参数1:交换机名称,如果没有指定则使用默认Default Exchage* 参数2:路由key,简单模式可以传递队列名称* 参数3:消息其它属性* 参数4:消息内容*/channel.basicPublish(EXCHANGE_ROUTE,"insert",null,message.getBytes());//发送消息,修改String message2 = "修改。 路由模式 routing key 为 update";channel.basicPublish(EXCHANGE_ROUTE,"update",null,message2.getBytes());//关闭资源channel.close();connection.close();}
}
package com.geng.rabbitmq.routing;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Consumer1 {public static void main(String[] args) throws IOException, TimeoutException {//获取连接Connection connection = ConnectionUtils.getConnection();//创建通道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(Produce.EXCHANGE_ROUTE, BuiltinExchangeType.DIRECT);//声明队列channel.queueDeclare(Produce.QUEUE_INSERT,true,false,false,null);//队列绑定交换机channel.queueBind(Produce.QUEUE_INSERT,Produce.EXCHANGE_ROUTE,"insert");//创建消息消费者回调对象DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {// 路由keySystem.out.println("路由key为:" + envelope.getRoutingKey());//交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id:" + envelope.getDeliveryTag());//消息内容System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));}};//监听消息/*** 参数1: 监听消息队列名称* 参数2: 是否接收到消息后自动向mq 回复消息接收到了,mq 接收到回复会删除消息*/channel.basicConsume(Produce.QUEUE_INSERT,true,consumer);}
}
package com.geng.rabbitmq.routing;import com.geng.utils.ConnectionUtils;
import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;public class Consumer2 {public static void main(String[] args) throws IOException, TimeoutException {//获取连接Connection connection = ConnectionUtils.getConnection();//创建通道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(Produce.EXCHANGE_ROUTE, BuiltinExchangeType.DIRECT);//声明队列channel.queueDeclare(Produce.QUEUE_UPDATE,true,false,false,null);//队列绑定交换机channel.queueBind(Produce.QUEUE_UPDATE,Produce.EXCHANGE_ROUTE,"update");//创建消息消费者回调对象DefaultConsumer consumer = new DefaultConsumer(channel){@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {// 路由keySystem.out.println("路由key为:" + envelope.getRoutingKey());//交换机System.out.println("交换机为:" + envelope.getExchange());//消息idSystem.out.println("消息id:" + envelope.getDeliveryTag());//消息内容System.out.println("消费者1-接收到的消息为:" + new String(body, "utf-8"));}};//监听消息/*** 参数1: 交换机名称* 参数2: 是否接收到消息后自动向mq 回复消息接收到了,mq 接收到回复会删除消息*/channel.basicConsume(Produce.QUEUE_UPDATE,true,consumer);}
}
2.3.5 通配符模式 topic
需要设置类型为topic的交换机,交换机和队列进行绑定,并且指定通配符方式的routing key,当发送消息到交换机后,交换机会根据routing key将消息发送到对应的队列
2.4 Spring 整合 RabbitMQ
RabbitMQ 归纳总结相关推荐
- RabbitMQ之消息确认机制(事务+Confirm)
概述 在使用RabbitMQ的时候,我们可以通过消息持久化操作来解决因为服务器的异常奔溃导致的消息丢失,除此之外我们还会遇到一个问题,当消息的发布者在将消息发送出去之后,消息到底有没有正确到达brok ...
- rabbitmq最大连接数(Socket Descriptors)
RabbitMQ自带了显示能够接受的最大连接数,有2种比较直观的方式: 1. rabbitmqctl命令. 1 2 3 4 5 6 7 8 9 10 11 12 <span style=&quo ...
- 消息中间件选型分析 —— 从 Kafka 与 RabbitMQ 的对比来看全局
一.前言 二.各类消息队列简述 三.选型要点概述 四.消息中间件选型误区探讨 一.前言 消息队列中间件(简称消息中间件)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布 ...
- RabbitMQ下的生产消费者模式与订阅发布模式
所谓模式,就是在某种场景下,一类问题及其解决方案的总结归纳.生产消费者模式与订阅发布模式是使用消息中间件时常用的两种模式,用于功能解耦和分布式系统间的消息通信,以下面两种场景为例: 数据接入 假 ...
- java webservice接口开发_给Java新手的一些建议----Java知识点归纳(J2EE and Web 部分)
J2EE(Java2 Enterprise Edition) 刚出现时一般会用于开发企业内部的应用系统,特别是web应用,所以渐渐,有些人就会把J2EE和web模式画上了等号.但是其实 J2EE 里面 ...
- 消息中间件选型分析——从Kafka与RabbitMQ的对比来看全局
本文收录于InfoQ,未经允许不得转载. 欢迎跳转到本文原文:https://honeypps.com/mq/kafka-vs-rabbitmq/ 一.前言 消息队列中间件(简称消息中间件)是指利用高 ...
- kafka消息消费有延迟_消息中间件选型分析---从Kafka与RabbitMQ的对比来看全局
有很多网友留言:公司要做消息中间件选型,该如何选?你觉得哪个比较好?消息选型的确是一个大论题,实则说来话长的事情又如何长话短说.对此笔者专门撰稿一篇内功心法:如何看待消息中间件的选型,不过这篇只表其意 ...
- RabbitMQ一个简单可靠的方案(.Net Core实现)
前言 最近需要使用到消息队列相关技术,于是重新接触RabbitMQ.其中遇到了不少可靠性方面的问题,归纳了一下,大概有以下几种: 1. 临时异常,如数据库网络闪断.http请求临时失效等: 2. 时序 ...
- 消息中间件Kafka与RabbitMQ谁更胜一筹?
在 IM 这种讲究高并发.高消息吞吐的互联网场景下,MQ 消息中间件是个很重要的基础设施,它在 IM 系统的服务端架构中担当消息中转.消息削峰.消息交换异步化等角色. 当然,MQ 消息中间件的作用远不 ...
- activemq消息丢失_Kafka or RabbitMQ:消息中间件选型深入分析
消息中间件选型深入分析 --从Kafka与RabbitMQ的对比来看全局 有很多网友留言:公司要做消息中间件选型,该如何选?你觉得哪个比较好?消息选型的确是一个大论题,实则说来话长的事情又如何长话短说 ...
最新文章
- discuz云平台报调用远程接口失败的问题分析和解决
- 索引节点(inode)爆满问题处理
- JavaSE(十七)——IO流之字节流
- python3 xml 取标签显示内容_如何应用“XML+XSLT”技术分离Web表示层数据和样式
- Spring Boot 2.x(六):优雅的统一返回值
- django-学习索引1908版
- Android开发笔记(一百三十七)自定义行为Behavior
- 家里有古玩古董摆放在家中好吗?
- java 改变文件权限_Java文件权限
- json文件_ajax
- wps启用编辑按钮在哪里_WPS文字打印设置
- C++-如何排查内存写坏
- 个人支付接口现状分析——总有一款适合你
- ssh登录极路由后台_自己动手DIY:路由器刷机改造
- android项目创建好慢,解决 Android Studio 创建项目时极其的慢的尴尬
- spring cloud alibaba nacos
- OpenGL 法线贴图Normal Mapping
- 我在美国与“狼”共舞的日子(6)
- oracle sql实现分词搜索分词功能
- J2ME实现手机振动器
热门文章
- Touchbar Pet 0.8.2 最新版 (Touch Bar触控栏养宠物)
- H3C交换机静态路由与NQA联动
- Craw the picture of the specific handle
- 助力数字经济,服务数智化转型,用友火力全开
- 中国电信5G技术引言
- 币圈进化,IFO、IHO玩法更高级,李笑来Candy“糖果”野望未来
- 实现java多线程的3种方式
- 详解Django的CSRF认证
- 中国居民身份证 算法 转 是java版本的
- ubuntu16.04+Titan Xp安装显卡驱动+Cuda9.0+cudnn