Spring AMQP RabbitMQ RPC优先级队列

时间:2018-12-10 13:19:08

标签: rabbitmq spring-amqp spring-rabbitmq

我正在尝试建立一个RPC队列,在该队列中,来自生产者/客户端的消息将优先考虑给消费者。我希望所有优先级为2的消息都在优先级为1的消息之前处理。我还希望每个消费者一次能够处理10条消息。我能够让每个消费者一次处理10条消息。我无法使消息优先工作。下面是我的设置:

配置文件:

@Configuration
public class QueueConfig  { 
    public static final String QUEUE_NAME = "requests";

    private int maxPriority = 2;

    @Autowired
    private ConnectionFactory connectionFactory;

    @Bean
    public Queue requests() {
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("x-max-priority", maxPriority);
        return new Queue(QUEUE_NAME,true,false,false, args);
    }

    @Bean
    public Queue replies() {
        Map<String, Object> args = new HashMap<String, Object>();
        args.put("x-max-priority", maxPriority);
        return new Queue("replies",true,false,false, args);
    }  

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
        container.setQueueNames(replies().getName());
        return container;
    }

    @Bean
    public RabbitTemplate template() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setRoutingKey(requests().getName());
        return rabbitTemplate;
    }

    @Bean
    public AsyncRabbitTemplate asyncRabbitTemplate(RabbitTemplate rabbitTemplate, SimpleMessageListenerContainer container) {
        AsyncRabbitTemplate asyncRabbitTemplate = new AsyncRabbitTemplate(rabbitTemplate, container);
        asyncRabbitTemplate.setReceiveTimeout(90000);
        return asyncRabbitTemplate;
    }        
}

客户/制作人:

@Component
public class Client {
    @Autowired
    private AsyncRabbitTemplate template;

    public void sendHigh(String name) {

        MessagePostProcessor messageProcessor = new MessagePostProcessor() {

            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setPriority(2);
                return message;
            }
        };

        ListenableFuture<String> response = template.convertSendAndReceive(QueueConfig.QUEUE_NAME, (Object) name,(MessagePostProcessor) messageProcessor);
        try {
            response.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public void sendLow(String name) {

        MessagePostProcessor messageProcessor = new MessagePostProcessor() {

            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setPriority(1);
                return message;
            }
        };

        ListenableFuture<String> response = template.convertSendAndReceive(QueueConfig.QUEUE_NAME, (Object) name,(MessagePostProcessor) messageProcessor);
        try {
            response.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

配置文件2:

@Configuration
@EnableAsync
public class ServiceConfig implements AsyncConfigurer {

    @Override
    @Bean
    public Executor getAsyncExecutor() {
        return new SimpleAsyncTaskExecutor();
    }


}

消费者:

@Component
public class Consumer  {

    @RabbitListener(queues = QueueConfig.QUEUE_NAME)
    public String consume(@Payload String name) {
        System.out.println("Request Consumer " + name);
        String result = name;
        if(result.equals("john") || result.equals("john1")) {
            try {
                Thread.sleep(22000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return result;
    }

Application.properties:

spring.rabbitmq.dynamic=true
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.host=localhost
spring.rabbitmq.listener.simple.concurrency=10
spring.rabbitmq.listener.direct.acknowledge-mode=MANUAL

Junit:

我希望所有的john和john1都会在jeff之前被消费者接收,但这不是我所看到的行为。基本上,我正在查看此println并期望所有john和john1都将在jeff System.out.println(“ Request Consumer” + name);

之前打印
@RunWith(SpringRunner.class)
@ComponentScan(basePackages = "com.test.test")
@EnableAutoConfiguration
@SpringBootTest
public class ApplicationTests {

    @Autowired AsyncClass asyncClass;

    @Test
    public void contextLoads() throws InterruptedException, ExecutionException {
        List<Future<String>> futures = new ArrayList<>();
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        futures.add(asyncClass.runAsyncHigh("john"));
        Thread.sleep(1000);
        futures.add(asyncClass.runAsyncLow("jeff"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));
        futures.add(asyncClass.runAsyncHigh("john1"));

        for(Future<String> future : futures) {
            future.get();
        }


    }

@Component 公共类AsyncClass {

@Autowired Client client;

@Async
public Future<String> runAsyncHigh(String name){
    client.sendHigh(name);
    return new AsyncResult<String>(name);
}

@Async
public Future<String> runAsyncLow(String name){
    client.sendLow(name);
    return new AsyncResult<String>(name);
}

}

谢谢, 布莱恩

0 个答案:

没有答案