RabbitMQ

服务异步调用:服务A如何保证异步请求一定能被服务B就收到并处理

 

 

削峰:海量请求,如何实现削峰效果,将请求全部放到一个队列中 慢慢消费  这个队列怎么实现?

 

 

服务解耦:如何尽量降低服务之间的耦合问题,如果在订单服务与积分服务解耦  需要一个队列  而这个队列依然需要实现上述两种功能

 

前提系统安装了 docker和docker-compose

https://m.runoob.com/docker/docker-compose.html
复制代码
version: "3.1"
services:
  rabbitmq:
    image: daocloud.io/library/rabbitmq:3.8.5
    container_name: rabbitmq
    restart: always
    volumes:
      - ./data/:/var/lib/rabbitmq/
    ports:
      - 5672:5672
      - 15672:15672
复制代码

 

执行

curl localhost:5672

 

 默认图形化界面是关闭的

 

docker exec -it rabbitmq bash
cd /opt/rabbitmq/
 cd plugins/

 

 

 cd ../sbin/
开启图形化界面 ./rabbitmq-plugins enable rabbitmq_management

 

 在window访问

http://192.168.1.137:15672/

 

 

账号密码为
guest
"Hello World!"  一个队列被一个消费者消费 入门
复制代码
Work queues  一个队列被多个消费者消费(如果 消费者的消费速率不一致  但是消费量却一样 就会导致 消费快的空转 而消费慢的消息迟迟消化不完生产者生产的消息)
此时我们需要关闭自动ack  手动去提交ack
channel.basicConsume(QUEUE_NAME, false, defaultConsumer);

 

 

复制代码
Publish/Subscribe 手动创建Exchange(FANOUT)  需要自定义创建一个交换机
Routing 手动创建Exchange(DIRECT)

 

 

复制代码
Topics 手动创建Exchange(TOPIC)

 

 

 

 

 

复制代码
RPC  RPC方式

 

 

 Publisher Confirms
复制代码
构建Connection工具类

<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.9.0</version>
</dependency>

复制代码
@SpringBootTest
class MallOrderApplicationTests {
    public static final String RABBITMQ_HOST="192.168.1.137";
    public static final Integer RABBITMQ_PORT=5672;
    public static final String RABBITMQ_USERNAME="guest";
    public static final String RABBITMQ_PASSWORD="guest";
    public static final String RABBITMQ_VIRTUAL_HOST="/";
    public static final String QUEUE_NAME="hello";
    //构建rabbitMQ链接对象
    public static Connection getConnection() throws IOException, TimeoutException {
        //创建connection工厂
         ConnectionFactory factory = new ConnectionFactory();
        //设置RabbitMq 连接信息
        factory.setHost(RABBITMQ_HOST);
        factory.setPort(RABBITMQ_PORT);
        factory.setUsername(RABBITMQ_USERNAME);
        factory.setPassword(RABBITMQ_PASSWORD);
        factory.setVirtualHost(RABBITMQ_VIRTUAL_HOST);
        //返回链接对象
        Connection connection = factory.newConnection();
        return connection;
    }

    @Test
    public void publish() throws IOException, TimeoutException {
        //获取连接对象
        Connection connection = MallOrderApplicationTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列  durable 队列是否持久化  exclusive 如果为true 只允许一个消费者消费  autoDelete 队列长时间没有使用 自动删除
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        String message="Hello World";
        //发布消息  使用rabbitMQ自带的默认交换机  routingkey 叫什么  就把消息路由到哪个队列中
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        System.out.println("消息发送成功");
        System.in.read();
    }
    @Test
    public void consumer() throws Exception {
        //获取连接对象
        Connection connection = MallOrderApplicationTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("body:"+new String(body) );
            }
        };
        channel.basicConsume(QUEUE_NAME, true, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }
}
复制代码
复制代码
Work queues 实现代码
复制代码
@SpringBootTest
class WorkqueuesTests {
    public static final String RABBITMQ_HOST="192.168.1.137";
    public static final Integer RABBITMQ_PORT=5672;
    public static final String RABBITMQ_USERNAME="guest";
    public static final String RABBITMQ_PASSWORD="guest";
    public static final String RABBITMQ_VIRTUAL_HOST="/";
    public static final String QUEUE_NAME="work";
    //构建rabbitMQ链接对象
    public static Connection getConnection() throws IOException, TimeoutException {
        //创建connection工厂
         ConnectionFactory factory = new ConnectionFactory();
        //设置RabbitMq 连接信息
        factory.setHost(RABBITMQ_HOST);
        factory.setPort(RABBITMQ_PORT);
        factory.setUsername(RABBITMQ_USERNAME);
        factory.setPassword(RABBITMQ_PASSWORD);
        factory.setVirtualHost(RABBITMQ_VIRTUAL_HOST);
        //返回链接对象
        Connection connection = factory.newConnection();
        return connection;
    }
    @Test
    public void publish() throws IOException, TimeoutException {
        //获取连接对象
        Connection connection = WorkqueuesTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列  durable 队列是否持久化  exclusive 如果为true 只允许一个消费者消费  autoDelete 队列长时间没有使用 自动删除
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        //发布消息  使用rabbitMQ自带的默认交换机  routingkey 叫什么  就把消息路由到哪个队列中
        for (int i = 0; i < 100; i++) {
            String message="Hello World"+i;
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
        }

        System.out.println("消息发送成功");
        System.in.read();
    }
    @Test
    public void consumer1() throws Exception {
        //获取连接对象
        Connection connection = WorkqueuesTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //设置消息的流控 一次只消费一个  别一次性分发完后 让consumer自己慢慢消费 此设置是让consume消费完一条消息后再从channel中再获取下一条消息
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者一号获取到的消息:"+new String(body) );
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }

    @Test
    public void consumer2() throws Exception {
        //获取连接对象
        Connection connection = WorkqueuesTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);
        //设置消息的流控
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者二号获取到的消息:"+new String(body) );
                //deliveryTag 标识
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }
}
复制代码

 

Publish/Subscribe  需要自定义交换价FANOUT 就是不关注routing key 是什么  只要直接绑定了交换机  就发送消息给绑定的queue
复制代码
@SpringBootTest
class PublishSubscribeTests {
    public static final String RABBITMQ_HOST="192.168.1.137";
    public static final Integer RABBITMQ_PORT=5672;
    public static final String RABBITMQ_USERNAME="guest";
    public static final String RABBITMQ_PASSWORD="guest";
    public static final String RABBITMQ_VIRTUAL_HOST="/";
    public static final String QUEUE_NAME_ONE="pubsub-one";
    public static final String QUEUE_NAME_TWO="pubsub-two";
    public static final String EXCHANGE_NAME="pubsub";
    //构建rabbitMQ链接对象
    public static Connection getConnection() throws IOException, TimeoutException {
        //创建connection工厂
         ConnectionFactory factory = new ConnectionFactory();
        //设置RabbitMq 连接信息
        factory.setHost(RABBITMQ_HOST);
        factory.setPort(RABBITMQ_PORT);
        factory.setUsername(RABBITMQ_USERNAME);
        factory.setPassword(RABBITMQ_PASSWORD);
        factory.setVirtualHost(RABBITMQ_VIRTUAL_HOST);
        //返回链接对象
        Connection connection = factory.newConnection();
        return connection;
    }
    @Test
    public void publish() throws IOException, TimeoutException {
        //获取连接对象
        Connection connection = PublishSubscribeTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建交换机
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
        //构建队列  durable 队列是否持久化  exclusive 如果为true 只允许一个消费者消费  autoDelete 队列长时间没有使用 自动删除
        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);
        //绑定交换机和队列 使用的是FANOUT类型交换机,绑定方式是直接绑定
        channel.queueBind(QUEUE_NAME_ONE, EXCHANGE_NAME, "");
        channel.queueBind(QUEUE_NAME_TWO, EXCHANGE_NAME, "");
        //发布消息  使用rabbitMQ自带的默认交换机  routingkey 叫什么  就把消息路由到哪个队列中
        for (int i = 0; i < 100; i++) {
            String message="Hello World"+i;
            channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
        }

        System.out.println("消息发送成功");
        System.in.read();
    }
    @Test
    public void consumer1() throws Exception {
        //获取连接对象
        Connection connection = PublishSubscribeTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        //设置消息的流控 一次只消费一个  别一次性分发完后 让consumer自己慢慢消费 此设置是让consume消费完一条消息后再从channel中再获取下一条消息
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者一号获取到的消息:"+new String(body) );
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME_ONE, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }

    @Test
    public void consumer2() throws Exception {
        //获取连接对象
        Connection connection = PublishSubscribeTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);
        //设置消息的流控
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者二号获取到的消息:"+new String(body) );
                //deliveryTag 标识
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME_TWO, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }
}
复制代码
Routing 手动创建Exchange(DIRECT)
复制代码
@SpringBootTest
class RoutingTests {
    public static final String RABBITMQ_HOST="192.168.1.137";
    public static final Integer RABBITMQ_PORT=5672;
    public static final String RABBITMQ_USERNAME="guest";
    public static final String RABBITMQ_PASSWORD="guest";
    public static final String RABBITMQ_VIRTUAL_HOST="/";
    public static final String QUEUE_NAME_ONE="routing-one";
    public static final String QUEUE_NAME_TWO="routing-two";
    public static final String EXCHANGE_NAME="routing";
    //构建rabbitMQ链接对象
    public static Connection getConnection() throws IOException, TimeoutException {
        //创建connection工厂
         ConnectionFactory factory = new ConnectionFactory();
        //设置RabbitMq 连接信息
        factory.setHost(RABBITMQ_HOST);
        factory.setPort(RABBITMQ_PORT);
        factory.setUsername(RABBITMQ_USERNAME);
        factory.setPassword(RABBITMQ_PASSWORD);
        factory.setVirtualHost(RABBITMQ_VIRTUAL_HOST);
        //返回链接对象
        Connection connection = factory.newConnection();
        return connection;
    }
    @Test
    public void publish() throws IOException, TimeoutException {
        //获取连接对象
        Connection connection = RoutingTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建交换机 routing 类型交换机为DIRECT
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        //构建队列  durable 队列是否持久化  exclusive 如果为true 只允许一个消费者消费  autoDelete 队列长时间没有使用 自动删除
        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);
        //绑定交换机和队列 使用的是FANOUT类型交换机,绑定方式是直接绑定  需要指定routingkey
        channel.queueBind(QUEUE_NAME_ONE, EXCHANGE_NAME, "ORANGE");
        channel.queueBind(QUEUE_NAME_TWO, EXCHANGE_NAME, "BLACK");
        channel.queueBind(QUEUE_NAME_TWO, EXCHANGE_NAME, "GREEN");
        //发布消息  使用rabbitMQ自带的默认交换机  routingkey 叫什么  就把消息路由到哪个队列中  需要指定routingkey  只有routingkey一致 才会将消息路由到指定的队列
        for (int i = 0; i < 100; i++) {
            String message="Hello World"+i;
            channel.basicPublish(EXCHANGE_NAME, "ORANGE", null, message.getBytes());
            channel.basicPublish(EXCHANGE_NAME, "BLACK", null, message.getBytes());
            channel.basicPublish(EXCHANGE_NAME, "WHITE", null, message.getBytes());//没有队列和交换机绑定 white
        }

        System.out.println("消息发送成功");
        System.in.read();
    }
    @Test
    public void consumer1() throws Exception {
        //获取连接对象
        Connection connection = RoutingTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        //设置消息的流控 一次只消费一个  别一次性分发完后 让consumer自己慢慢消费 此设置是让consume消费完一条消息后再从channel中再获取下一条消息
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者一号获取到的消息:"+new String(body) );
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME_ONE, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }

    @Test
    public void consumer2() throws Exception {
        //获取连接对象
        Connection connection = RoutingTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);
        //设置消息的流控
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者二号获取到的消息:"+new String(body) );
                //deliveryTag 标识
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME_TWO, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }
}
复制代码
Topics 手动创建Exchange(TOPIC)   routing 规则  项目名+模块名+方法名
复制代码
@SpringBootTest
class TopicsTests {
    public static final String RABBITMQ_HOST="192.168.1.137";
    public static final Integer RABBITMQ_PORT=5672;
    public static final String RABBITMQ_USERNAME="guest";
    public static final String RABBITMQ_PASSWORD="guest";
    public static final String RABBITMQ_VIRTUAL_HOST="/";
    public static final String QUEUE_NAME_ONE="topic-one";
    public static final String QUEUE_NAME_TWO="topic-two";
    public static final String EXCHANGE_NAME="topic";
    //构建rabbitMQ链接对象
    public static Connection getConnection() throws IOException, TimeoutException {
        //创建connection工厂
         ConnectionFactory factory = new ConnectionFactory();
        //设置RabbitMq 连接信息
        factory.setHost(RABBITMQ_HOST);
        factory.setPort(RABBITMQ_PORT);
        factory.setUsername(RABBITMQ_USERNAME);
        factory.setPassword(RABBITMQ_PASSWORD);
        factory.setVirtualHost(RABBITMQ_VIRTUAL_HOST);
        //返回链接对象
        Connection connection = factory.newConnection();
        return connection;
    }
    @Test
    public void publish() throws IOException, TimeoutException {
        //获取连接对象
        Connection connection = TopicsTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建交换机 routing 类型交换机为DIRECT
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
        //构建队列  durable 队列是否持久化  exclusive 如果为true 只允许一个消费者消费  autoDelete 队列长时间没有使用 自动删除
        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);
        //绑定交换机和队列 使用的是TOPIC类型交换机,需要以aaa.bbb.ccc方式编写toutingkey
        //其中*(相当于占位符),#(相当于通配符)
        channel.queueBind(QUEUE_NAME_ONE, EXCHANGE_NAME, "*.orange.*");//aaa.orange.bbb
        channel.queueBind(QUEUE_NAME_TWO, EXCHANGE_NAME, "*.*.rabbit");//aaa.orange.rabbit  以上两个都会路由
        channel.queueBind(QUEUE_NAME_TWO, EXCHANGE_NAME, "lazy.#");//lazy.后面随便跟什么  都会路由到这里
        //发布消息  使用rabbitMQ自带的默认交换机  routingkey 叫什么  就把消息路由到哪个队列中  需要指定routingkey  只有routingkey一致 才会将消息路由到指定的队列
        for (int i = 0; i < 100; i++) {
            String message="Hello World"+i;
            channel.basicPublish(EXCHANGE_NAME, "big.orange.rabbit", null, message.getBytes());//路由两个
            channel.basicPublish(EXCHANGE_NAME, "small.white.rabbit", null, message.getBytes());//路由一个
            channel.basicPublish(EXCHANGE_NAME, "lazy.dog.dog.dog.dog.dog", null, message.getBytes());//匹配最后一个
        }

        System.out.println("消息发送成功");
        System.in.read();
    }
    @Test
    public void consumer1() throws Exception {
        //获取连接对象
        Connection connection = TopicsTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME_ONE, false, false, false, null);
        //设置消息的流控 一次只消费一个  别一次性分发完后 让consumer自己慢慢消费 此设置是让consume消费完一条消息后再从channel中再获取下一条消息
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者一号获取到的消息:"+new String(body) );
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME_ONE, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }

    @Test
    public void consumer2() throws Exception {
        //获取连接对象
        Connection connection = TopicsTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_NAME_TWO, false, false, false, null);
        //设置消息的流控
        channel.basicQos(1);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者二号获取到的消息:"+new String(body) );
                //deliveryTag 标识
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        };
        channel.basicConsume(QUEUE_NAME_TWO, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }
}
复制代码
RPC  

 

 
复制代码
@SpringBootTest
class RPCTests {
    public static final String RABBITMQ_HOST="192.168.1.137";
    public static final Integer RABBITMQ_PORT=5672;
    public static final String RABBITMQ_USERNAME="guest";
    public static final String RABBITMQ_PASSWORD="guest";
    public static final String RABBITMQ_VIRTUAL_HOST="/";
    public static final String QUEUE_PUBLISHER="rpc-publisher";
    public static final String QUEUE_CONSUMER="rpc-consumer";

    //构建rabbitMQ链接对象
    public static Connection getConnection() throws IOException, TimeoutException {
        //创建connection工厂
         ConnectionFactory factory = new ConnectionFactory();
        //设置RabbitMq 连接信息
        factory.setHost(RABBITMQ_HOST);
        factory.setPort(RABBITMQ_PORT);
        factory.setUsername(RABBITMQ_USERNAME);
        factory.setPassword(RABBITMQ_PASSWORD);
        factory.setVirtualHost(RABBITMQ_VIRTUAL_HOST);
        //返回链接对象
        Connection connection = factory.newConnection();
        return connection;
    }
    @Test
    public void publish() throws IOException, TimeoutException {
        //获取连接对象
        Connection connection = RPCTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_PUBLISHER, false, false, false, null);
        channel.queueDeclare(QUEUE_CONSUMER, false, false, false, null);
        //发布消息  使用rabbitMQ自带的默认交换机  routingkey 叫什么  就把消息路由到哪个队列中  需要指定routingkey  只有routingkey一致 才会将消息路由到指定的队列
        String uuid = UUID.randomUUID().toString();
        for (int i = 0; i < 100; i++) {
            String message="Hello World RPC"+i;
            AMQP.BasicProperties pros=new AMQP.BasicProperties()
                    .builder()
                    .replyTo(QUEUE_CONSUMER)
                    .correlationId(uuid)
                    .build();
            channel.basicPublish("", QUEUE_PUBLISHER, pros, message.getBytes());//路由两个
            channel.basicConsume(QUEUE_CONSUMER,false, new DefaultConsumer(channel){
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    String id = properties.getCorrelationId();
                    if(id!=null&&id.equals(uuid)){
                        System.out.println("接收到服务端响应"+new String(body,"utf-8"));
                    }
                    channel.basicAck(envelope.getDeliveryTag(), false);
                }
            });
        }
        System.out.println("消息发送成功");
        System.in.read();
    }
    @Test
    public void consumer1() throws Exception {
        //获取连接对象
        Connection connection = RPCTests.getConnection();
        //构建Channel
        Channel channel = connection.createChannel();
        //构建队列
        channel.queueDeclare(QUEUE_PUBLISHER, false, false, false, null);
        channel.queueDeclare(QUEUE_CONSUMER, false, false, false, null);
        //监听消息
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者一号获取到的消息:"+new String(body) );
                String resp="获取到了client信息";
                String responseQueueName = properties.getReplyTo();
                String uuid = properties.getCorrelationId();
                AMQP.BasicProperties pros=new AMQP.BasicProperties()
                        .builder()
                        .correlationId(uuid)
                        .build();
                channel.basicPublish("", responseQueueName, pros, resp.getBytes());
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(QUEUE_PUBLISHER, false, defaultConsumer);
        System.out.println("开始监听队列");
        System.in.read();
    }


}
复制代码

 

posted @   花心大萝卜li  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示