什么会导致Kafka序列化异常?

时间:2019-01-13 20:52:18

标签: java spring-boot apache-kafka spring-kafka

我有一个小型的Spring Boot项目,旨在使用来自其中的消息。

我的服务行为异常,因为一则消息出现在Kafka中,并引发了异常。

这里是例外:

org.apache.kafka.common.errors.SerializationException: Error deserializing key/value for partition persistSubscription-0 at offset 5. If needed, please seek past the record to continue consumption.
    Caused by: java.lang.IllegalArgumentException: The class 'com.polubentcev.messenger.subscription.model.Subscription' is not in the trusted packages: [java.util, java.lang, com.polubentcev.messenger.subscription.repository.model]. If you believe this class is safe to deserialize, please provide its name. If the serialization is only done by a trusted source, you can also enable trust all (*).

这是我的@Configuration班:

@EnableKafka
@Configuration
public class KafkaConfiguration {

    private final String bootstrapServers;

    private final String consumerGroupId;

    public KafkaConfiguration(@Value("${kafka.bootstrap-servers}") final String bootstrapServers,
                              @Value("${kafka.consumer.group-id}") final String consumerGroupId) {
        this.bootstrapServers = bootstrapServers;
        this.consumerGroupId = consumerGroupId;
    }

    @Bean
    public KafkaTemplate<String, Subscription> kafkaSubscriptionTemplate() {
        final ProducerFactory<String, Subscription> producerFactory = new DefaultKafkaProducerFactory<>(kafkaProps());
        return new KafkaTemplate<>(producerFactory);
    }

    @Bean
    public KafkaTemplate<String, UserSubscriptions> kafkaUserSubscriptionsTemplate() {
        final ProducerFactory<String, UserSubscriptions> producerFactory =
                new DefaultKafkaProducerFactory<>(kafkaProps());
        return new KafkaTemplate<>(producerFactory);
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Subscription> kafkaListenerSubscriptionContainerFactory() {
        final Map<String, Object> props = kafkaProps();
        props.put(ConsumerConfig.GROUP_ID_CONFIG, consumerGroupId);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonSerializer.class);
        final ConsumerFactory<String, Subscription> consumerFactory = new DefaultKafkaConsumerFactory<>(
                props, new StringDeserializer(), new JsonDeserializer<>(Subscription.class));
        final ConcurrentKafkaListenerContainerFactory<String, Subscription> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory);
        return factory;
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, UserSubscriptions>
    kafkaListenerUserSubscriptionsContainerFactory() {
        final Map<String, Object> props = kafkaProps();
        props.put(ConsumerConfig.GROUP_ID_CONFIG, consumerGroupId);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringSerializer.class);
        final ConsumerFactory<String, UserSubscriptions> consumerFactory = new DefaultKafkaConsumerFactory<>(
                props, new StringDeserializer(), new JsonDeserializer<>(UserSubscriptions.class));
        final ConcurrentKafkaListenerContainerFactory<String, UserSubscriptions> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory);
        return factory;
    }

    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, User> kafkaListenerUserContainerFactory() {
        final Map<String, Object> props = kafkaProps();
        props.put(ConsumerConfig.GROUP_ID_CONFIG, consumerGroupId);
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringSerializer.class);
        final ConsumerFactory<String, User> consumerFactory = new DefaultKafkaConsumerFactory<>(
                props, new StringDeserializer(), new JsonDeserializer<>(User.class));
        final ConcurrentKafkaListenerContainerFactory<String, User> factory =
                new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(consumerFactory);
        return factory;
    }

    private Map<String, Object> kafkaProps() {
        final Map<String, Object> props = new HashMap<>();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(JsonDeserializer.TRUSTED_PACKAGES, "*");
        return props;
    }

}

Subscription类:

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Builder(toBuilder = true)
public final class Subscription {

    private String id;

    private User firstUser;

    private User secondUser;

    private Status firstUserStatus;

    private Status secondUserStatus;

    public Subscription(final User firstUser, final User secondUser, final Status firstUserStatus,
                        final Status secondUserStatus) {
        this.id = null;
        this.firstUser = firstUser;
        this.secondUser = secondUser;
        this.firstUserStatus = firstUserStatus;
        this.secondUserStatus = secondUserStatus;
    }

    public Subscription(final SubscriptionEntity entity, final Map<String, User> userMap) {
        this.id = entity.getId();
        this.firstUser = userMap.get(entity.getFirstUserId());
        this.secondUser = userMap.get(entity.getSecondUserId());
        this.firstUserStatus = entity.getFirstUserStatus();
        this.secondUserStatus = entity.getSecondUserStatus();
    }

    public enum Status {

        ISSUED, ACTION_EXPECTED, APPROVED, DECLINED

    }

}

最后是消费者类:

@Component
public class SubscriptionConsumerImpl implements SubscriptionConsumer {

    private final SubscriptionService subscriptionService;

    @Autowired
    public SubscriptionConsumerImpl(final SubscriptionService subscriptionService) {
        this.subscriptionService = subscriptionService;
    }

    @Override
    @KafkaListener(topics = PERSIST_SUBSCRIPTION, groupId = MESSENGER_SUBSCRIPTION,
            containerFactory = "kafkaListenerSubscriptionContainerFactory")
    public void receive(@Payload final Subscription subscription) {
        subscriptionService.save(subscription);
    }

}

您能帮我找出错误吗?我敢打赌,问题出在Kafka配置中。

0 个答案:

没有答案