De forma asincrónica cometer un mensaje justo después de la lectura del tema

MrPotatoServer:

Estoy tratando de cometer un mensaje justo después de la lectura del tema. He seguido este enlace ( https://www.confluent.io/blog/apache-kafka-spring-boot-application ) para crear un consumidor Kafka con la primavera. Normalmente funciona perfecto y el consumidor recibe el mensaje y espera hasta anotherone entra en la cola. Pero el problema es que cuando proceso estos mensajes se tarda mucho tiempo (alrededor de 10 minutos), la cola de kafka piensa que el mensaje no se consume (comprometido) y los consumidores lee una y otra vez. Tengo que decir que cuando mi tiempo de proceso es menos de 5 minutos funciona bien pero cuando Lastas ya no se compromete el mensaje.

He buscado algunas respuestas en torno pero no me ayuda porque no estoy usando el mismo código fuente (y, por supuesto, una estructura diferente). He intentado enviar métodos asincrónicos y también para cometer de forma asíncrona el mensaje, pero no lo he logrado. Algunas de las fuentes son:

Primavera de arranque Kafka: Commit no puede ser completado desde que el grupo ya ha reequilibrado

https://www.confluent.io/blog/tutorial-getting-started-with-the-new-apache-kafka-0-9-consumer-client/

https://dzone.com/articles/kafka-clients-at-most-once-at-least-once-exactly-o

Kafka 0,10 Java consumidor no leer mensaje del tema

https://github.com/confluentinc/confluent-kafka-dotnet/issues/470

La clase principal está aquí:


@SpringBootApplication
@EnableAsync
public class SpringBootKafkaApp {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootKafkaApp .class, args);
    }


La clase de los consumidores (donde tengo que comprometer mi mensaje)

@Service
public class Consumer {

@Autowired
    AppPropert prop;

   Consumer cons;
@KafkaListener(topics = "${app.topic.pro}", groupId = "group_id")
    public void consume(String message) throws IOException {
        /*HERE I MUST CONSUME THE MESSAGE AND COMMIT IT */

        Properties  props=prope.startProp();//just getting my properties from my config-file
        ControllerPRO pro = new ControllerPRO();

        List<Future<String>> async= new ArrayList<Future<String>>();//call this method asynchronous, doesn't help me
        try {

            CompletableFuture<String> ret=pro.processLaunch(message,props);//here I call the process method 
            /*This works fine when the processLaunch method takes less than 5 minutes, 
            if it takes longer the consumer will get the same message from the topic and start again with this operation 
            */

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("End of consumer method ");

    }

    }


¿Cómo puedo cometer el mensaje justo después de que lo leí de la cola.

Quiero estar seguro de que cuando recibo el mensaje cometo el mensaje inmediatamente. En este momento el mensaje está comprometida cuando termine de ejecutar el método justo después de la (System.out.println). Entonces, ¿puede alguien decirme cómo hacer esto?

----- ------- actualización

Lo siento por la respuesta tardía pero como @GirishB sugirió que he estado buscando a la configuración de GirishB pero no veo donde puedo definir el tema que quiero leer / escuchar de mi archivo de configuración (applications.yml). Todos los ejemplos que consulte uso de una estructura similar a este ( http://tutorials.jenkov.com/java-util-concurrent/blockingqueue.html ). ¿Hay alguna opción que puedo leer un tema que se declara en otro servidor? El uso de algo similar a esto @KafkaListener (temas = "$ {} app.topic.pro", groupId = "group_id")

=========== SOLUCIÓN 1 ===================================== ===

Seguí @victor consejos Gallet y contó con la declaración de los porperties confumer en oder para acomodar el objeto "acuse" en el método consumen. También he seguido este enlace ( https://www.programcreek.com/java-api-examples/?code=SpringOnePlatform2016/grussell-spring-kafka/grussell-spring-kafka-master/s1p-kafka/src/main /java/org/s1p/CommonConfiguration.java ) para obtener todos los métodos que he utilizado para declarar y configurar todas las propiedades (consumerProperties, consumerFactory, kafkaListenerContainerFactory). El único problema que he encontrado es el "nuevo SeekToCurrentErrorHandler ()" declaración porque estoy recibiendo un error y por el momento no soy capaz de resolverlo (Sería muy bueno si alguien me lo explique).


@Service
public class Consumer {

@Autowired
    AppPropert prop;

   Consumer cons;


   @Bean
    public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory();

        factory.setConsumerFactory(consumerFactory());
        factory.getContainerProperties().setAckOnError(false);
        factory.getContainerProperties().setAckMode(AckMode.MANUAL_IMMEDIATE);
        //factory.setErrorHandler(new SeekToCurrentErrorHandler());//getting error here despite I've loaded the library
        return factory;
    }

    @Bean
    public ConsumerFactory<String, String> consumerFactory() {
        return new DefaultKafkaConsumerFactory<>(consumerProperties());
    }

     @Bean
    public Map<String, Object> consumerProperties() {
        Map<String, Object> props = new HashMap<>();
        Properties  propsManu=prop.startProperties();// here I'm getting my porperties file where I retrive the configuration from a remote server (you have to trust that this method works)
        //props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, this.configProperties.getBrokerAddress());
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, propsManu.getProperty("bootstrap-servers"));
        //props.put(ConsumerConfig.GROUP_ID_CONFIG, "s1pGroup");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, propsManu.getProperty("group-id"));
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 15000);
        //props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, propsManu.getProperty("key-deserializer"));
        //props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, propsManu.getProperty("value-deserializer")); 
        return props;
    }




    @KafkaListener(topics = "${app.topic.pro}", groupId = "group_id")
    public void consume(String message) throws IOException {
        /*HERE I MUST CONSUME THE MESSAGE AND COMMIT IT */
        acknowledgment.acknowledge();// commit immediately
        Properties  props=prop.startProp();//just getting my properties from my config-file
        ControllerPRO pro = new ControllerPRO();

        List<Future<String>> async= new ArrayList<Future<String>>();//call this method asynchronous, doesn't help me
        try {

            CompletableFuture<String> ret=pro.processLaunch(message,props);//here I call the process method 
            /*This works fine when the processLaunch method takes less than 5 minutes, 
            if it takes longer the consumer will get the same message from the topic and start again with this operation 
            */

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("End of consumer method ");

    }

    }

``````````````````````````````````````````````````````````
Victor Gallet:

Tiene que modificar su configuation del consumidor con la propiedad enable.auto.commitconjunto false:

properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);

A continuación, tiene que modificar fábrica de primavera Kafka Oyente y establecer el modo de acuse de recibo-a MANUAL_IMMEDIATE. Aquí está un ejemplo de ConcurrentKafkaListenerContainerFactory:

@Bean
public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory();
    factory.setConsumerFactory(consumerFactory());
    factory.getContainerProperties().setAckOnError(false);
    factory.getContainerProperties().setAckMode(AckMode.MANUAL_IMMEDIATE);
    factory.setErrorHandler(new SeekToCurrentErrorHandler());
    return factory;
}

Como se explica a partir de documentación, MANUAL_IMMEDIATEmedios: Commit el desplazamiento inmediatamente cuando el método Acknowledgment.acknowledge () es llamado por el oyente.

Puede encontrar todos los métodos que cometen aquí .

Luego, en el código de escucha, puede cometer el desplazamiento manualmente mediante la adición de un Acknowledgmentobjeto, por ejemplo:

@KafkaListener(topics = "${app.topic.pro}", groupId = "group_id")
public void consume(String message, Acknowledgment acknowledgment) {
   // commit immediately
    acknowledgment.acknowledge();
}

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=206249&siteId=1
Recomendado
Clasificación