MQ的使用

一、MQ介绍

MQ全称 Message Queue([kjuː])(消息队列),是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。

二、MQ的优势和劣势

1.优势

  • 应用解耦:提高系统容错性和可维护性。
  • 异步提速:提升用户体验和系统吞吐量。
  • 削峰填谷:提高系统稳定性。

2.劣势 

  • 系统可用性降低 

        系统引入的外部依赖越多,系统稳定性越差。一旦 MQ 宕机,就会对业务造成影响。如何保证MQ的高可用?

  • 系统复杂度提高

        MQ 的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过 MQ 进行异步调用。如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?

  • 一致性问题

        A 系统处理完业务,通过 MQ 给B、C、D三个系统发消息数据,如果 B 系统、C 系统处理成功,D 系统处理失败。如何保证消息数据处理的一致性?

三、常见MQ产品

四、RabbitMQ基本介绍

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、 安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。

五、RabbitMQ 基础架构

Broker 中间者 服务

procedure 和consumer都是客户端

客户端通过链接和服务端进行通信 所以需要建立起来连接 然后进行通信a

使用channel(管道)节省资源

一个rabbitmq里面有很多的虚拟机 相当于mysql里面有很多数据库,数据库里面有很多表,都是独立的。

每个虚拟机里面有很多的exchange和queue 独立分区的作用

六、RabbitMQ的安装和配置

1.安装包准备

2.安装依赖环境

yum -y install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ kernel-devel m4 ncurses-devel tk tc xz

3.安装Erlang

rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm

4.安装RabbitMQ

1.安装依赖的包

rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm

2.安装rabbitmq

rpm -ivh rabbitmq-server-3.7.18-1.el7.noarch.rpm

5. 开启管理界面及配置

rabbitmq-plugins enable rabbitmq_management

6.修改默认配置信息

vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.18/ebin/rabbit.app

7.启动RabbitMQ

  • systemctl start rabbitmq-server # 启动服务
  • systemctl stop rabbitmq-server # 停止服务
  • systemctl restart rabbitmq-server # 重启服务
  • systemctl status rabbitmq-server #查看状态

8.打开客户端

ipxxx:15672

 使用guest/guest登录之后出现如下即为安装成功

七、 添加用户

 

 1.给用户添加权限

 

即可

八、RabbitMQ工程搭建 

1.简单模式

1.添加pom

    <dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>5.6.0</version>
    </dependency>

2. 生产者

public class productTest {
    @Test
    public void product() throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();
        /**
         * String queue, 队列的名称
         * boolean durable, 持久化
         * boolean exclusive, 是否独占
         * boolean autoDelete,  受否自动删除
         * Map<String, Object> arguments  参数
         */
//        创建队列
        channel.queueDeclare("test1",false,false,false,null);
//        发布消息
        channel.basicPublish("","test1",null,"hello".getBytes());
    }
}

3.消费者

public class Consumer {
    @Test
    public void product() throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();

        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String s = new String(body);
                System.out.println("消息队列:"+s);
            }
        };
        channel.basicConsume("test1",true,defaultConsumer);
    }
}

 2.竞争消费者模式

1.生产者

public class productTest1 {
    @Test
    public void product() throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();
        /**
         * String queue, 队列的名称
         * boolean durable, 持久化
         * boolean exclusive, 是否独占
         * boolean autoDelete,  受否自动删除
         * Map<String, Object> arguments  参数
         */
//        创建队列
        channel.queueDeclare("test1",false,false,false,null);

        for (int i = 0; i < 10; i++) {
            //        发布消息
            channel.basicPublish("","test1",null,("hello"+i).getBytes());
        }
    }
}
2.消费者
1.消费者1
public class Consumer1 {
    public static void main(String[] args) throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();

        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String s = new String(body);
                System.out.println("消息队列:" + s);
            }
        };
        channel.basicConsume("test1", true, defaultConsumer);
    }
}
2.消费者
public class Consumer2 {
    public static void main(String[] args) throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();

        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String s = new String(body);
                System.out.println("消息队列:"+s);
            }
        };
        channel.basicConsume("test1",true,defaultConsumer);
    }
    }

项目结构

3.订阅模式

1.生产者

public class productTest2 {
    @Test
    public void product() throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();
//        创建交换机
        channel.exchangeDeclare("myjhj", BuiltinExchangeType.FANOUT,false);
//        创建队列
        channel.queueDeclare("testj3",false,false,false,null);
        channel.queueDeclare("testj4",false,false,false,null);
//        交换机绑定
        channel.queueBind("testj3","myjhj","");
        channel.queueBind("testj4","myjhj","");
//        消息
        channel.basicPublish("myjhj","",null,"testex".getBytes());
    }
}

消费者同上

4.路由模式

1.消费者

public class productTest3 {
    @Test
    public void product() throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();
//        创建交换机
        channel.exchangeDeclare("myjhj1", BuiltinExchangeType.DIRECT,false);
//        创建队列
        channel.queueDeclare("testj5",false,false,false,null);
        channel.queueDeclare("testj6",false,false,false,null);
//        交换机绑定队列
        channel.queueBind("testj5","myjhj1","error");
        channel.queueBind("testj6","myjhj1","test6666");
        channel.queueBind("testj6","myjhj1","test7777");
//        消息
        channel.basicPublish("myjhj1","test7777",null,"测试".getBytes());
    }
}

消费者同上

5.通配符模式

Topic类型与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符

通配符规则:

#:匹配一个或多个词 

*:匹配不多不少恰好1个词   test.* test.insert

Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert

举例:

item.#:能够匹配item.insert.abc 或者 item.insert

item.*:只能匹配item.insert 

 1.生产者

public class productTest3 {
    @Test
    public void product() throws Exception {
        ConnectionFactory continuation = new ConnectionFactory();
        continuation.setHost("192.168.64.33");
        continuation.setPort(5672);
        continuation.setPassword("ww");
        continuation.setUsername("ww");
//        设置对应的虚拟主机
        continuation.setVirtualHost("/ww");
//        物理连接
        Connection connection = continuation.newConnection();
//        建立通道
        Channel channel = connection.createChannel();
//        创建交换机
        channel.exchangeDeclare("myjhj3", BuiltinExchangeType.TOPIC,false);
//        创建队列
        channel.queueDeclare("testj9",false,false,false,null);
        channel.queueDeclare("testj10",false,false,false,null);
//        交换机绑定队列
        channel.queueBind("testj9","myjhj3","test.#");
        channel.queueBind("testj10","myjhj3","test.*");
        channel.queueBind("testj10","myjhj3","*.aaa");
//        消息
        //受作用的为9和10
        channel.basicPublish("myjhj3","test.aaa",null,"测试111".getBytes());
    }
}

消费者同上

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值