KafkaJS 生产者使用指南:消息发送与高级配置

KafkaJS 生产者使用指南:消息发送与高级配置

kafkajs A modern Apache Kafka client for node.js kafkajs 项目地址: https://gitcode.com/gh_mirrors/ka/kafkajs

生产者基础使用

在 KafkaJS 中创建生产者非常简单,只需调用客户端对象的 producer() 方法即可:

// 创建默认配置的生产者
const producer = kafka.producer()

// 或带配置选项的生产者
const producer = kafka.producer({
    allowAutoTopicCreation: false,
    transactionTimeout: 30000
})

生产者核心配置选项

| 配置项 | 说明 | 默认值 | |-----------------------|-------------------------------------------------------------------------------------------------------------------------|-------------------| | createPartitioner | 自定义分区器,详见自定义分区器 | null | | retry | 重试机制配置,详见生产者重试 | null | | metadataMaxAge | 元数据强制刷新间隔(毫秒),即使没有分区领导变更也会主动发现新broker或分区 | 300000 (5分钟) | | allowAutoTopicCreation| 查询不存在的主题元数据时是否允许自动创建主题 | true | | transactionTimeout | 事务协调器等待生产者事务状态更新的最长时间(毫秒),超时则中止事务 | 60000 | | idempotent | 实验性功能,启用后确保消息精确一次写入(acks必须设为-1) | false | | maxInFlightRequests | 同时进行中的最大请求数,设为falsey值表示无限制 | null (无限制) |

消息发送基础

使用 send() 方法向Kafka集群发布消息:

const producer = kafka.producer()

// 必须先连接
await producer.connect()

// 发送消息
await producer.send({
    topic: 'user-events',
    messages: [
        { key: 'user1', value: JSON.stringify({ action: 'login' }) },
        { key: 'user2', value: JSON.stringify({ action: 'purchase' }) }
    ],
})

发送方法参数详解

await producer.send({
    topic: <String>,          // 主题名称
    messages: <Message[]>,    // 消息数组
    acks: <Number>,          // 确认机制
    timeout: <Number>,       // 超时时间(毫秒)
    compression: <CompressionTypes>, // 压缩类型
})

| 参数 | 说明 | 默认值 | |------------|----------------------------------------------------------------------------------------|----------------------------------| | topic | 目标主题名称 | 必填 | | messages | 消息对象数组 | 必填 | | acks | 确认机制:
-1=所有同步副本必须确认
0=不需要确认
1=只需领导者确认 | -1 (所有同步副本确认) | | timeout | 等待响应的超时时间(毫秒) | 30000 | | compression| 压缩编码类型 | CompressionTypes.None (无压缩) |

消息结构详解

每条消息可以包含以下属性:

| 属性 | 说明 | 默认值 | |------------|----------------------------------------------------------------------------------------|----------------| | key | 用于分区的键值 | | | value | 消息内容,可以是Buffer、字符串或null | | | partition | 指定目标分区号 | | | timestamp | 消息创建时间戳 | Date.now() | | headers | 消息关联的元数据 | |

消息键与分区策略

消息的 key 决定了消息将被发送到哪个分区,这对于确保相关消息按顺序处理非常重要。例如,使用 orderId 作为键可以保证同一订单的所有消息按顺序处理。

默认分区策略:

  1. 如果消息指定了分区,使用该分区
  2. 如果未指定分区但有键,则基于键的哈希值(murmur2)选择分区
  3. 如果既无分区也无键,则使用轮询方式选择分区

消息时间戳

每条消息都有一个UTC时间戳(毫秒精度)。如果未提供时间戳,生产者会使用当前时间。消费者获取消息时,时间戳可能被broker覆盖,具体取决于主题配置:

  • 主题配置为CreateTime:使用生产者提供的时间戳
  • 主题配置为LogAppendTime:使用broker追加消息时的本地时间

消息头

Kafka v0.11+支持记录头,允许消息携带额外元数据:

await producer.send({
    topic: 'audit-log',
    messages: [{
        key: 'event1',
        value: 'security event',
        headers: {
            'trace-id': 'abc123',
            'service': 'auth-service'
        }
    }]
})

头值可以是字符串或字符串数组。

批量发送到多个主题

使用 sendBatch() 方法可同时向多个主题发送消息:

const topicMessages = [
  {
    topic: 'notifications',
    messages: [{ key: 'user1', value: 'New message' }]
  },
  {
    topic: 'analytics',
    messages: [{ key: 'event1', value: 'Page view' }]
  }
]

await producer.sendBatch({ topicMessages })

自定义分区器实现

可以自定义分区器来控制消息分配逻辑:

const CustomPartitioner = () => {
    return ({ topic, partitionMetadata, message }) => {
        // 自定义分区选择逻辑
        return selectedPartition
    }
}

// 使用自定义分区器
kafka.producer({ createPartitioner: CustomPartitioner })

partitionMetadata 参数包含分区信息数组,格式为:{ partitionId: <NodeId>, leader: <NodeId> }

内置分区器

KafkaJS提供两种内置分区器:

  • DefaultPartitioner:与Java客户端兼容,满足共同分区要求
  • LegacyPartitioner:v2.0.0之前的默认分区器
const { Partitioners } = require('kafkajs')
kafka.producer({ createPartitioner: Partitioners.LegacyPartitioner })

消息压缩支持

KafkaJS核心支持GZIP压缩,其他压缩算法需额外安装包。

GZIP压缩示例

const { CompressionTypes } = require('kafkajs')

await producer.send({
    topic: 'logs',
    compression: CompressionTypes.GZIP,
    messages: [
        { value: 'error log entry' }
    ]
})

其他压缩算法

  1. Snappy:需安装 kafkajs-snappy
  2. LZ4:需安装 kafkajs-lz4
  3. ZSTD:需安装 @kafkajs/zstd

配置示例(Snappy):

const { CompressionTypes, CompressionCodecs } = require('kafkajs')
const SnappyCodec = require('kafkajs-snappy')

CompressionCodecs[CompressionTypes.Snappy] = SnappyCodec

自定义压缩算法

可以实现任意压缩算法:

const CustomCodec = {
    async compress(encoder) {
        return customCompress(encoder.buffer)
    },
    async decompress(buffer) {
        return customDecompress(buffer)
    }
}

CompressionCodecs[CompressionTypes.Snappy] = () => CustomCodec

最佳实践建议

  1. 连接管理:发送消息前务必调用 connect()
  2. 错误处理:实现适当的错误处理和重试逻辑
  3. 性能优化:考虑批量发送和压缩大消息
  4. 顺序保证:对需要严格顺序的消息使用相同的键
  5. 资源清理:生产结束时调用 disconnect()

通过合理配置和使用这些功能,可以构建高效可靠的Kafka生产者应用。

kafkajs A modern Apache Kafka client for node.js kafkajs 项目地址: https://gitcode.com/gh_mirrors/ka/kafkajs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仲嘉煊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值