Spring AMQP优先级消息

时间:2016-09-11 12:48:55

标签: java spring rabbitmq amqp spring-rabbit

RabbitMQ中队列中的消息优先级。它正在与rabbitmq一起提供java客户端。但它不适用于春兔依赖。请看一看。

  • RabbitMQ服务器版本 - 3.6.5
  • Erlang - OTP 19(8.0)

使用 RabbitMQ Java客户端
Pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework.samples</groupId>
    <artifactId>RabbitMQ</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <developers>
        <developer>
            <name>Sagar Rout</name>
        </developer>
    </developers>

    <properties>
        <!-- Generic properties -->
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring -->
        <spring-framework.version>4.3.2.RELEASE</spring-framework.version>
    </properties>

    <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Spring AMQP -->
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>1.6.1.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>  

Publisher.java

public class Publisher {

private final static String QUEUE_NAME = "S1_Priority";

public static void main(String[] argv) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();
    Map<String, Object> args = new HashMap<String, Object>();
    args.put("x-max-priority", 10);
    channel.queueDeclare(QUEUE_NAME, false, false, false, args);
    String message = "Hello World!";

    for (int i = 0; i < 10; i++) {
        channel.basicPublish("", QUEUE_NAME,
                new AMQP.BasicProperties.Builder().contentType("text/plain").deliveryMode(2).priority(i).build(),
                message.getBytes("UTF-8"));
        System.out.println(" [x] Sent '" + message + "'" + "priority" + i);
    }
    channel.close();
    connection.close();
}}  

Consumer.Java

public class Consumer {

private final static String QUEUE_NAME = "S1_Priority";

public static void main(String[] argv) throws Exception {
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();
    Map<String, Object> args = new HashMap<String, Object>();
    args.put("x-max-priority", 10);
    channel.queueDeclare(QUEUE_NAME, false, false, false, args);
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

    DefaultConsumer consumer = new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
                byte[] body) throws IOException {
            String message = new String(body, "UTF-8");
            System.out.println(" [x] Received '" + message + "'" + properties.getPriority());
        }
    };
    channel.basicConsume(QUEUE_NAME, true, consumer);
}}  

这是有效的,并且正在出现具有更高优先级的消息。但它不适用于Spring-rabbit。请找到代码 RabbitMQConfig.class

@Configuration
@ComponentScan(basePackages = { "com.blackocean.*" })
@PropertySource("classpath:config.properties")
public class RabbitMQConfig {

@Value("${rabbitmq.host}")
private String host;

@Value("${rabbitmq.port}")
private Integer port;

@Value("${rabbitmq.username}")
private String username;

@Value("${rabbitmq.password}")
private String password;

@Value("${rabbitmq.connection.size}")
private Integer connectionSize ;

@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
    return new PropertySourcesPlaceholderConfigurer();
}

@Bean
public ConnectionFactory connectionFactory() {

    CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
    cachingConnectionFactory.setHost(host);
    cachingConnectionFactory.setPort(port);
    cachingConnectionFactory.setUsername(username);
    cachingConnectionFactory.setPassword(password);
    cachingConnectionFactory.setConnectionLimit(connectionSize);

    return cachingConnectionFactory;
}

@Bean
public RabbitAdmin rabbitAdmin() {
    return new RabbitAdmin(connectionFactory());
}

@Bean
public RabbitTemplate rabbitTemplate() {
    return new RabbitTemplate(connectionFactory());
}

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

SendUsingJavaConfig

public class Send1UsingJavaConfig {

/**
 * @param args
 */
public static void main(String[] args) {

    ApplicationContext context = new AnnotationConfigApplicationContext(RabbitMQConfig.class);
    RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);

        rabbitTemplate.convertAndSend("", "myQueue", "Hi Mr.Ocean 10", new MessagePostProcessor() {

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

接收JavaConfig

public class RecvUsingJavaConfig {

public static void main(String[] args) {
    ApplicationContext context = new AnnotationConfigApplicationContext(RabbitMQConfig.class);
    RabbitTemplate rabbitTemplate = context.getBean(RabbitTemplate.class);

    // Basic Example
    String message = (String) rabbitTemplate.receiveAndConvert("myQueue");
    System.out.println(message);
}}  

Config.properties

#RabbitMQ
rabbitmq.host=localhost
#Always provide port and connection size in numbers
rabbitmq.port=5672
rabbitmq.username=guest
rabbitmq.password=guest
rabbitmq.connection.size=100

现在我发送的邮件具有不同的优先级,但它始终在订单中收到邮件。任何建议都会很棒!!!

3 个答案:

答案 0 :(得分:4)

这里只是一个猜测,我试着查看我曾经使用的旧AMQP库(旧版本的Rabbit MQ中的优先级队列)。

优先级设置如下

args.put("x-max-priority", 10); ,它与args.put("x-priority", 10);略有不同。

您可以在链接中引用旧priority queue repo。您可以尝试查看是否有帮助

答案 1 :(得分:0)

如果任何人对消息优先级有类似要求,则需要在创建队列之前定义优先级(配置类)。如果您打算将配置应用于现有队列,则该配置将不起作用(根据我的测试)。

@Value("${myApp.rabbitmq.queue}")
private String queueName;

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

当您将消息推送到队列中时,请确保优先级不超过10,因为我们已将队列上的最大优先级定义为10。

BR,桑索什

答案 2 :(得分:0)

  1. 队列必须具有arg'x-max-priority'。
  2. 发布messageProperties.priority不得为0。
  3. 使用spring-boot amqp时,进行设置很重要

    spring.rabbitmq.listener.simple.prefetch=1

否则,spring-boot将获取250条消息,而这些消息完全忽略了优先级。