es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Es posible enganchar un manejador personalizado antes de un basicGet () en Spring AMQP?

Tengo un manejador de mensajes que está anotado con @RabbitHandler el cual recoge y procesa mensajes de la cola.

Caso de uso

Durante los momentos de despliegue, la instancia no debería estar recogiendo ningún mensaje de la cola. ¿Hay algún lugar donde pueda detener y verificar si mi instancia se encuentra bloqueada (leyendo desde la base de datos para verificar), y así detener la recepción de mensajes? He verificado que tenemos setAfterReceivePostProcessors, pero lo que en realidad estoy buscando es algo como beforeReceiveProcessor para solucionar mi caso de uso de verificar y no hacer polling del todo. No debería estar llegando a mi método @RabbitHandler en absoluto. ¿Es posible lograr este nivel de control?

Si no es posible, ¿es la única forma posible escribir un recolector personalizado?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Como experto en tecnología de la información especializado en rabbitmq y spring-rabbit, puedo sugerir las siguientes soluciones para el caso de uso mencionado:

    Opción 1: Usar Consumidores Condicionales

    Una solución posible es utilizar Consumidores Condicionales. Esta característica permite que la instancia reciba mensajes sólo si se cumple una cierta condición. Esto se puede lograr utilizando las clases ConditionalRejectingErrorHandler y ConditionalRejectingMessageListenerContainer en spring-rabbit.

    Por ejemplo:

    @Bean
    public MessageListenerContainer simpleMessageListenerContainer(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("nombre-de-tu-cola");
        container.setMessageListener(tuMessageListener());
        container.setErrorHandler(new ConditionalRejectingErrorHandler(tuCondicion()));
        return container;
    }
    

    En este ejemplo, tuCondicion() debería devolver verdadero o falso dependiendo de si la instancia debería recibir mensajes o no.

    Opción 2: Usar un Asesoramiento Personalizado

    Otra solución posible es usar un Asesoramiento Personalizado. Spring-rabbit provee una manera sencilla de interceptar mensajes antes de que sean procesados. Esto se puede lograr implementando la interfaz MethodBeforeAdvice y agregando tu implementación como beforeAdvice a la instancia SimpleMessageListenerContainer.

    Por ejemplo:

    @Bean
    public MessageListenerContainer simpleMessageListenerContainer(ConnectionFactory connectionFactory) {
    
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("nombre-de-tu-cola");
        container.setMessageListener(tuMessageListener());
    
        container.setAdviceChain(new MethodBeforeAdvice[] { 
            new TuAsesoramientoPersonalizado() // agrega aquí tu asesoramiento personalizado
        });
    
        return container;
    }
    

    En este ejemplo, TuAsesoramientoPersonalizado debería implementar la interfaz MethodBeforeAdvice y comprobar si la instancia está autorizada para recibir mensajes antes de que los mensajes sean procesados. Si la instancia no está autorizada para recibir mensajes, el método before debería generar una excepción para detener el procesamiento de mensajes.

    Opción 3: Escribir un Encuestador Personalizado

    Si las soluciones anteriores no satisfacen tus requisitos, puedes escribir un Encuestador Personalizado. En este caso, tendrás control total sobre cuándo se reciben y procesan los mensajes. Sin embargo, esta solución requiere más código y puede ser más difícil de mantener.

    Por ejemplo:

    @Bean
    public SimpleMessageListenerContainer customMessageListenerContainer(ConnectionFactory connectionFactory) {
    
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("nombre-de-tu-cola");
    
        // aquí va tu implementación de encuestador personalizado
        container.setTaskExecutor(tuExecutorDeEncuestadorPersonalizado());
        container.setConcurrentConsumers(1);
    
        return container;
    }
    

    En este ejemplo, tuExecutorDeEncuestadorPersonalizado() debería devolver un ThreadPoolTaskExecutor o cualquier otra implementación de Executor que satisfaga tus necesidades. Este ejecutor será utilizado para encuestar los mensajes y llamar a tu implementación personalizada de manipulador de mensajes.

Comments are closed.