RabbitMQ
同步通讯:就像打电话,需要实时响应。
异步通讯:就像发邮件,不需要马上回复。
同步调用的优点:
- 
时效性较强,可以立即得到结果 
同步调用的问题:
- 
耦合度高 
- 
性能和吞吐能力下降 
- 
有额外的资源消耗 
- 
有级联失败问题 
我们以购买商品为例,用户支付后需要调用订单服务完成订单状态修改,调用物流服务,从仓库分配响应的库存并准备发货。
在事件模式中,支付服务是事件发布者(publisher),在支付完成后只需要发布一个支付成功的事件(event),事件中带上订单id。
订单服务和物流服务是事件订阅者(Consumer),订阅支付成功的事件,监听到事件后完成自己业务即可。
 
- 
吞吐量提升:无需等待订阅者处理完成,响应更快速 
- 
故障隔离:服务没有直接调用,不存在级联失败问题 
- 
调用间没有阻塞,不会造成无效的资源占用 
- 
耦合度极低,每个服务都可以灵活插拔,可替换 
- 
流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件 
- 
架构复杂了,业务没有明显的流程线,不好管理 
- 
需要依赖于Broker的可靠、安全、性能 
好在现在开源软件或云平台上 Broker 的软件是非常成熟的,比较常见的一种就是我们今天要学习的MQ技术。
比较常见的MQ实现:
- 
ActiveMQ 
- 
RabbitMQ 
- 
RocketMQ 
- 
Kafka 
几种常见MQ的对比:

追求可靠性:RabbitMQ、RocketMQ
追求吞吐能力:RocketMQ、Kafka
追求消息低延迟:RabbitMQ、Kafka
- 
publisher:生产者 
- 
consumer:消费者 
- 
exchange个:交换机,负责消息路由 
- 
queue:队列,存储消息 
- 
virtualHost:虚拟主机,隔离不同租户的exchange、queue、消息的隔离 
- 
publisher:消息发布者,将消息发送到队列queue 
- 
queue:消息队列,负责接受并缓存消息 
- 
consumer:订阅队列,处理队列中的消息 
- 
建立连接 
- 
创建Channel 
- 
声明队列 
- 
发送消息 
- 
关闭连接和channel 
@Test public void testSendMessage() throws IOException, TimeoutException { // 1.建立连接 ConnectionFactory factory = new ConnectionFactory(); // 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码 factory.setHost("192.168.150.101"); factory.setPort(5672); factory.setVirtualHost("/"); factory.setUsername("itcast"); factory.setPassword("123321"); // 1.2.建立连接 Connection connection = factory.newConnection(); // 2.创建通道Channel Channel channel = connection.createChannel(); // 3.创建队列 String queueName = "simple.queue"; channel.queueDeclare(queueName, false, false, false, null); // 4.发送消息 String message = "hello, rabbitmq!"; channel.basicPublish("", queueName, null, message.getBytes()); System.out.println("发送消息成功:【" + message + "】"); // 5.关闭通道和连接 channel.close(); connection.close(); }
- 
建立连接 
- 
创建Channel(这里为什么也创建,因为生产和消费者不一定谁先启动,没有就会报错) 
- 
声明队列 
- 
订阅消息 
public static void main(String[] args) throws IOException, TimeoutException { // 1.建立连接 ConnectionFactory factory = new ConnectionFactory(); // 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码 factory.setHost("192.168.150.101"); factory.setPort(5672); factory.setVirtualHost("/"); factory.setUsername("itcast"); factory.setPassword("123321"); // 1.2.建立连接 Connection connection = factory.newConnection(); // 2.创建通道Channel Channel channel = connection.createChannel(); // 3.创建队列 String queueName = "simple.queue"; channel.queueDeclare(queueName, false, false, false, null); // 4.订阅消息 channel.basicConsume(queueName, true, new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { // 5.处理消息 String message = new String(body); System.out.println("接收到消息:【" + message + "】"); } }); System.out.println("等待接收消息。。。。"); }
- 
建立connection 
- 
创建channel 
- 
利用channel声明队列 
- 
利用channel向队列发送消息 
基本消息队列的消息接收流程:
- 
建立connection 
- 
创建channel 
- 
利用channel声明队列 
- 
定义consumer的消费行为handleDelivery() 
- 
利用channel将消费者与队列绑定 
 
                    
                     
                    
                 
                    
                




 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号