在Spring Cloud Streams中将消息发送到DLQ之前添加自定义信息

在Spring Cloud Streams中将消息发送到DLQ之前添加自定义信息,spring,spring-cloud-stream,spring-retry,Spring,Spring Cloud Stream,Spring Retry,我使用的是SpringCloudStreams和默认的Spring重试机制,只使用属性。它工作正常,消息被重试,然后转到DLQ。。。到目前为止一切都很好。现在问题来了 我需要在邮件中添加一些自定义信息,然后再将其从我的服务转到DLQ。它们足够简单,可以帮助我识别失败的消息,而无需接触一般的有效负载 可能我可以添加自定义标题或将其包装在已知模型中,在该模型中,我可以检索我需要的信息—无论是哪种方式,我都需要截取/修改消息 最简单的方法是什么,不用花很多钱?我的意思是,我们只是使用简单的配置来进行重

我使用的是SpringCloudStreams和默认的Spring重试机制,只使用属性。它工作正常,消息被重试,然后转到DLQ。。。到目前为止一切都很好。现在问题来了

我需要在邮件中添加一些自定义信息,然后再将其从我的服务转到DLQ。它们足够简单,可以帮助我识别失败的消息,而无需接触一般的有效负载

可能我可以添加自定义标题或将其包装在已知模型中,在该模型中,我可以检索我需要的信息—无论是哪种方式,我都需要截取/修改消息


最简单的方法是什么,不用花很多钱?我的意思是,我们只是使用简单的配置来进行重试,所以“成本”是指将配置与其他配置交换。无论如何谢谢你

使用卡夫卡活页夹,您可以将
producertinterceptor
添加到卡夫卡生产者配置
拦截器.classes

/**
 * This is called from {@link org.apache.kafka.clients.producer.KafkaProducer#send(ProducerRecord)} and
 * {@link org.apache.kafka.clients.producer.KafkaProducer#send(ProducerRecord, Callback)} methods, before key and value
 * get serialized and partition is assigned (if partition is not specified in ProducerRecord).
 * <p>
 * This method is allowed to modify the record, in which case, the new record will be returned. The implication of modifying
 * key/value is that partition assignment (if not specified in ProducerRecord) will be done based on modified key/value,
 * not key/value from the client. Consequently, key and value transformation done in onSend() needs to be consistent:
 * same key and value should mutate to the same (modified) key and value. Otherwise, log compaction would not work
 * as expected.
 * <p>
 * Similarly, it is up to interceptor implementation to ensure that correct topic/partition is returned in ProducerRecord.
 * Most often, it should be the same topic/partition from 'record'.
 * <p>
 * Any exception thrown by this method will be caught by the caller and logged, but not propagated further.
 * <p>
 * Since the producer may run multiple interceptors, a particular interceptor's onSend() callback will be called in the order
 * specified by {@link org.apache.kafka.clients.producer.ProducerConfig#INTERCEPTOR_CLASSES_CONFIG}. The first interceptor
 * in the list gets the record passed from the client, the following interceptor will be passed the record returned by the
 * previous interceptor, and so on. Since interceptors are allowed to modify records, interceptors may potentially get
 * the record already modified by other interceptors. However, building a pipeline of mutable interceptors that depend on the output
 * of the previous interceptor is discouraged, because of potential side-effects caused by interceptors potentially failing to
 * modify the record and throwing an exception. If one of the interceptors in the list throws an exception from onSend(), the exception
 * is caught, logged, and the next interceptor is called with the record returned by the last successful interceptor in the list,
 * or otherwise the client.
 *
 * @param record the record from client or the record returned by the previous interceptor in the chain of interceptors.
 * @return producer record to send to topic/partition
 */
public ProducerRecord<K, V> onSend(ProducerRecord<K, V> record);
/**
*这是从{@link org.apache.kafka.clients.producer.KafkaProducer#send(ProducerRecord)}和
*{@link org.apache.kafka.clients.producer.KafkaProducer#send(ProducerRecord,Callback)}方法,在键和值之前
*获取序列化并分配分区(如果ProducerRecord中未指定分区)。
*
*此方法允许修改记录,在这种情况下,将返回新记录。修改的含义
*键/值是指分区分配(如果未在ProducerRecord中指定)将基于修改后的键/值进行,
*不是来自客户端的键/值。因此,在onSend()中完成的键和值转换需要一致:
*相同的键和值应该变异为相同的(修改的)键和值。否则,日志压缩将无法工作
*正如所料。
*
*同样,由拦截器实现来确保在ProducerRecord中返回正确的主题/分区。
*大多数情况下,它应该是与“记录”相同的主题/分区。
*
*此方法引发的任何异常都将被调用方捕获并记录,但不会进一步传播。
*
*由于生产者可以运行多个拦截器,因此将按以下顺序调用特定拦截器的onSend()回调
*由{@link org.apache.kafka.clients.producer.ProducerConfig#INTERCEPTOR_CLASSES_CONFIG}指定。第一拦截器
*在获取从客户端传递的记录的列表中,以下拦截器将传递
*以前的拦截器,等等。由于允许拦截器修改记录,拦截器可能会
*记录已被其他拦截器修改。但是,构建依赖于输出的可变拦截器管道
*不鼓励使用以前的拦截器,因为拦截器可能无法
*修改记录并引发异常。如果列表中的某个拦截器从onSend()引发异常,则该异常
*捕获、记录并调用下一个拦截器,同时调用列表中最后一个成功拦截器返回的记录,
*或是客户。
*
*@param record来自客户端的记录或拦截器链中前一个拦截器返回的记录。
*@返回要发送到主题/分区的生产者记录
*/
公共生产记录onSend(生产记录);
生产者记录包含目标主题名称;您可以在那里添加/删除标题


RabbitMQ绑定器目前没有类似的钩子。如果您使用的是该活页夹,请在GitHub上针对该活页夹打开新功能问题。

您使用的活页夹是哪一个(例如RabbitMQ或Kafka)?Hi@GaryRussell-使用Kafka。感谢@GaryRussell-在此处使用Kafka。不知道我是否需要用什么东西来截取信息。在出现特定错误时(或重试后),它们会直接进入DLQ。正如我上面解释的,您可以使用
producertinterceptor
;什么不清楚?我不知道你还需要什么。