Kafka学习(4)——生产消费实践

kafka的consumerConnector.createMessageStreams 方法源码分析 Consumer.create(consumerConfig) val topicMessageStreams = consumerConnector.createMessageStreams( topics, keyDecoder, valueDecoder) 这里的createMessageStreams调用的是子类ZookeeperConsumerConnector 的实现 阅读详情

1. 基于0.8的生产者和消费者

maven依赖:

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.9.0.1</version>
</dependency>
<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka_2.10</artifactId>
    <version>0.9.0.1</version>
</dependency>

1.1 消息生产

package com.best.kafka.test;

import com.best.xingng.cxf.databinding.json.util.JsonUtil;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.UUID;


public class LogProcessProducer {

    private static String KAFKA_ZOOKEEPER_CONNECT = "127.0.0.1:2181";
    private static String KAFKA_METADATA_BROKER_LIST = "127.0.0.1:9092";
    private static String KAFKA_ZK_CONNECTION_TIMEOUT_MS = "1000000";
    private static String TOPIC = "test1";

    public void test() {
        //初始化producer
        Properties producerProps = new Properties();
        producerProps.put("zookeeper.connect", KAFKA_ZOOKEEPER_CONNECT);
        producerProps.put("zk.connectiontimeout.ms", KAFKA_ZK_CONNECTION_TIMEOUT_MS);
        producerProps.put("metadata.broker.list", KAFKA_METADATA_BROKER_LIST);
        producerProps.put("key.serializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        producerProps.put("value.serializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        kafka.javaapi.producer.Producer<byte[], byte[]> producer = new kafka.javaapi.producer.Producer<byte[], byte[]>(new ProducerConfig(producerProps));

        //封装数据
        List<KeyedMessage<byte[], byte[]>> keyedMessages = new ArrayList<KeyedMessage<byte[], byte[]>>();
        for (int i=1; i<=100; i++) {
            String s = "test"; //此处数据类型为String
            KeyedMessage<byte[], byte[]> keyedMessage = new KeyedMessage<byte[], byte[]>(TOPIC, UUID.randomUUID().toString().getBytes(), SerializerUtil.serializer(s));
            keyedMessages.add(keyedMessage);
        }

        //批量发送
        producer.send(keyedMessages);
    }
}

SerializerUtil一个自定义的序列化帮助类,实现对象的序列化和反序列化。

1.2 消息消费

一方面,kafka认为0.9.*版本的consumer还不够完善,所以推荐使用0.9.*之前的consumer。

另一方面,0.9.*版本不再在zookeeper上维护consumer的offset,而是维护在broker上。

这对旧的kafka-manager来说影响较大,当前最新的kafka-manager-1.3.0.8已经支持broker上维护的offset,我们还未升级。

package com.best.kafka.test;

import kafka.consumer.Consumer;
import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.message.MessageAndMetadata;

import java.util.*;


public class LogProcessConsumer {

    private static String KAFKA_ZOOKEEPER_CONNECT = "127.0.0.1:2181";
    private static String KAFKA_METADATA_BROKER_LIST = "127.0.0.1:9092";
    private static String KAFKA_FETCH_MAX_SIZE = (5*1024*1024) + "";
    private static String TOPIC = "test1";
    private static int PARTITION_NUM = 1;

    public void test() {
        //初始化consumer
        Properties consumerProps = new Properties();
        consumerProps.put("zookeeper.connect", KAFKA_ZOOKEEPER_CONNECT);
        consumerProps.put("metadata.broker.list", KAFKA_METADATA_BROKER_LIST);
        consumerProps.put("key.deserializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        consumerProps.put("value.deserializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        consumerProps.put("auto.commit.enable", "false");
        consumerProps.put("auto.offset.reset", "smallest");
        consumerProps.put("fetch.message.max.bytes", KAFKA_FETCH_MAX_SIZE);
        consumerProps.put("group.id", "test");
        kafka.javaapi.consumer.ConsumerConnector consumerConnector = Consumer.createJavaConsumerConnector(new ConsumerConfig(consumerProps));

        //获取KafkaStream
        int num = 10; // partition数目
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put(TOPIC, PARTITION_NUM);
        Map<String, List<KafkaStream<byte[], byte[]>>> streamMap = consumerConnector.createMessageStreams(map);
        List<KafkaStream<byte[], byte[]>> kafkaStreamList = streamMap.get(TOPIC);

        //获取KafkaStream的iterator
        List<ConsumerIterator<byte[], byte[]>> consumerIterators = new ArrayList<ConsumerIterator<byte[], byte[]>>();
        for (final KafkaStream<byte[], byte[]> stream : kafkaStreamList) {
            ConsumerIterator<byte[], byte[]> iterator = stream.iterator();
            consumerIterators.add(iterator);
        }

        // 取数据
        for (final ConsumerIterator<byte[], byte[]> iterator : consumerIterators) {
            while (iterator.hasNext()) {
                MessageAndMetadata<byte[], byte[]> mam = iterator.next();
                if (mam.message() == null) {
                    continue;
                }
                String s = (String) SerializerUtil.deserializer(mam.message());
                System.out.println(s);
                consumerConnector.commitOffsets();
            }
        }
    }
}
  • KafkaStream。KafkaStream是kafka的consumer,KafkaStream的数量应和partition的数量保持一致,一个partition对应一个KafkaStream,超过partition数量的KafkaStream其实一直阻塞着,并不会其作用。所以,要增加KafkaStream就必须相应增加partition。
  • offset。offset是consumer消费位置的标志,提交offset表明消息被消费。自动提交方式,offset是在iterator.next()之后就会进行。手动提交方式,可以定制消息被后续处理流程处理后再提交,从而确保消息发送的exactly once。如上例,设置auto.commit.enable为false,在print之后手动提交consumerConnector.commitOffsets(),可以确保print每一条消息。
  • 消费组。group.id决定了consumer所属的消费组,同一个消费组的consumer共同维护一个offset。
  • 初始消费位置。auto.offset.reset决定了一个新的consumer(不同group)消费的位置,默认为largest,表示从最新的消息开始消费;smallest表示从最久的消息开始消费。
  • 阻塞消费。默认情况下,未设置consumer.timeout.ms参数,ConsumerIterator.hasNext()是阻塞式的,有数据时,ConsumerIterator.hasNext()返回true,无数据时,程序卡在ConsumerIterator.hasNext(),直到有新的数据进来。如果设置consumer.timeout.ms,则ConsumerIterator.hasNext()是限时消费的,有数据的时候,ConsumerIterator.hasNext()返回true,无数据时,ConsumerIterator.hasNext()等待consumer.timeout.ms时间,如果仍无数据,则抛出ConsumerTimeoutException错误。
  • 消息大小。在consumer端关注的是获取的单条消息大小,由fetch.message.max.bytes决定。取出的消息大小超过fetch.message.max.bytes就会报MessageSizeTooLargeException。取出的消息大小是由写入的消息大小决定的,topic的max.message.bytes(默认情况下使用Broker的message.max.bytes)是限制producer对该topic发送的消息大小。所以要求fetch.message.max.bytes大于topic的max.message.bytes。

2. 基于0.9的生产者和消费者

使用0.9客户端对kafka进行消息读写。

0.8.2对Producer进行了较大改变,发送更快。

0.9.0对Consumer进行了较大的改变,去除了0.8上高低版本consumer的区别,使用更加方便。同时offset不再维护到zk上,维护到了broker上,可以降低对zk的依赖。但目前只是beta版本。

maven依赖:

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.9.0.1</version>
</dependency>

API具体文档见Producer API和Consumer API

参数配置见Producer Config和Consumer Config

2.1 消息生产

客户端加snappy压缩,需要确保snappy-java版本为1.1.1.7

2.2 消息消费

kafka会管理如何分配partition的消费。0.9的KafkaConsumer是一个批量消费。

(1)当某个consumer消费了数据,但是在heartbeat.interval.ms时间内没有commit,它就认为consumer挂了。这个时候就要reblance了。
(2)consumer每次poll时,取出max.partition.fetch.bytes大小的数据。

下面是一个简单的producer-consumser单元测试:

JsonUtil一个自定义的序列化帮助类,实现对象的序列化和反序列化。

package com.best.kafka.test;

import best.kafka.test.serialize.json.JsonUtil;
import junit.framework.Assert;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.clients.producer.ProducerRecord;

import java.util.Iterator;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Kafka090ClientTest
 *
 * @author cnuuid
 * @date 1/9/2016
 * @since
 */
public class Kafka090ClientTest {
    protected final Log logger = LogFactory.getLog(getClass());

    private Kafka090ProducerService kafka090ProducerService = null;
    private Kafka090ConsumeService kafka090ConsumeService = null;

    private volatile boolean flag = true;
    private String topic = "localtest";
    private static int consumerNum = 1;

    final CountDownLatch startGate = new CountDownLatch(1);
    final CountDownLatch endGate = new CountDownLatch(consumerNum);
    AtomicLong counter = new AtomicLong();

    private Properties getProducerProperties() {
        Properties properties = new Properties();
//        properties.put("bootstrap.servers", "127.0.0.1:9092");
        properties.put("bootstrap.servers", "192.168.0.2:9092,192.168.0.3:9092");
        properties.put("key.serializer", "org.apache.kafka.common.serialization.ByteArraySerializer");
        properties.put("value.serializer", "org.apache.kafka.common.serialization.ByteArraySerializer");
        properties.put("buffer.memory", 1024000); //1M
        properties.put("compression.type", "snappy");
        properties.put("retries", 3);
        properties.put("batch.size", 102400); //100k
//        properties.put("client.id", );
//        properties.put("max.block.ms", 60000); //60s
        properties.put("max.request.size", 1024000); //1M
//        properties.put("receive.buffer.bytes", );
//        properties.put("request.timeout.ms", );
        properties.put("block.on.buffer.full", true);
        return properties;
    }

    private Properties getConsumerProperties() {
        Properties properties = new Properties();
//        properties.put("bootstrap.servers", "127.0.0.1:9092");
        properties.put("bootstrap.servers", "192.168.0.2:9092,192.168.0.3:9092");
        properties.put("key.deserializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer");
        properties.put("value.deserializer", "org.apache.kafka.common.serialization.ByteArrayDeserializer");
//        properties.put("fetch.min.bytes", );
        properties.put("group.id", "localtestgroup");
        properties.put("heartbeat.interval.ms", "20000");
//        properties.put("max.partition.fetch.bytes", "3145728");//3M
        properties.put("max.partition.fetch.bytes", "1000");//3M
        properties.put("request.timeout.ms", "60000");
        properties.put("session.timeout.ms", "30000");
        properties.put("group.max.session.timeout.ms", "60000");
        properties.put("auto.offset.reset", "earliest");
        properties.put("enable.auto.commit", "false");
//        properties.put("max.poll.records", "1"); //0.10.0版本可用
//        properties.put("partition.assignment.strategy", );
//        properties.put("receive.buffer.bytes", );
//        properties.put("request.timeout.ms", );
//        properties.put("send.buffer.bytes", );
//        properties.put("client.id", );
//        properties.put("fetch.max.wait.ms", );
        return properties;
    }


    @org.junit.Before
    public void before() throws Exception {
        kafka090ProducerService = new Kafka090ProducerService(getProducerProperties());
        kafka090ConsumeService = new Kafka090ConsumeService(getConsumerProperties(), topic, consumerNum);
    }

    @org.junit.After
    public void after() throws Exception {
        flag = false;
        kafka090ProducerService.close();
        kafka090ConsumeService.close();
    }

    @org.junit.Test
    public void produce() throws InterruptedException {
        int i = 0;
        while(i<1000){
            Message message = new Message();
            message.setContent(i + "");
            ProducerRecord<byte[], byte[]> producerRecord = new ProducerRecord<byte[], byte[]>(topic, UUID.randomUUID().toString().getBytes(), JsonUtil.toByteJson(message));
            kafka090ProducerService.send(producerRecord);
            System.out.println("put " + i++);
        }
        Thread.sleep(10*1000);
    }

    @org.junit.Test
    public void consume() throws InterruptedException {
        CopyOnWriteArraySet<KafkaConsumer<byte[], byte[]>> consumers = kafka090ConsumeService.getConsumers();
        KafkaConsumer<byte[], byte[]> consumer = consumers.iterator().next();
        int i = 0;
        while (flag) {
            ConsumerRecords<byte[], byte[]> consumerRecords = consumer.poll(100);
            for (ConsumerRecord<byte[], byte[]> record : consumerRecords) {
                if (record.value() == null) {
                    continue;
                }
                Message message = JsonUtil.formByteJson(Message.class, record.value());
                System.out.println("consume:" + message.getContent() + "..");
            }
            if (consumerRecords.count()>0) {
                consumer.commitSync();
            }
            System.out.println("loop-" + i);
            Thread.sleep(1000);
        }
    }

    @org.junit.Test
    public void test() throws InterruptedException {
        while (counter.longValue() < 1000) {
            Message message = new Message();
            message.setContent(counter.longValue() + "");
            ProducerRecord<byte[], byte[]> producerRecord = new ProducerRecord<byte[], byte[]>(topic, UUID.randomUUID().toString().getBytes(), JsonUtil.toByteJson(message));
            kafka090ProducerService.send(producerRecord);
            System.out.println("put " + counter.longValue());
            counter.incrementAndGet();
        }

        Thread.sleep(10 * 1000);

        // consume
        CopyOnWriteArraySet<KafkaConsumer<byte[], byte[]>> consumers = kafka090ConsumeService.getConsumers();
        Iterator<KafkaConsumer<byte[], byte[]>> iterator = consumers.iterator();
        while (iterator.hasNext()) {
            KafkaConsumer<byte[], byte[]> consumer = iterator.next();
            Thread consumeThread = new Thread(new ConsumeTask(consumer));
            consumeThread.start();
        }
        startGate.countDown();
        endGate.await();
        Assert.assertEquals(0l, counter.longValue());
    }

    class ConsumeTask implements Runnable {
        private KafkaConsumer<byte[], byte[]> consumer;

        public ConsumeTask(KafkaConsumer<byte[], byte[]> consumer) {
            this.consumer = consumer;
        }

        @Override
        public void run() {
            try {
                startGate.await();
                logger.info("Kafka " + Thread.currentThread().getName() + " running...");
                try {
                    int i=0;
                    while (i<50) {
                        ConsumerRecords<byte[], byte[]> consumerRecords = consumer.poll(100);
                        for (ConsumerRecord<byte[], byte[]> record : consumerRecords) {
                            if (record.value() == null) {
                                continue;
                            }
                            Message message = JsonUtil.formByteJson(Message.class, record.value());
                            counter.decrementAndGet();
                            System.out.println(Thread.currentThread().getName() + " consume:" + message.getContent() + "..");
                        }
                        if (consumerRecords.count() > 0) {
                            consumer.commitSync();
                        }
                        System.out.println("loop-" + i);
                        Thread.sleep(1000);
                        i++;
                    }
                } catch (Exception e) {
                    logger.error("", e);
                }
                Thread.sleep(10 * 1000);
                endGate.countDown();
                logger.info("Kafka " + Thread.currentThread().getName() + " finished.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

消息体

package com.best.kafka.test;

/**
 * Message
 *
 * @author cnuuid
 * @date 9/1/2016
 * @since
 */
public class Message {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

生产者producer

package com.best.kafka.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

import java.util.Properties;

/**
 * Kafka090ProducerService
 *
 * @author cnuuid
 * @date 9/1/2016
 * @since
 */
public class Kafka090ProducerService {
    protected final Log logger = LogFactory.getLog(getClass());

    private Producer<byte[], byte[]> producer;

    public Kafka090ProducerService(Properties properties) throws Exception {
        if (properties==null && properties.get("bootstrap.servers")==null
                && properties.get("key.serializer")==null
                && properties.get("value.serializer")==null) {
            throw new Exception("lack of properties");
        } else {
            producer = new KafkaProducer<byte[], byte[]>(properties);
        }
    }

    public void close() throws Exception {
        try {
            producer.close();
        } catch (Exception e) {
            logger.error("Close kafka producer or consumer Error!", e);
        }
        logger.info(" kafka has been shut down!");
    }

    public void send(ProducerRecord<byte[], byte[]> producerRecord) {
        if (producerRecord!=null) {
            producer.send(producerRecord);
        }
    }
}

消费者consumer

package com.best.kafka.test;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.kafka.clients.consumer.KafkaConsumer;

import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * Kafka090ConsumeService
 *
 * @author cnuuid
 * @date 9/1/2016
 * @since
 */
public class Kafka090ConsumeService {
    protected final Log logger = LogFactory.getLog(getClass());

    private CopyOnWriteArraySet<KafkaConsumer<byte[], byte[]>> consumers = new CopyOnWriteArraySet<KafkaConsumer<byte[], byte[]>>();

    public Kafka090ConsumeService(Properties properties, String topic, int consumerNum) throws Exception {
        if (properties==null && properties.get("bootstrap.servers")==null
                && properties.get("key.serializer")==null
                && properties.get("value.serializer")==null
                && consumerNum<=0
                && StringUtils.isNotBlank(topic)) {
            throw new Exception("lack of properties");
        } else {
            for (int i=0; i< consumerNum; i++) {
                KafkaConsumer<byte[], byte[]> consumer = new KafkaConsumer<byte[], byte[]>(properties);
                consumer.subscribe(Arrays.asList(topic));
                consumers.add(consumer);
            }
        }
    }

    public void close() throws Exception {
        try {
            if (consumers!=null && consumers.size()>0) {
                for (KafkaConsumer<byte[], byte[]> consumer : consumers) {
                    if (consumer!=null) {
                        synchronized (consumer) {
                            if (consumer!=null) {
                                consumer.close();
                                consumer = null;
                            }
                        }
                    }

                }
            }
        } catch (Exception e) {
            logger.error("Close kafka producer or consumer Error!", e);
        }
        logger.info(" kafka has been shut down!");
    }

    public CopyOnWriteArraySet<KafkaConsumer<byte[], byte[]>> getConsumers() {
        return consumers;
    }
}
kafka学习之路(一)——入门 kafka学习之路(一)——入门Kafka学习之路...一、入门..1、      简介2、      主题(Topics)、日志(Logs)3、      分布式(Distribution)4、      生产者(Producers)5、      消费者(Consumers) 一、入门1、简介Kafka 是linkedin 公司用于日志处理的分布式消息队列,同时支持离线和在线日志处理。kafk... 阅读详情

相关推荐

kafka学习总结(含java生产者、消费者、Topic操作代码)

kafka(http://kafka.apache.org)是一款分布式消息发布和订阅的系统,具有高性能和高吞吐率。笔者主要是将在自己的应用当中所用到资料整合在一起,并且加上自己的理解从而写下了这篇文章,文章主要包括了Kafka的简单介绍、Kafka的部署、Kafka的java代码应用。如果写的不好的地方还请指正。

czs1130的博客 6931

Linux部署Kafka及常见问题记录

(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)kafka消息发送的时候 ,考虑到性能 可以采用打包方式发送, 也就是说 传统的消息是一条一条发送, 现在可以先把需要发送的消息缓存在客户端, 等到达一定数值时, 再一起打包发送, 而且还可以对发送的数据进行压缩处理,减少在数据传输时的开销。topic命令时的警告 创建topic的时候,如果名称中包含. 或者_,kafka会抛出警告。

leeindex的博客 2897

Kafka学习(一):消费者实现对分区的并发消费

说明 在上篇博文《springboot学习(十七):了解spring - kafka配置工作原理》中,我们简单了解了spring-kafka的配置工作原理。通过源码可以看到spring在实现并发消费时,采用的是线程封闭的策略,也就是一个groupid中,根据配置的concurrency来创建多个消费者线程,每个消费者消费一个或多个分区,来实现整个topic消息的消费处理。本篇博文将对上篇博文中最后...

wds的博客 1万+

kafka消费API理解

主要消费部分API:ConsumerConnector connector = Consumer.create(consumerConfig);interface ConsumerConnector { public Map<String,List<KafkaStream>> createMessageStreams(Map<String,Int> topicCountMap); p

suibo0912hf的专栏 5184

Kafka 消费端消费重试和死信队列

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Spring-Kafka 提供消费重试的机制。当消息消费失败的时候,Spring-Kafka 会通过消费重试机制,重新投递该消息给 Consumer ,让 Consumer 重新消费消息 。默认情况下,Spring-Kafka 达到配置的重试次数时,【每条消息的失败重试时间,由配置的时间隔决定】Consumer 如果依然消费失败 ,那么该消息就会进入到死信队列。Sp

pleaseprintf的博客 2073

Golang学习篇—kafka压缩使用生产和消费

1.kafka使用依赖包 "github.com/Shopify/sarama" "github.com/bsm/sarama-cluster" 2.kafka生产和消费端二次封装 Common.go package XLKafka import "github.com/Shopify/sarama" type KafkaCfg struct { Producer struct ...

Map的博客 2164

【Kafka】2.在SpringBoot中使用官方原生java版Kafka客户端

使用官方原生java版Kafka客户端

yuhuofei的草屋 1494

kafka实战篇(二):消息消费实战

本文主要使用java来实战kafka消费数据的过程,解析并实现kafka手动提交offset和自动提交offset的demo,并进行详细的总结和对比。

静待花开 9430

Kafka java api-生产者代码、高性能吞吐

前面做过命令行让生产者发送消息,现在使用java api来进行消息的生产,以及解释kafka高性能是如何实现(来源于学习资料)。

成都往右的博客 3276

使用Java编写Kafka生产者和消费者示例

本文介绍了如何使用Java编写Kafka的生产者和消费者示例。通过这些示例代码,我们可以轻松地在Java应用中集成Kafka,实现消息的生产和消费。Kafka具有高性能、高可靠性的特点,适用于各种场景的消息处理需求。

私聊前往站内信:https://i.youkuaiyun.com/#/msg/chat/weixin_44976692 2万+

手把手教你用Qt和DSP28335实现串口Bootloader,附赠源码和避坑指南

本文详细介绍了如何使用Qt和DSP28335实现串口Bootloader,包括开发环境搭建、通信协议设计、Qt上位机开发、DSP端Bootloader核心实现以及应用程序工程的特殊配置。通过实战案例和源码分享,帮助开发者快速掌握嵌入式固件升级技术,提升工业设备远程升级的效率和可靠性。

weixin_29176179的博客 133

【Kafka专栏 05】一条消息的完整生命周期:Kafka如何保证消息的顺序消费

除了默认的哈希分区策略外,Kafka还允许使用自定义的分区器。这为用户提供了更大的灵活性,可以根据业务需求自定义分区逻辑,进一步确保消息的顺序性。Kafka通过其独特的分区机制、消费者组配置、生产者的分区策略以及监控与错误处理机制,共同保证了消息的顺序消费。在实际应用中,需要根据业务需求合理配置和使用这些机制,以确保消息的有序性。同时,也需要注意Kafka的性能和可扩展性,以满足大规模数据处理的需求。

weixin_40736233的博客 2787

矩阵LED和矩阵按键

先说矩阵LED,如图: 下面以行几、列几的表达方法说明 三极管可以当做开关使用 由图可知,如果想让一个LED亮,那么它对应的行和列的三极管都要导通。如果这个矩阵每次只亮一个LED,那么正常写程序没问题。 如果我们想让LED1和LED6亮,其他灯不亮,则需要开启行1、行2、列1、列2,随之带来的问题就是LED2和LED5也会跟着亮起来。 解决方法类似于扫描,因为单片机运行速度很快,可以在很短的时间内开关数次而肉眼看不到。所以我们可以每次只亮一列(排)灯,亮单位时间后关掉同时开启另外一列(排),如此四次一循环

qq_46615634的博客 5788

详细讲解如何使用Java连接Kafka构建生产者和消费者(带测试样例)

详细讲解如何使用Java连接Kafka构建生产者和消费者。

天然玩家的博客 1万+

银河麒麟(ky10)x86与arm双架构下编译zlmediakit的实战指南

本文提供了在银河麒麟(ky10)操作系统上,针对x86与arm双架构编译部署流媒体服务器zlmediakit的完整实战指南。文章详细阐述了从环境准备、依赖安装、代码获取到编译构建与测试的全过程,重点解析了两种CPU架构下的关键差异与注意事项,帮助开发者高效完成国产化平台上的流媒体服务搭建。

weixin_29306875的博客 98

ANSYS Fluent热边界条件避坑指南:为什么你的自然对流计算结果总出错?

本文深入剖析了在ANSYS Fluent中进行自然对流仿真时,导致计算结果出错或发散的核心原因与解决方案。重点解析了重力项与操作密度设置、Boussinesq与不可压缩理想气体模型的抉择、以及压力离散格式(推荐Body Force Weighted)这三大关键雷区,并结合电子机箱散热等实战案例,提供了一套稳定可靠的仿真设置流程与调试技巧。

weixin_28396629的博客 737

Linux下的kafka终端发送、接收消息(生产、消费模式)

新接触kafka,学习记录下。 producer 消息的生成者,即发布消息 consumer 消息的消费者,即订阅消息 broker Kafka以集群的方式运行,可以由一个或多个服务组成,服务即broker zookeeper 协调转发 1、# 启动 Zookeeper ./bin/zookeeper-server-start.sh config/zookeeper.properties 2、 启动 Kafka ./bin/kafka-server-start.sh config/

猫瑾的博客 8690

在Ubuntu系统中安装和使用wxPython进行Python图形用户界面(GUI)开发

在本文中,我将向您展示如何在Ubuntu系统上安装和使用wxPython,并提供一些示例代码来帮助您开始使用这个强大的工具。在MyFrame的构造函数中,我们创建了一个wx.Panel和一个按钮,并将按钮的点击事件绑定到一个自定义的方法on_button_click上。最后,我们创建了一个wx.App的实例,创建了一个MyFrame对象并显示它,最后通过调用app.MainLoop()启动应用程序的主事件循环。这只是一个简单的示例,但它演示了如何使用wxPython创建一个基本的GUI应用程序。

qq_37934722的博客 1038

Kafka - 基于Spring Boot实战:消息生产与消费完整实现

event) .addCallback( result -> log.info("Message sent: {}", result.getRecordMetadata()), ex -> log.error("Failed to send message", ex) ); } // 同步发送(阻塞直到确认) public void sendSync(String key, UserEvent event) throws Exception { kafka

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

JavaScript实现斗地主(附完整源码)

JavaScript实现斗地主(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1503

手把手教你学Simulink--基于Simulink的高增益DC-DC变换器仿真建模

特点高电压增益:可以在不使用变压器的情况下实现较大的电压升压比。适用于低电压源:如太阳能电池板、燃料电池等提供的低压直流电源。效率问题:设计时需特别注意提高效率,减少能量损失。挑战电路复杂性:通常涉及多个电感和电容,以及复杂的开关模式。元件选择:合适的元件参数对于达到理想性能至关重要。控制策略:确保高效稳定运行的同时,适应负载变化。首先明确要模拟的任务内容。实现特定的电压增益比(例如从24V升至380V)。根据预期的输入输出电压确定合适的电路拓扑和元件值。

MHD0815的博客 172

Kafka及Kafka消费者的消费问题及线程问题

kafka消费与线程池遇到的问题分析

胡买提 6031

rk3588 适配音频解码芯片 ALC5616

在 RK3588 的高性能方案中,选择 **ALC5616**(来自 Realtek 瑞昱)通常意味着项目更侧重于**音频性能的稳定性**以及**全球供应链的通用性**。

weixin_35723192的博客 141

Kafka 生产者和消费者学习笔记

最近搭建 kafka 集群环境以便于收集应用程序日志并进行个性化的处理,因此学习了 kafka 生产者和消费者 python 程序的实现。这篇文章当是个 kafka 的学习笔记。 一、搭建 kafka 集群 为方便测试,我们在 MacOS 单机上搭建具有三个 kafka 节点的集群。如果在生产上部署 kafka ,请在不同的物理机上部署 kafka 集群。 1. 下载 kafka 镜像 我们使用 wurstmeister/kafka 镜像来部署 kafka,由于 kafka 依赖于 zookeeper ,因

Leo的博客 1255

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

kafka学习(三)--生产消息和消费消息

上一讲说 --describe 可以省略 --topic ,没有报错,这里看看两者区别 因此,要查看特定的 topic 信息,建议加上 --topic

你不是叶秋的博客 1448

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Kafka 生产者 、 Kafka 消费者与 kafka事务

文章目录Kafka 生产者 、 Kafka 消费者与 kafka事务3.2、Kafka 生产者3.2.1 分区策略3.2.1.1)分区的原因3.2.1.2)分区的原则【*】3.2.2 数据可靠性保证(生产者推送的数据)【*】3.2.2.1、副本数据同步策略3.2.2.2、ISR3.2.2.3、ack 应答机制(数据丢失和数据重复)3.2.2.4、故障处理细节(数据一致性)3.2.3 Exactly Once 语义3.3、Kafka 消费者3.3.1 Kafka消费方式3.3.2 消费者组里的分区分配策略3.

wang_luwei的博客 1397
上一篇: Kafka学习(3)——测试
下一篇: Kafka学习(5)——常用集群操作
白水不开
博客等级 码龄18年 91粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值