在春季收听许多Kafka流

时间:2018-11-25 14:03:58

标签: java spring apache-kafka spring-kafka

我正在使用事件驱动的体系结构开发应用程序。

我正在尝试对以下事件流进行建模:

UserAccountCreated(用户管理事件)->发送电子邮件-> MailNotificationSent(通知服务事件)

通知服务应用程序执行整个流程。通过侦听 user-management-events 主题,它等待 UserAccountCreated 事件。收到事件后,应用程序将发送电子邮件并向 notification-service-events 主题发布新事件- MailNotificationSent

我在监听第一个事件( UserAccountCreated )时没有问题-应用程序接收到该事件并执行其余流程。发布 MailNotificationSent 事件也没有问题。不幸的是,出于开发目的,我想监听通知服务中的 MailNotificationSent 事件,因此应用程序必须监听 UserAccountCreated MailNotificationSent >。在这里,我无法使其正常工作。

让我们看一下实现:

NotificationStreams:

public interface NotificationStreams {

    String INPUT = "notification-service-events-in";
    String OUTPUT = "notification-service-events-out";

    @Input(INPUT)
    SubscribableChannel inboundEvents();

    @Output(OUTPUT)
    MessageChannel outboundEvents();
}

NotificationsEventsListener:

@Slf4j
@Component
@RequiredArgsConstructor
public class NotificationEventsListener {


    @StreamListener(NotificationStreams.INPUT)
    public void notificationServiceEventsIn(Flux<ActivationLinkSent> input) {
        input.subscribe(event -> {
            log.info("Received event ActivationLinkSent: " + event.toString());
        });
    }
}

UserManagementEvents:

public interface UserManagementEvents {

    String INPUT = "user-management-events";

    @Input(INPUT)
    SubscribableChannel inboundEvents();
}

UserManagementEventsListener:

@Slf4j
@Component
@RequiredArgsConstructor
public class UserManagementEventsListener {

    private final Gate gate;

    @StreamListener(UserManagementEvents.INPUT)
    public void userManagementEvents(Flux<UserAccountCreated> input) {
        input.subscribe(event -> {
            log.info("Received event UserAccountCreated: " + event.toString());
            gate.dispatch(SendActivationLink.builder()
                .email(event.getEmail())
                .username(event.getUsername())
                .build()
            );
        });
    }
}

KafkaStreamsConfig:

@EnableBinding(value = {NotificationStreams.class, UserManagementEvents.class})
public class KafkaStreamsConfig {
}

EventPublisher:

@Slf4j
@RequiredArgsConstructor
@Component
public class EventPublisher {

    private final NotificationStreams eventsStreams;

    private final AvroMessageBuilder messageBuilder;

    public void publish(Event event) {
        MessageChannel messageChannel = eventsStreams.outboundEvents();

        AvroActivationLinkSent activationLinkSent = new AvroActivationLinkSent();                         activationLinkSent.setEmail(((ActivationLinkSent)event).getEmail());
        activationLinkSent.setUsername(((ActivationLinkSent)event).getUsername() + "-domain");
        activationLinkSent.setTimestamp(System.currentTimeMillis());
        messageChannel.send(messageBuilder.buildMessage(activationLinkSent));
    }
}

应用程序配置:

spring:
  devtools:
    restart:
      enabled: true
  cloud:
    stream:
      default:
        contentType: application/*+avro
      kafka:
        binder:
          brokers: localhost:9092
      schemaRegistryClient:
        endpoint: http://localhost:8990
  kafka:
    consumer:
      group-id: notification-group
      auto-offset-reset: earliest
kafka:
  bootstrap:
    servers: localhost:9092

应用程序似乎忽略了通知服务事件侦听器。仅收听一个流时,它有效。

我几乎100%确信这与发布事件无关,因为我已手动连接到Kafka并验证了消息是否已正确发布:

kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic notification-service-events-out --from-beginning

您有什么想法我还要检查吗? Spring端是否还有其他配置?

1 个答案:

答案 0 :(得分:0)

我找到了问题所在。 我缺少绑定配置。在应用程序属性中,我应该添加以下行:

cloud:
 stream:
  bindings:
    notification-service-events-in:
      destination: notification-service-events
    notification-service-events-out:
      destination: notification-service-events
    user-management-events-in:
      destination: user-management-events

在用户管理服务中,我没有这样的问题,因为我使用了其他属性:

  cloud:
   stream:
    default:
      contentType: application/*+avro
      destination: user-management-events