消息中间件RabbitMQ和AMQS-------------------(一)

默认端口:5672,,5671

消息中间件:解耦,异步

AMQS:对消息协议的规定,类似http

概念:

Broker: 接收和分发消息的应用,我们在介绍消息中间件的时候所说的消息系统就是Message Broker。

Virtual host: 出于多租户和安全因素设计的,把AMQP的基本组件划分到一个虚拟的分组中,类似于网络中 的namespace概念。当多个不同的用户使用同一个RabbitMQ server提供的服务时,可以划分出多个vhost, 每个用户在自己的vhost创建exchange/queue等。      类似命名空间

Connection: publisher/consumer和broker之间的TCP连接。断开连接的操作只会在client端进行,Broker 不会断开连接,除非出现网络故障或broker服务出现问题。

Channel: 如果每一次访问RabbitMQ都建立一个Connection,在消息量大的时候建立TCP Connection的开 销将是巨大的,效率也较低。Channel是在connection内部建立的逻辑连接,如果应用程序支持多线程,通 常每个thread创建单独的channel进行通讯,AMQP method包含了channel id帮助客户端和message broker 识别channel,所以channel之间是完全隔离的。Channel作为轻量级的Connection极大减少了操作系统建立 TCP connection的开销。              channel是根据TCP连接开辟出来的

Exchange(交换机): message到达broker的第一站,根据分发规则,匹配查询表中的routing key,分发消息到queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)。

Queue: 消息最终被送到这里等待consumer取走。一个message可以被同时拷贝到多个queue中。

Binding: exchange和queue之间的虚拟连接,binding中可以包含routing key。Binding信息被保存到 exchange中的查询表中,用于message的分发依据。 

注意生产者和消费者位置

 

 

消息默认存在内存中,如果down机消息会消失------------->有办法

1.RabbitMQ服务端安装:先安装erlang环境,再安装rabbitMQ服务端

安装成功

 

打开控制台

打开浏览器              http://127.0.0.1:15672

打开控制台之后可以添加用户,设置访问权限

 

public static void main(String[] argv) throws Exception {
               Connection  connection=ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //队列允许持久化,队列可以其他channel调用,没有任何消费者消费时自动删除队列,队列配置(消息寿命,容纳消息数量等信息)
        channel.queueDeclare(ConnectionUtil.QUEUE_NAME, true, false, false, null);
        String message = "Hello World!";
        //默认路由,队列名,消息配置先为null
        channel.basicPublish("", ConnectionUtil.QUEUE_NAME, null, message.getBytes());
        channel.close();
        System.out.println(" Sent '" + message + "'");

    }
public class Consumer {
    public static void main(String[] args) throws Exception{
        getMessage();
    }
    public static void getMessage()throws Exception{
        Connection connection= ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //channel.queueDeclare(ConnectionUtil.QUEUE_NAME, false, false, false, null);
        //消费消息
        DefaultConsumer deliverCallback = new DefaultConsumer(channel) {
            //envelope,可以拿消息标识路由        properties,消息配置      body消息
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(new String(body, "UTF-8"));
            }
        };
        //开始消费
        channel.basicConsume(ConnectionUtil.QUEUE_NAME, true, deliverCallback);
    }
}

消费

 

 

 

metricsCollector:数据采集器

RabbitMQ通过一帧(Frame)一帧进行数据传输

channel--->connnection--->socket

 

发送确认代码:可以测试发送到错的交换机会报错

public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //rabbitTemplate.setMandatory(true);
        //发送确认的回调,发送成功
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                System.out.println(ack);    //消息是否成功
                System.out.println(cause);  //失败原因
                System.out.println(correlationData);    //类似于业务id
            }
        });
        return rabbitTemplate;
}

也可以设置多个callBack函数:

 

设置消息回调

 //开启失败回调
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                //message : 发送的消息 "hello"+ 发送消息的配置(如过期时间等。。)
                System.out.println(message);
                //状态码
                System.out.println(replyCode);
                //失败信息
                System.out.println(replyText);
                System.out.println(exchange);
                System.out.println(routingKey);
            }
        });
        return rabbitTemplate;

 

消息序列化:JSON.toJSONString(map)

消费端:

有两种接收消息的方式有什么区别呢???会有乱码问题,springboot会查参数中是否包含text,如果是文本类型就会给转成String,否则直接返回body时byte数组========>1.设置消息类型为文本  见代码

第一种方式spring会按照参数的类型进行赋值。。

 

备用交换机:

队列设置时的配置参数

交换机配置参数

 

 

设置备用交换机:

 @Bean
    public DirectExchange defaultExchange() {
        Map<String, Object> map = new HashMap<>();
        //声明备用交换机,已经存在的
        map.put("alternate-exchange","name");
        //如果交换机directExchangeTest2失败,将会调用备用交换机name
        return  new DirectExchange("directExchangeTest2",false,false,map);
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值