微服务07-认识MQ+RabbitMQ入门

1.前言

了解同步调用和异步调用

微服务07-认识MQ+RabbitMQ入门_第1张图片

1.1.同步调用

比如这里的支付服务,需要等待订单服务、短信服务…执行完毕才能执行,这样支付整个流程完毕需要500ms

然后如果订单、仓储等其中一个服务挂掉了,那么支付服务请求请求不了,挂掉的服务越来越多,级联失败;——>服务提供者出现问题,那么整个微服务都会出现故障;

资源浪费:消费者需要等待服务提供者响应,不能干其他事情只能干等;

耦合度较高:每次加入新的需求,还需要动原来的代码——>比如:订单加了一个用户积分,那么Feign模块中还要加相关代码,以便订单模块调用,订单模块还需要+调用用户积分的代码:需要改动订单代码;

再来一个场景:比如说,我们要删除某个业务,需要将支付服务中的调用某个业务的相关代码删除;

缺点

微服务07-认识MQ+RabbitMQ入门_第2张图片
微服务07-认识MQ+RabbitMQ入门_第3张图片

1.2.异步调用

利用了一个Broker进行事件通知

优点

级联失败问题得到解决:比如订单服务挂了,它并不会影响支付服务,自己重启就行了
耦合度低:因为支付服务不需要调用其他服务了,而是通过发布事件,Broker对其他事务进行通知,你支付服务该干嘛干嘛,发布完消息返回用户支付成功——>支付服务发布支付成功消息给到Broker,然后Broker进行通知——>对其他服务,然后其他服务执行即可;

吞吐量提升:因为不存在服务之间的调用,所以时间较少(发布信息),能发送的数据就能够越多——>牺牲:消息的延迟,从发送到接收

流量削峰:Broker作为缓冲,将并发请求保存起来,然后通过微服务里面的实现的功能,对请求进行放行——>从而达到流量削峰的效果

缺点

异步调用只是通知你干一件事情,并不知道你干没干完(通过Broker发送请求让你干事情,从而达到解耦的效果)

微服务07-认识MQ+RabbitMQ入门_第4张图片
流量削峰

Broker作为缓冲区对请求进行缓存;
微服务07-认识MQ+RabbitMQ入门_第5张图片
微服务07-认识MQ+RabbitMQ入门_第6张图片

2.认识MQ

微服务07-认识MQ+RabbitMQ入门_第7张图片
RabbitMQ:一般用于业务之间的通信,安全稳定。

KafKa:一般用于海量数据处理,单机吞吐量高:每秒钟能发送的数据大小来分析

3.RabbitMQ入门

3.1 安装使用

1.导入虚拟机并解压
微服务07-认识MQ+RabbitMQ入门_第8张图片

2.运行镜像产生MQ容器
微服务07-认识MQ+RabbitMQ入门_第9张图片

3.运行成功
微服务07-认识MQ+RabbitMQ入门_第10张图片

4.访问RabbitMQ
微服务07-认识MQ+RabbitMQ入门_第11张图片

5.RabbitMQ各属性解读
发布者Publisher会把消息->给到交换机(Exchange),交换机路由给到指定的消息队列(Queue),queue把消息保存起来,然后消费者consumer会从queue将消息拿出来

VirtualHost:各个虚拟主机是不一样的,相当于对操作进行分组——>不同用户访问是不同的虚拟主机,体现隔离性;

微服务07-认识MQ+RabbitMQ入门_第12张图片

3.2 常见消息模型

微服务07-认识MQ+RabbitMQ入门_第13张图片

3.3 简单队列案例

微服务07-认识MQ+RabbitMQ入门_第14张图片

3.3.1 发送

1.建立消息队列连接

IDEA中写好配置

package cn.itcast.mq.helloworld;
 
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;
 
import java.io.IOException;
import java.util.concurrent.TimeoutException;
 
public class PublisherTest {
    @Test
    public void testSendMessage() throws IOException, TimeoutException {
        // 1.建立连接
        ConnectionFactory factory = new ConnectionFactory();
        // 1.1.设置连接参数,分别是:主机名、消息通信端口号、vhost、用户名、密码
        factory.setHost("192.168.88.130");
        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();
 
    }
}

运行代码后

进入RabbitMQ发现连接成功
微服务07-认识MQ+RabbitMQ入门_第15张图片

2.创建一个通道,以此发送消息到队列
微服务07-认识MQ+RabbitMQ入门_第16张图片

3.利用通道来声明队列
微服务07-认识MQ+RabbitMQ入门_第17张图片

4.发送消息
在这里插入图片描述

5.消息成功发送到队列中,消息断开,不管你后面的接收

3.3.2 接收

老样子 IDEA中写好配置,运行即能接收

package cn.itcast.mq.helloworld;
 
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 {
        // 1.建立连接
        ConnectionFactory factory = new ConnectionFactory();
        // 1.1.设置连接参数,分别是:主机名、端口号、vhost、用户名、密码
        factory.setHost("192.168.88.130");
        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("等待接收消息。。。。");
    }
}

跟消息队列的消息发送流程差不多,注意点就是也声明了队列:避免队列不存在

还有一点:定义了consume消费行为handleDelivery()消费行为和队列名字绑定了,只要一有消息就会传递到队列当中被消费行为执行;——>一个异步操作,消费者与消息提供者互相不等待

从先执行后面的打印信息,再执行前面的接收到消息可以看出是一个异步操作:接没接受到不管 (两个线程一个回调,一个往后面继续走

在这里插入图片描述

消费者收到消息后,RabbitMQ中的消息队列的消息就没有了

在这里插入图片描述

你可能感兴趣的:(微服务,微服务,rabbitmq,架构)