MQ探究-Kafka

多种MQ的探究-Kafka

  1. ActiveMQ原理探究与开发部署
  2. RocketMQ原理探究与开发部署

Kafka

原理

简介
kafka是一个支持高吞吐量的分布式消息服务。
特点:
kafka依赖于zookeeper进行节点注册。
kafka集群:
kafka集群与zk类似,leader拥有最新最全的信息,然后复制信息到从节点上。
springboot2.0版本集成的kafka2.x,消息offsets放置在zk节点topics上。
优缺点
采用分区机制,吞吐量高,拥有ack容错机制,支持集群负载均衡,对日志文件的记录比较好。
但由于高效率的原因,kafka对死信队列、延迟队列等方面不如其他mq。
原理
kafka集群节点注册到zk上,服务加载初始化时加载kafka集群信息,然后进行消息处理。
kafka与zk类似,存在leader与follower,并实时监测服务状态。
模式:
kafka----broker1(topic1…topicn)–consumer

kafka----brokern(topic1…topicn)–consumer
详细:
kafka的topic会依据配置分区数量进行分区(partition),消息producer后push进入broker的各个分区中有序排列(offset)。消息消费监听到当前分区有自己的消息进来,然后进行处理,并记录offset。

producer

消息推送首先获取节点分片情况,然后进行序列化处理

clusterAndWaitTime = waitOnMetadata(record.topic(), record.partition(), maxBlockTimeMs);
...
serializedKey = keySerializer.serialize(record.topic(), record.headers(), record.key());
serializedValue = valueSerializer.serialize(record.topic(), record.headers(), record.value());

我们可以在application配置文件中配置序列化:

key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer

然后获取传入的分片id、时间戳等信息创建分片对象,然后创建producer进行提交:

 ProducerBatch batch = new ProducerBatch(tp, recordsBuilder, time.milliseconds());
 FutureRecordMetadata future = Utils.notNull(batch.tryAppend(timestamp, key, value, headers, callback, time.milliseconds()));
consumer

消息消费有两种方式:1-继承函数接口实现onMessage() 2-注册监听@KafkaListener,两种都是通过监听器来实现,consumer通过poll分片来获取消费对象。消息监听后会进行注册:

public class KafkaListenerEndpointRegistrar implements BeanFactoryAware, InitializingBean {

	private final List<KafkaListenerEndpointDescriptor> endpointDescriptors = new ArrayList<>();

	private KafkaListenerEndpointRegistry endpointRegistry;
	...

通过bean工厂来管理监听器,当监听到消息时会即时进行处理消费。
与其他mq监听并无二致。

安装

环境:centos7

下载

1.从官方服务器上下载
2.直接在服务器上下载
例如:wget http://mirror.bit.edu.cn/apache/kafka/1.0.0/kafka_2.11-1.0.0.tgz
然后解压 tar -zxvf xxx.gz

配置

kafka拥有四种配置:

server.properties

作为服务的主配置,其中可配置信息如下:

  1. listeners=PLAINTEXT://192.168.99.128:9092 监听器监听的ip与端口,需要放开,否则无法识别连接
  2. num.partitions=1 kafka的分区,默认1个区,仅支持一个consumer,如果需要一个主题多消费者则需要放开分区,例如num.partitions=5
  3. log.dirs=/tmp/kafka-logs 日志存放路径
  4. zookeeper.connect=192.168.99.128:2181 kafka依赖的zookeeper的连接地址(一般使用自己的zk)
  5. 等等…
producer.properties

消息生产者的配置信息,主要的配置有bootstrap.servers,默认为当前机器单节点

consumer.properties

消息消费者,与生产者一致,其中配置了consumer.group-id作为分组id

zookeeper.properties

单机zk的配置,如果使用外置zk则不需要配置

启动

执行:./bin/kafka-server-start.sh -daemon ./config/server.properties
jps查询运行的应用:
在这里插入图片描述
停止:./bin/kafka-server-stop.sh

应用

采用springboot集成kafka模式进行开发

服务

1.kafka组件
将kafka服务作为独立组件jar来实现
在这里插入图片描述
引入依赖:

  <dependency>
      <groupId>org.springframework.kafka</groupId>
      <artifactId>spring-kafka</artifactId>
  </dependency>

配置producer

@Service("kafkaProducer")
public class KafkaProducer
{
    @Resource
    private KafkaTemplate kafkaTemplate;
    
    public Boolean sendMessage(String topic, Object message)
    {
        try
        {
            kafkaTemplate.send(topic, message);
        } catch (Exception e)
        {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
}

2.业务
引入kafka组件包
主题:

    public static final String KAFKA_MY_TOPIC = "MY_KAFKA_TOPIC";
    public static final String KAFKA_MY_TOPIC_BAK = "MY_KAFKA_TOPIC_BAK";

服务启动后zk中可见:
在这里插入图片描述
说明:__consumer_offsets偏移量为消费者已消费的元数据,存储在消费者分区上,是在config配置中的num.partitions决定的,默认50个,0~49

消息推送:

    @PostMapping("/sendBatchKafka")
    @ResponseBody
    public String sendBatchKafka(@RequestBody String request)
    {
        kafkaProducer.sendMessage(KafkaTopic.KAFKA_MY_TOPIC, request);
        Map<String, String> params = (Map<String, String>) JSONObject.parse(request);
        String context = params.get("context");
        params.put("context", context + "123");
        kafkaProducer.sendMessage(KafkaTopic.KAFKA_MY_TOPIC_BAK, JSONObject.toJSONString(params));
        return "success";
    }

消息消费:

    @KafkaListener(topics = {KafkaTopic.KAFKA_MY_TOPIC})
    public void onMessage(String message)
    {
        logger.info("KafkaConsumer主题消息:" + message);
    }
    @KafkaListener(topics = {KafkaTopic.KAFKA_MY_TOPIC, KafkaTopic.KAFKA_MY_TOPIC_BAK}, containerFactory = KafkaConfig.TOPIC_FACTORY)
    public void dealMessage(String message)
    {
        logger.info("KafkaBatchConsumer主题消息(多主题):" + message);
    }

调用推送接口,即可发送消息,多主题都可以接收。
单消费配置

spring:
  kafka:
    bootstrap-servers: 192.168.99.128:9092
    consumer:
      group-id: test-consumer-group
      enable-auto-commit: true
    listener:
      missing-topics-fatal: false
    producer:
      batch-size: 4096

说明:kafka默认单消费者,选取最新加载的消费者进行消费,如下:
在这里插入图片描述
此时查看zk,则可发现只有一个分区:
在这里插入图片描述
如果我们需要的就是一对一模式,那么在code的时候注意规范,完全可当做点对点来实现。
多消费者模式
但如果我们需要一对多模式,那么就需要进行调整:

spring:
  kafka:
    bootstrap-servers: 192.168.99.128:9092
    consumer:
      group-id: test-consumer-group
      enable-auto-commit: true
    listener:
      missing-topics-fatal: false
      concurrency: 5
      type: batch
    producer:
      batch-size: 4096

listener.type改为batch批量模式
listener.concurrency线程数调整为依据server.properoties中的num.partitions=5来配置。
missing-topics-fatal默认会校验不存在的topic,此处false,否则需要在启动时创建,不然报错。
topic设置分区信息即可,默认1个分区(会依据规则找最新注册消费者消费),分区数不能大于配置的分区数:

    @Bean(name = "MY_KAFKA_TOPIC")
    public NewTopic myTopic()
    {
        return new NewTopic(KAFKA_MY_TOPIC, 5, (short)2);
    }

可见按照配置设置了5个分区:
在这里插入图片描述
详细说明:
此处采用的是依据消费者的数量进行消息分区推送,因为分区数>=消费者数,那么自定义一个全局线程安全的容器来存放消费者的数量,故推送方法做出变化:

protected static Map<String, Integer> consumerCache = new ConcurrentHashMap<String, Integer>();

Integer concurrency = consumerCache.get(topic);
for (int i=0; i<concurrency; i++)
{
    kafkaTemplate.send(topic, i, groupId , message);
}

说明:多消费者模式包含单消费,单主题默认分区为1个id为0。

测试:
在这里插入图片描述
这样三个消费者就都能收到消息了。

此处推送为一个topic对应多consumer模式,另一种是多topic对应多consumer模式,需要消息根据不同的topic进行推送,如果几千条就需要更多的topic,有点得不偿失。

mq-kafka-code源码
微信公众号:像是风
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
rsyslog-kafka是一种将rsyslog日志服务器与Apache Kafka消息队列集成的工具。rsyslog是一个功能强大的开源日志收集器,可用于在Linux系统上收集、处理和转发日志数据。而Kafka是一个高度可扩展的分布式消息系统,用于实时处理和存储大量数据。 通过rsyslog-kafka的集成,我们可以将rsyslog收集到的日志数据发送到Kafka消息队列中,从而实现日志的实时处理和存储。这种集成的好处是可以应对流量大、实时性要求高的日志场景,提高日志的传输速度和处理能力。 使用rsyslog-kafka的过程大致分为以下几步:首先,需要配置rsyslog服务器以收集特定文件或设备的日志数据;然后,配置rsyslog-kafka模块,指定Kafka的主题(topic)和其他相关参数;接下来,rsyslog-kafka将会将收集到的日志数据传输到Kafka消息队列中;最后,消费者可以从Kafka消息队列中实时接收、处理和存储这些日志数据。 rsyslog-kafka具有一些优点。首先,通过使用Kafka作为消息队列,可以轻松地扩展和处理大量的日志数据。其次,rsyslog-kafka提供了高度可配置性,可以根据需求选择日志的格式、过滤器和其他参数。此外,rsyslog-kafka还支持故障转移和高可用性机制,确保日志数据的可靠传输和存储。 总之,rsyslog-kafka是一种强大的工具,可以将rsyslog日志服务器与Kafka消息队列集成,实现高效的日志收集、传输、处理和存储。它为大规模的日志数据场景提供了解决方案,并提供了灵活的配置选项和高可靠性的机制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值