消息中间件-RabbitMQ入门

概述

RabbitMQ是一个由Erlang语言开发的基于AMPQ标准的开源实现。
具有以下特点:
1.可靠性:可以通过消息确认,消息持久化来保证可靠性
2.具有灵活的路由:消息在进入队列之前是通过Exchange来路由消息的。
3.支持消息集群
4.支持多语言客户端
5.支持跟踪机制

基本概念

在这里插入图片描述

如上图所示,Rabbit的关键元素

关键需要理解的有两点
1.路由机制
消息到达Broker后会先经过Exchange,这过程还隐藏着一个元素,那就是route key,一般发消息会指定一个route key,Exchange通过检查这个route key与Bindingz中的binding key来决定投到哪一个Queue。
2.信道
我们知道连接是一种很昂贵的资源,RabbitMQ为了尽量少的减少Connection的开销,采用信道也就是Channel来多路复用,即在一个连接中可以存在多个Channel,Channel是建立在真实的TCP连接中的虚拟连接。

交换器类型

不同的交换器发生消息的策略也不同,目前交换器有四种,Direct, Fannot, Topic, Headers,其中Headers由于和Direct交换机差不多,所以基本不用,不作解释。

Direct

这种方式强调的是单播,完全匹配。即消息中的路由键要和Binding中的绑定建完全一致,交换器就会把消息发送到对应的队列中去。

Fanout

Fanout强调广播,Fanout不处理路由键,只是简单的将队列绑定到交换器上。通过Fanout是最快的。

Topic

Topic 交换器是通过模式匹配分配消息的路由键属性,将录用后键和某种模式进行匹配。
关键点,路由键通过点分割,绑定建通过#来表示0或多个,*表示不少于一个

java访问实例

public class Consumer {

    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();

        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");

        connectionFactory.setHost("129.204.174.193");
        connectionFactory.setVirtualHost("/");

        Connection connection = connectionFactory.newConnection();

        Channel channel = connection.createChannel();

        String exchangeName = "hello-exchange";
        channel.exchangeDeclare(exchangeName, "direct", true);

        String queueName = channel.queueDeclare().getQueue();
        String routingKey = "testRoutingKey";

        channel.queueBind(queueName, exchangeName, routingKey);

        while (true) {

            boolean autoAck = false;
            String consumerTag = "";
            channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                    byte[] body) throws IOException {
                    String routingKey = envelope.getRoutingKey();
                    String contentType = properties.getContentType();
                    System.out.println("消费的路由键:" + routingKey);
                    System.out.println("消费的内容类型:" + contentType);
                    long delivryTag = envelope.getDeliveryTag();

                    channel.basicAck(delivryTag, false);
                    System.out.println("消费的信息体内容:");
                    String bodyStr = new String(body, "UTF-8");
                    System.out.println(bodyStr);
                }
            });
        }
    }
}

public class Producer {

    public static void main(String[] args) throws IOException, TimeoutException {

        //创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername("guest");
        factory.setPassword("guest");

        factory.setHost("129.204.174.193");
        factory.setVirtualHost("/");

        Connection conn = factory.newConnection();

        Channel channel = conn.createChannel();

        String exchangeName = "hello-exchange";

        channel.exchangeDeclare(exchangeName, "direct", true);

        String routingKey = "testRoutingKey";

        byte[] messageBodyBytes = "quit".getBytes();

        channel.basicPublish(exchangeName, routingKey, null, messageBodyBytes);

        channel.close();
        conn.close();
    }
}

以上是直接用java连接,当然我们可以选择用Spring 或 springboot来处理,这样我们就不必自己来创建连接,做配置了,直接操作RabbitTemplate要方便的多。

持久化

为了消息不丢失,我们需要做持久化,关键点是,持久化我们要对交换器,队列,消息都进行持久化,交换器和队列在声明时候有个durable的参数设置成ture就可以了,消息在发生时,配置BasicProperties,把deliveryMode设置成2就可以了

消息确认

消息确认存在两个地方,一个是由生产者向Broker,二是Broker向消费者

使用场景

消息异步

消息推送

能够推送在于RabbitMQ居然连js都能操作,我们在js里声明客户端,然后监听队列。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章