Flink 消费RabbitMQ 和 Kafka

1
2
在消息RabbitMQ时,我们关心的一个问题是手动ack还是自动ack,如果是自动ack就怕出现丢消息的情况
Flink以RabbitMQ作为Source,是怎么保证消息唯一性的呢,是怎么保证ack的.

 

1
2
3
4
5
6
首先引入依赖包
<dependency>
     <groupId>org.apache.flink</groupId>
     <artifactId>flink-connector-kafka-0.10_${scala.version}</artifactId>
     <version>${flink.version}</version>
</dependency>              

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
RMQSource类,可以看到如果设置了checkpointing,则默认autoAck是false,是手动控制提交的<br>那什么时候提交呢,flink checkpointing有个时间间隔,每次checkpointing触发时,才能ack,也就是说,不是一条消息ack一下,而是定时ack<br>这个跟kafka,update offset一样,都是在checkpoint的时候处理
 
@Override
    public void open(Configuration config) throws Exception {
        super.open(config);
        ConnectionFactory factory = setupConnectionFactory();
        try {
            connection = factory.newConnection();
            channel = connection.createChannel();
            if (channel == null) {
                throw new RuntimeException("None of RabbitMQ channels are available");
            }
            setupQueue();
            consumer = new QueueingConsumer(channel);
 
            RuntimeContext runtimeContext = getRuntimeContext();
            if (runtimeContext instanceof StreamingRuntimeContext
                    && ((StreamingRuntimeContext) runtimeContext).isCheckpointingEnabled()) {
                autoAck = false;
                // enables transaction mode
                channel.txSelect();
            } else {
                autoAck = true;
            }
 
            LOG.debug("Starting RabbitMQ source with autoAck status: " + autoAck);
            channel.basicConsume(queueName, autoAck, consumer);
 
        } catch (IOException e) {
            throw new RuntimeException("Cannot create RMQ connection with " + queueName + " at "
                    + rmqConnectionConfig.getHost(), e);
        }
        running = true;
    }

 

RMQSource
 
@Override
    public void run(SourceContext<OUT> ctx) throws Exception {
        while (running) {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
 
            synchronized (ctx.getCheckpointLock()) {
 
                OUT result = schema.deserialize(delivery.getBody());
 
                if (schema.isEndOfStream(result)) {
                    break;
                }
 
                if (!autoAck) {
                    final long deliveryTag = delivery.getEnvelope().getDeliveryTag();
                    if (usesCorrelationId) {
                        final String correlationId = delivery.getProperties().getCorrelationId();
                        Preconditions.checkNotNull(correlationId, "RabbitMQ source was instantiated " +
                            "with usesCorrelationId set to true but a message was received with " +
                            "correlation id set to null!");
                        if (!addId(correlationId)) {
                            // we have already processed this message
                            continue;
                        }
                    }
                    sessionIds.add(deliveryTag);
                }
 
                ctx.collect(result);
            }
        }
    }

 

@Override
    protected void acknowledgeSessionIDs(List<Long> sessionIds) {
        try {
            for (long id : sessionIds) {
                channel.basicAck(id, false);
            }
            channel.txCommit();
        } catch (IOException e) {
            throw new RuntimeException("Messages could not be acknowledged during checkpoint creation.", e);
        }
    }

 

posted on   龙&缘  阅读(1884)  评论(1编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示