producer序列化与consumer反序列化

583 阅读2分钟

介绍

Kafka为一些基本的数据类型提供了默认的序列化器。如无特殊需要,不建议使用自定义的序列化器或反序列化器,因为这样会增加生产者与消费者之间的耦合度,在系统升级换代的时候很容易出错。

对于String类型来说,生产者采用StringSerializer,消费者可以顺其自然地采用 StringDeserializer ,不过某个类Entity而言,某个上游应用采用EntitySerializer 进行序列化之后,下游应用也必须实现对应的EntityDeserializer 。再者,如果Entity类型改变,那么序列化器和反序列化器也需要跟着重新实现,比较麻烦。

在使用的时候,可以利用JSON工具将发送的消息类型转换成String,然后通过kafka客户端提供的StringSerializer、StringDeserializer完成序列化和反序列化。反过来,也可以在自定义的序列化器中,利用通用的工具包装。

自定义序列化器

假设要发送消息的类型如下

public class Entity {
    private String name;
    private Integer age;
}

序列化和反序列化器都是利用JSON包了一下,有要求也可以自己定制,主要是记录一下模板

public class EntitySerializer implements Serializer<Entity> {
    @Override
    public void configure(Map<String, ?> map, boolean b) {

    }

    @Override
    public byte[] serialize(String topic, Entity data) {
        if (data == null) {
            return null;
        }
        return JSON.toJSONString(data).getBytes();
    }

    @Override
    public void close() {

    }
}
public class EntityDeserializer implements Deserializer<Entity> {
    @Override
    public void configure(Map<String, ?> map, boolean b) {

    }

    @Override
    public Entity deserialize(String topic, byte[] data) {
        if (data == null) {
            return null;
        }
        return JSON.parseObject(new String(data), Entity.class);
    }

    @Override
    public void close() {

    }
}

在producer和consumer的配置文件分别中指定一下

properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, EntitySerializer.class.getName());
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, EntityDeserializer.class.getName());

观察打印日志,可以看到使用了自定义的序列化器,且发送和接收都正常