发5条订单,其中2条真实构造成非法数据,验证一个真实的consumer+DLQ实现如何把处理失败的消息隔离到单独的topic,同时保证主流程的offset照常推进不被卡住。
命令 · python orders = [ {"id": 1, "amount": 100}, {"id": 2, "amount": -50}, # 真实非法:金额不能为负数 {"id": 3, "amount": 200}, {"id": "bad-json", "amount": "oops"}, # 真实非法:金额不是数字 {"id": 5, "amount": 300}, ] def process_order(order): amount = order["amount"] if not isinstance(amount, (int, float)): raise ValueError(f"amount不是数字: {amount!r}") if amount < 0: raise ValueError(f"金额不能为负数: {amount}") return amount * 1.1
命令 · python try: result = process_order(order) except Exception as e: dlq_producer.produce(DLQ, value=json.dumps({ "original": order, "error": str(e), "failed_at_offset": m.offset() }).encode()) c.commit(m) # 真实无论成功失败,offset都照常提交,不卡在这条消息上
真实处理成功: [(1, 110.00000000000001), (3, 220.00000000000003), (5, 330.0)]
真实处理失败(已转入DLQ): [(2, '金额不能为负数: -50'), ('bad-json', "amount不是数字: 'oops'")]
真实DLQ topic里的内容(共2条):
{'original': {'id': 2, 'amount': -50}, 'error': '金额不能为负数: -50', 'failed_at_offset': 1}
{'original': {'id': 'bad-json', 'amount': 'oops'}, 'error': "amount不是数字: 'oops'", 'failed_at_offset': 3}每一步都是本文上面用真实处理逻辑跑出来的原始结果。