RabbitMq 概念与基础使用

------------------------------------------------------------------------RabbitMq 核心概念-----------------------------------------------------------------------

AMQP:高级消息队列协议

Server :Broker接受客户端的连接,实现AMQP 实体服务

Connection:连接 ,应用程序与Broker 建立连接

Channel:网络通信, 几乎所有的操作都在Channel中进行,是进行消息读写的通道,每一个channel代表一个会话任务

Message:消息,传送的数据 由Properties 和Body 组成

Virtual host:虚拟主机,用于逻辑隔离,最上层的消息路由的划分。同一个Virtual host 不能有相同名称的Exchange或Queue

Exchange :交换机,接受消息,根据路由键转发消息到绑定的队列

Binding: Exchange  和Queue 之间的虚拟连接,bingding中可以包含routing key

Routing key : 一个路由规则,虚拟机可以用它来确定如何路由一个特别消息

Queue : message queue,消息队列

------------------------------------------------------------------------RabbitMq 安装使用-----------------------------------------------------------------------

erlang/socat/rabbitmq

官网下载 erlang(相当于java 的jdk), 和rabbitMq 服务。

配置环境变量后 cmd 执行:

rabbitmqctl status --查看状态

rabbitmq-plugins.bat enable rabbitmq_management //管理界面插件

rabbitmq-server.bat --启动mq 服务

登陆 http://localhost:15672 用户名密码:guest/guest

-----------------------------------------------------------------------命令行操作与管控台-基础操作----------------------------------------------------------

rabbitmqctl  stop_app:关闭应用

rabbitmqctl  add_user username password: 添加用户

rabbitmqctl list_users: 列出所有用户

rabbitmqctl delete_user username : 删除用户

rabbitmqctl  add_vihost vhostpath :创建虚拟主机

rabbitmqctl list_vihost  : 列出所有虚拟主机

rabbitmqctl list_queues:查看所有队列信息

rabbitmqctl  reset :移除所有数据,要在rabbitmqctl  stop_app 之后使用

rabbitmqctl join_cluster <cluster_node> [--ram] : 组成集群命令

rabbitmqctl cluster_status :查看集群状态

....

所有管控台能操作得步骤,控制台命令都可操作。

-----------------------------------------------------------------------Exchange 交换机---------------------------------------------------------------

Exchange有以下属性:

Name:交换机名称

Type:Direct,Topic,Fanout ,Headers(不常用)

Durability:(durable-持久化/transient-瞬变)是否需要持久化,true/durable 为持久化 

Auto Delete:当最后一个绑定到Exchange 上得队列删除后,自动删除改Exchange

Internal:当前Exchange是否用于RabbitMQ 内部使用,默认为false/no(基本不做设定使用默认)

Argument:扩展参数,用于扩展AMQP协议自制定化使用

-----------------------------------------------------------------------Direct Exchange 模式---------------------------------------------------------------

Direct Exchange:所有发送到 Direct Exchange 得消息被转发到RoutingKey 中指定得Queue (注意:Direct 模式可以使用RabbitMQ自带得Exchange:default Exchange,所以不需要将Exchange进行任何绑定(binding)操作,消息传递时,Routingkey 必须完全匹配才会被队列接收,否则消息会被抛弃

/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生产者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";

        String exchangename = "test_direct_exchange";
        String routingKey = "test_direct";

        for (int i = 0; i <5 ; i++) {
            //发消息时必须要指定Exchange, 如果没有指定, 默认找default Exchange 通过指定得Routing Key 去找对应得名字
            //1.exchange 2.routing key
            channel.basicPublish(exchangename,routingKey,null,Massage.getBytes());
        }
        channel.close();
        connection.close();

    }

}
/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消费者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();

        //声明
        String exchangename = "test_direct_exchange";
        String exchangeType = "direct";
        String queuename = "test_direct_queue";
        String routingKey = "test_direct";
        //声明一个交换机
        channel.exchangeDeclare(exchangename,exchangeType,true,false,false,null);
        //声明一个队列
        channel.queueDeclare(queuename,true,false,false,null);
        //交换机和队列通过routingkey绑定
        channel.queueBind(queuename,exchangename,routingKey);

        //创建一个消费者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)
                        throws IOException
                {
                    System.out.println("消费者......");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                }
         });

    }
}

-----------------------------------------------------------------------Topic Exchange 模式---------------------------------------------------------------

Topic Exchange:所有发送到 Topic Exchange 的消息被转发到所有关心RoutingKey中指定的Topic的Queue上(Exchange 将RoutingKey 和某Topic进行模糊匹配,此时队列需要绑定一个Topic 注意:可以使用通配符进行模糊匹配 "#" 匹配一个或多个词;"*" 匹配不多不少一个词,例如:"log.#" 能够匹配到"log.info.oa" ; "log.*"只会匹配到"log.erro")

/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消费者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();

        //声明
        String exchangename = "test_topic_exchange";
        String exchangeType = "topic";
        String queuename = "test_topic_queue";
        String routingKey = "user.#";
        //声明一个交换机
        channel.exchangeDeclare(exchangename,exchangeType,true,false,false,null);
        //声明一个队列
        channel.queueDeclare(queuename,false,false,false,null);
        //交换机和队列通过routingkey绑定
        channel.queueBind(queuename,exchangename,routingKey);

        //创建一个消费者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)throws IOException{
                    System.out.println("消费者consumerTag ["+consumerTag+"]envelope["+envelope+"]properties["+properties+"]");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                   // System.out.println("消费者收到的消息["++"]");
                }
         });

    }
}
/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生产者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";

        String exchangename = "test_topic_exchange";
        String routingKey1 = "user.save";
        String routingKey2 = "user.update";
        String routingKey3 = "user.delete.abc";

        System.out.println("生产者......");
        channel.basicPublish(exchangename,routingKey1,null,Massage.getBytes());
        channel.basicPublish(exchangename,routingKey2,null,Massage.getBytes());
        channel.basicPublish(exchangename,routingKey3,null,Massage.getBytes());

        channel.close();
        connection.close();

    }

}

-----------------------------------------------------------------------Fanout Exchange 模式---------------------------------------------------------------

Fanout Exchange:不处理任何的路由键,只需要简单的将队列绑定到交换机上;发送到交换机上的消息都会被转发到与该交换机绑定的所有队列上;Fanout 交换机转发消息是最快的。

/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生产者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";

        String exchangename = "test_fanout_exchange";
        String routingKey1 = ""; //无论是否设置路由键, fanout模式都忽略,直接看交换机的一个绑定关系
       /* String routingKey2 = "user.update";
        String routingKey3 = "user.delete.abc";*/

        System.out.println("生产者......");
        for (int i = 0; i <3 ; i++) {
            channel.basicPublish(exchangename,routingKey1,null,Massage.getBytes());

        }
        channel.close();
        connection.close();

    }
}
/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消费者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();

        //声明
        String exchangename = "test_fanout_exchange";
        String exchangeType = "fanout";
        String queuename = "test_fanout_queue";
        String routingKey = "";//不设置路由键
        //声明一个交换机
        channel.exchangeDeclare(exchangename,exchangeType,true,false,false,null);
        //声明一个队列
        channel.queueDeclare(queuename,false,false,false,null);
        //交换机和队列通过routingkey绑定
        channel.queueBind(queuename,exchangename,routingKey);

        //创建一个消费者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)throws IOException{
                    System.out.println("消费者consumerTag ["+consumerTag+"]envelope["+envelope+"]properties["+properties+"]");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                }
         });

    }
}

-----------------------------------------------------------------------Binding-绑定---------------------------------------------------------------------------------

Binding-绑定: Exchange 和Exchange、Queue之间的连接关系 ; Binding中可以包含RoutingKey或者参数

-----------------------------------------------------------------------Queue-消息队列----------------------------------------------------------------------------Queue-消息队列:实际存储消息数据

Durability:是否需要持久化,durable-是/ transient-否

Auto Delete:当最后一个绑定到Exchange 上得队列删除后,自动删除改Exchange

-----------------------------------------------------------------------Message-消息----------------------------------------------------------------------------

Message:服务和应用程序之间传送的数据;本质上就是一段数据 由Properties 和Body 组成

常用属性:delivery mode、headers(自定义属性)

其它属性:content_type、content_encoding、priority ;

                 correlation_id、reply_to、expiration、message_id;

                 timestamp、type、user_id、app_id、cluster_id;

/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生产者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";
        String routingKey= "test001"; 
        Map<String, Object> map = new HashMap<>();
        map.put("my1","111");
        map.put("my2","222");
        AMQP.BasicProperties  Properties= new AMQP.BasicProperties.Builder()
                .deliveryMode(2) //常用模式 2-持久化 服务器重启消息依旧存在
                .contentType("UTF-8")//
                .expiration("50000") //消息过期时间
                .headers(map)//放自定义的属性
                .build();
        for (int i = 0; i <3 ; i++) {
            System.out.println("生产者......");
            //发送一个带有附加属性的消息
            channel.basicPublish("",routingKey,Properties,Massage.getBytes());

        }
        channel.close();
        connection.close();

    }
}
/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消费者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //创建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通过ConnectionFactory 创建Connection
        Connection connection =connectionFactory.newConnection();

        //通过Connection创建Channel(核心通信)
        Channel channel = connection.createChannel();

        //声明
        String queuename = "test001";
        //声明一个队列
        channel.queueDeclare(queuename,true,false,false,null);

        //创建一个消费者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)throws IOException{
                    System.out.println("消费者consumerTag ["+consumerTag+"]envelope["+envelope+"]properties["+properties.getHeaders().get("my1")+"]");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                }
         });

    }
}

 

 

 

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