RabbitMq-入门

MQ

MessageQueue(消息队列),多用于分布式系统中各个服务之间传递消息;

MQ的优势

1.解耦
在下面的系统架构中,采用同步方式进行交互,当其中任一系统宕机时。都会导致其他系统不可用;
RabbitMq-入门_第1张图片
RabbitMq-入门_第2张图片

2.异步提速

采用同步方式进行交互时,需要等待其他系统的返回结果才能继续往下执行;时间较长;
RabbitMq-入门_第3张图片
RabbitMq-入门_第4张图片

3.削峰填谷

面对突然的大流量,系统可能处理不了容易导致系统宕机,可以使用MQ来限制消费数量保证系统稳定运行;
RabbitMq-入门_第5张图片

RabbitMq-入门_第6张图片

MQ的劣势

1.可用性问题,由于系统/服务交互之间需要使用MQ,一旦MQ宕机那么其他系统也无法进行正常的业务流程;
2.系统复杂度,MQ的加入大大增加了系统的复杂度,以前系统之间是远程同步调用的,现在加入MQ,如何保证MQ的消息不丢失?不重复消费?
RabbitMq-入门_第7张图片

常见的MQ产品

RabbitMq-入门_第8张图片

RabbitMQ工作模式

1.Work
最基本的工作模式,一个生产者多个消费者,消费者对于同一队列内的消息存在竞争关系,如100条数据有两个消费者,那么每个消费者只能消费其中一部分;
RabbitMq-入门_第9张图片
生产者

    public static void main(String[] args) throws IOException {
        Connection conn = MqFactory.getConn();
        Channel channel = conn.createChannel();

        /**
         * 创建队列
         * arg1:队列名称
         * arg2:是否持久化队列数据
         * arg3:是否私有化队列,false时所有消费者共享;true时只有第一个使用的消费者占有
         * arg4:是否删除队列,连接关闭以后是否删除相应的队列;
         * arg5:额外参数
         */
        channel.queueDeclare(MqConstants.queue_worker,false,false,false,null);
        //发送消息
        for (int i = 0; i < 100; i++) {
            String message="i"+ RandomUtil.randomStringUpper(5);
            channel.basicPublish("",MqConstants.queue_worker,null,message.getBytes(StandardCharsets.UTF_8));
        }
        channel.close();
        conn.close();
    }

消费者

    public static void main(String[] args) throws IOException {
        Connection conn = MqFactory.getConn();
        final Channel channel = conn.createChannel();
//        channel.basicQos(1); 不设置Qos时,消息将会平均发给每个消费者;设置Qos后,会等到消费者完成后再发送;
        channel.basicConsume(MqConstants.queue_worker,new DefaultConsumer(channel){
                    @Override
                    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                        System.err.println("workerConsumer1"+new String(body));
                        //false只确认签收当前的消息,设置为true的时候则代表签收该消费者所有未签收的消息
                        channel.basicAck(envelope.getDeliveryTag(),false);
                    }
                }
        );
    }

2.Publish/Subscribe
订阅模式引出了交换机(Exchange)的概念,首先在rabbitMq服务端建立Exchange并且指定类型(fanout,direct,topic);
1.fanout
生产者发送消息时需要指定Exchange,不需要指定routing key,消费者接收消息时需要指定Exchange并且全量消费;生产100条,每个消费者都能消费100条;

 /**
         * fanout模式:
         * arg1:交换机
         * arg2:routing key,此时不需要指定
         * arg3:额外参数
         * arg4:发送的消息
         */
        channel.basicPublish(MqConstants.exchange_direct,"",null,RandomUtil.randomString(5).getBytes(StandardCharsets.UTF_8));

2.direct
也就是routing 模式,生产者发送消息时指定Exchange,指定routing key;消费者同样需要指定;此时生产者生产的消息将依据routking分别转给对应的消费者

  /**
         * fanout模式:
         * arg1:交换机
         * arg2:routing key
         * arg3:额外参数
         * arg4:发送的消息
         */
        channel.basicPublish(MqConstants.exchange_direct,"rabbitmq.message.1",null,RandomUtil.randomString(5).getBytes(StandardCharsets.UTF_8));

3.topics 模式
此时消费者只有rouking key有区别,支持通配符模式; 通配符规则:# 匹配一个或多个词,* 号匹配不多不少恰好1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert,item. 星号只能匹配 item.insert

      /**
         * arg1:队列名
         * arg2:交换机
         * arg3:routing key
         */
        channel.queueBind(MqConstants.queue_helloworld,MqConstants.exchange_direct,"rabbitmq.#")

RabbitMq-入门_第10张图片

3.Routing
上述 routing 模式
4.Topics
上述 topic模式
5.RPC

Confirm & Return

RabbitMq-入门_第11张图片

你可能感兴趣的:(日常学习,rabbitmq)