簡體   English   中英

Spring Cloud Stream不使用Kafka頻道綁定器發送消息

[英]Spring Cloud Stream doesn't use Kafka channel binder to send a message

我正在嘗試實現以下目標:

使用帶有Kafka活頁夾的Spring Cloud Stream 2.1.3.RELEASE將消息發送到輸入通道,並實現發布訂閱行為,在該行為中,將通知每個消費者,並能夠處理發送到Kafka主題的消息。

我了解,在卡夫卡,如果每個消費者都屬於其自己的消費者組,則他們將能夠閱讀主題中的每條消息。 在我的情況下,spring為我的spring boot應用程序運行的每個實例創建了一個匿名的唯一使用者組。 Spring Boot應用程序只有一個配置為偵聽輸入通道的流偵聽器。

測試案例:

使用綁定到Kafka主題的輸入通道配置了示例Spring Cloud Stream應用程序。 使用spring rest控制器將消息發送到輸入通道,以期望該消息將傳遞到每個正在運行的spring boot應用程序實例。 在兩個應用程序啟動時,我都能看到kafka分區已正確分配。

問題:

但是,當我使用output()。send()發送消息時,spring甚至不會向配置的Kafka主題發送消息,而是在同一線程中觸發同一應用程序實例的@StreamListener方法。

在調試期間,我看到spring代碼具有兩個消息處理程序。 StreamListenerMessageHandler和KafkaProducerMessageHandler。 Spring只是將它們鏈接在一起,如果第一個處理程序以成功結束,那么它甚至不會走得更遠。 StreamListenerMessageHandler只需在同一線程中調用我的@StreamListener方法,消息就永遠不會到達Kafka。

題:

這是設計使然,為什么呢? 如何實現帖子開頭提到的行為?

PS。 如果我使用KafkaTemplate和@KafkaListener方法,那么它將按我的要求工作。 消息發送到Kafka主題,並且兩個應用程序實例都接收消息,並使用Kafka偵聽器注釋的方法處理消息。

碼:

流偵聽器方法按以下方式配置:

@SpringBootApplication
@EnableBinding(Processor.class)
@EnableTransactionManagement
public class ProcessorApplication {

private Logger logger = 
LoggerFactory.getLogger(this.getClass().getName());

private PersonRepository repository;

public ProcessorApplication(PersonRepository repository) {

    this.repository = repository;
}

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

}

@Transactional
@StreamListener(Processor.INPUT)
@SendTo(Processor.OUTPUT)
public PersonEvent process(PersonEvent data) {
    logger.info("Received event={}", data);
    Person person = new Person();
    person.setName(data.getName());

    logger.info("Saving person={}", person);

    Person savedPerson = repository.save(person);

    PersonEvent event = new PersonEvent();
    event.setName(savedPerson.getName());
    event.setType("PersonSaved");
    logger.info("Sent event={}", event);
    return event;
   }
  }

將消息發送到輸入通道:

@RestController()
@RequestMapping("/persons")
public class PersonController {

@Autowired
private Sink sink;


  @PostMapping("/events")
  public void createPerson(@RequestBody PersonEvent event) {

      sink.input().send(MessageBuilder.withPayload(event).build());
  }


}

Spring Cloud Stream配置:

spring:
  cloud.stream:
    bindings:
        output.destination: person-event-output
        input.destination: person-event-input

sink.input().send

您將完全繞開活頁夾,並將其直接發送到流偵聽器。

您需要將消息發送到kafka(到person-event-input主題),然后每個流偵聽器都將從kafka接收消息。

您需要配置另一個output綁定,然后將其發送到那里,而不是直接發送到輸入通道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM