Spring Cloud Stream 分区键表达式(partitionKeyExpression)不能使用 payload.field

本文介绍了在使用Spring Cloud Stream遇到的分区键表达式错误,详细解析了不能使用`payload.field`的原因,并提供了两种解决方案:1) 将`payload.field`替换为`headers`设置;2) 自定义序列化方式。由于RabbitMQ Binder限制,使用`payload`可能涉及性能和序列化一致性问题,推荐使用`headers`字段以简化处理。
摘要由CSDN通过智能技术生成
背景

在使用 Spring Cloud Stream 进行分区操作的时候,发现 partitionKeyExpression 配置成 payload.field 并使用 StreamBridge 发送消息时,报了 SpelEvaluationException: EL1008E 错误

# 配置获取 Message 对象的哪个字段作为分区 key,如根据订单 id 作为 key 则写成 payload.orderId
spring.cloud.stream.bindings.<channelName>.producer.partitionKeyExpression=payload.orderId

在 Github 上找到了该问题的 issue: Using messageKeyExpression=payload.field with StreamBridge
根据 Set default SpEL to configure partition key expression for outbound messages 可以知道在旧版本的 Spring Cloud Stream 中是可以使用 payload.field 的,但在这个 commented 提到在并发的情况下 payload.field 会存在问题,因此不支持使用。

解决方案

先说解决方案,主要有以下两种方式:

  1. payload.field 方式换为 headers.field,意思是将字段设置到 headers

    // 伪代码
    MessageBuilder.withPayload(data).setHeader("field", 1).build();
    
  2. 报这个错误的根本原因是 Spring Cloud Stream 将 payload 由原来的对象转为了字节数组,可以通过自定义的序列化解决

    spring.cloud.stream.bindings.<channelName>.producer.use-native-encoding=true
    spring.cloud.stream.kafka.bindings.<channelName>.producer.configuration.key.serializer=org.apache.kafka.common.serialization.StringSerializer
    spring.cloud.stream.kafka.bindings.<channelName>.producer.configuration.value.serializer=org.springframework.kafka.support.serializer.JsonSerializer
    

需要注意的是,以上的序列化配置只针对 Kafka 有效,对于 RabbitMQ 通过追踪它的源码,似乎写死了 org.springframework.amqp.support.converter.SimpleMessageConverter 转换器,不支持自定义配置

public class
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值