记一次对kafka+elk的研究,直接传的笔记

前情提要

boss看某公司使用的kafka+elk搞审计日志挺好的,让我也搞一下…
我们的项目是使用公司自己的框架,研究到最后发现…
最后发现我们的框架和kafka+elk不兼容,虽然最后没成功,但是研究过程记录一下以备不时之需。
下面是直接导入的我写的笔记,里面的一下安装包之类的我也不提供了,度娘上都有~
作为一个程序员找资料的能力还是得有的。

kafka的使用

一、windows上安装zookeeper

kafka是基于zookeeper的,是在其上面搭建的,所以需要先运行zookeeper再运行kafka

1.解压

将文件夹中的apache-zookeeper-3.7.0-bin.tar.gz解压并记住**安装路径 ** 我的是E:\software\apache-zookeeper-3.7.0-bin

2.将安装路径配置成系统环境变量

3.修改zookeeper配置文件:

在zookeeper安装路径下,conf文件夹中,将其中的“zoo_sample.cfg”重命名为“zoo.cfg“。

4.测试

win+R cmd 输入zKserver测试是否成功

5.注:

电脑上没有安装jdk的话会启动不成功

二、windows上安装kafka

1.解压

将文件夹中的kafka_2.11-2.4.0.tgz解压,记住**安装路径 ** 我的是E:\kafka_2.11-2.4.0

!!!解压路径不能过深,不能有中文 不然启动的时候会报文本过长错误

2.修改kafka配置文件:

kafka安装路径 \config\server.properties中的

lod.dirs 日志存储地址 改成自定义目录,也可默认 我的是E:\log

zookeeper.connect=localhost:2181 zookeeper连接地址

3.测试启动:

1.启动zookeeper:cmd输入zkServer
2.启动kafka,新建cmd
cd E:\kafka_2.11-2.4.0
.\bin\windows\kafka-server-start.bat .\config\server.properties
3.创建主题,新建cmd
cd E:\kafka_2.11-2.4.0\bin\windows
创建topic: kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic testTopic
查看topic: kafka-topics.bat --list --zookeeper localhost:2181
删除topic: kafka-topics.bat --delete --zookeeper 【zookeeper server】 --topic 【topic name】
4.创建生产者,新建cmd
cd E:\kafka_2.11-2.4.0\bin\windows
kafka-console-producer.bat --broker-list localhost:9092 --topic testTopic
5.创建消费者,新建cmd
cd E:\kafka_2.11-2.4.0\bin\windows
kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic testTopic–from-beginning
6.生产消息并消费 生产者cmd输入,消费者cmd有输出

!!!注意 发消息后需要在启动kafka的cmd界面点一下 回车,因为kafka不会自动提交数据,需要手动提交

4.注:

zookeeper默认的启动路径和地址是 localhost:2181

kafka默认启动地址是localhost:9092

zookeeper配置文件:\conf \zoo.cfg
kafka配置文件:\config\server.properties

三、工程配置及项目启动

1.导包

将jar包文件夹中的4个jar包 放入工程主项目的 publib文件夹下 gradle刷新一下 重新导入本地jre

子项目 gradle刷新 重新导入本地jre

2.springboot集成kafka

修改子项目的 application.properties 文件

添加如下:

#id:port
spring.kafka.bootstrap-servers = localhost:9092
#发生错误后,消息重发的次数。
spring.kafka.producer.retries = 0 
#当有多个消息需要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算。
spring.kafka.producer.batch-size= 4096
# 设置生产者内存缓冲区的大小。
spring.kafka.producer.buffer-memory= 40960
# 键的序列化方式
spring.kafka.producer.key-serializer= org.apache.kafka.common.serialization.StringSerializer
# 值的序列化方式
spring.kafka.producer.value-serializer= org.apache.kafka.common.serialization.StringSerializer
spring.kafka.consumer.group-id= test-consumer
# 是否自动提交偏移量,默认值是true,为了避免出现重复数据和数据丢失,可以把它设置为false,然后手动提交偏移量
spring.kafka.consumer.enable-auto-commit= true
# 自动提交的时间间隔 在spring boot 2.X 版本中这里采用的是值的类型为Duration 需要符合特定的格式,如1S,1M,2H,5D
spring.kafka.consumer.auto-commit-interval= 1S
# 键的反序列化方式
spring.kafka.consumer.key-deserializer= org.apache.kafka.common.serialization.StringDeserializer
# 值的反序列化方式
spring.kafka.consumer.value-deserializer= org.apache.kafka.common.serialization.StringDeserializer

3.编写测试生产者

kafkaTemplate.send(topic,message);

kafkaTemplate.send(topic,key,message);

kafkaTemplate.send(topic,partition,key,message);

key和partition:

kafka中每个topic被划分为多个分区patition,若发送消息时未指定 patition,但指定了 key,则对key值进行hash计算,根据计算结果路由到指定分区,这种情况下可以保证同一个 Key 的所有消息都进入到相同的分区。key不是必须。

package com.edft.idx.service.managecenter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@CrossOrigin("*")
@RequestMapping("/KafkaTemplate")
public class KafkaProducer {

	@Autowired
	private KafkaTemplate<String, Object> kafkaTemplate;
	@RequestMapping("/send")
	public void send(Object obj) {
        ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send("topic1", "aaa");
        ListenableFuture<SendResult<String, Object>> future2 = kafkaTemplate.send("topic1", "key1", "bbb");
        kafkaTemplate.flush();
        ListenableFutureCallback<SendResult<String, Object>> callback = new ListenableFutureCallback<SendResult<String, Object>>() {
	        @Override
	        public void onFailure(Throwable throwable) {
	            //发送失败的处理
	            System.out.println(" - 生产者 发送消息失败:" + throwable.getMessage());
	        }
	
	        @Override
	        public void onSuccess(SendResult<String, Object> stringObjectSendResult) {
	            //成功的处理
	        	System.out.println(" - 生产者 发送消息成功:" + stringObjectSendResult.toString());
	        }
	    };
        future.addCallback(callback);
        future2.addCallback(callback);
	}
}

4.依次启动

1).启动zookeeper: cmd输入

zkServer

2).启动kafka,新建cmd

e:
cd E:\kafka_2.11-2.4.0
.\bin\windows\kafka-server-start.bat .\config\server.properties

3).创建主题,新建cmd

e:
cd E:\kafka_2.11-2.4.0\bin\windows
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic topic1

4).创建消费者,新建cmd

e:
cd E:\kafka_2.11-2.4.0\bin\windows
kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic topic1 --from-beginning

5.启动项目

6.浏览器直接输入url:

http://localhost:8089/KafkaTemplate/send

7.查看消费者

消费者cmd窗口 打印了aaa,测试成功

8.注:

消费者窗口启动后会自动打印之前的所有日志信息。

四、编写测试消费者

1.编写测试消费者

package com.edft.idx.service.managecenter;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.annotation.PartitionOffset;
import org.springframework.kafka.annotation.TopicPartition;
import org.springframework.stereotype.Component;


@Component
public class KafkaConsumer {
	@KafkaListener(id = "consumer1",groupId = "group1",topicPartitions = {
	        @TopicPartition(topic = "topic1",partitionOffsets = @PartitionOffset(partition = "0", initialOffset = "0"))
	})
    public  void  reveice(ConsumerRecord<?, ?> record){
    	System.out.println("简单消费:"+record.topic()+"-"+record.partition()+"-"+record.value());
    	
    }
}


关于consumer的group.id

mq一共有两种基本消费模式:

  1. load balancing(负载均衡):共享订阅、提高性能
  2. fan-out(扇出):各自订阅、互不影响

group内是load balancing,group间是fan-out

五、kafka中一些名词的解释

  • Topic:一类消息,主题,Kafka集群能够同时负责多个topic的分发。

  • Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。list

  • Segment:partition物理上由多个segment组成。

  • offset:每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息。相当于arraylist里的下标,list中存着一条条message。

    消费者可以通过offset获取消息。

  • key:若发送消息时未指定 patition,但指定了 key,则对key值进行hash计算,根据计算结果路由到指定分区,这种情况下可以保证同一个 Key 的所有消息都进入到相同的分区。key不是必须。

  • KafkaTemplate:kafka生产者实例对象,可以进行消息的发送。

  • @KafkaListener:配置kafka监听器,可以通过此注解创建消费者,举个此注解使用的例子:

    @KafkaListener(id = "consumer1",groupId = "felix-group",topicPartitions = {
            @TopicPartition(topic = "topic1", partitions = { "0" }),
            @TopicPartition(topic = "topic2", partitions = "0", partitionOffsets = @PartitionOffset(partition = "1", initialOffset = "8"))
    })
    //同时监听topic1和topic2,监听topic1的0号分区、topic2的 "0号和1号" 分区,指向1号分区的offset初始值为8
    
  • @TopicPartition:配置监听哪个topic,还可以配置分区partitions,还可以配置partitionOffsets相当于消息编号的set集合

  • @PartitionOffset:配置offset所在分区,配置initialOffset初始查询位置,和@TopicPartition中的partitions不可相同

六、ELK介绍

ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana

E:日志存储,L:相当于一个io,这里由kafka输入,输出到es,K:日志查询工具

七、ELKA+kafka做日志收集的过程:

1.通过spring AOP切面注入,给所有controller层方法注入前置方法和后置方法。

前置方法:将参数,请求对象的ip url port等信息写成日志,并写入kafka

后置方法:将返回值,返回值类型等信息携程日志,并写入kafka

2.springboot加个全局异常处理,将异常消息推送到Kafka。

3.Logstash,即ELK中的L,类似io,编写配置文件,并使用此配置文件启动。配置文件配置的内容:从kafka中读取日志信息,发布到ES服务。ES服务即ELK中的E。

4.通过Kibana,即ELK中的K,从ES服务中查询日志

八、定义一个kafka操作类

1.写一个kafka对象autoware的util类

package com.edft.idx.util;

import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class KafkaUtil {
	
	public static KafkaTemplate<String, String> kafkaTemplate=null;
	
	@Resource
	@Qualifier("kafkaTemplate")
	public void setTemp(KafkaTemplate temp) {
		KafkaUtil.kafkaTemplate = temp;
	}
	
}

2.kafak推送消息的操作类

package com.edft.idx.service.managecenter;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.edft.idx.util.KafkaUtil;
import com.edft.idx.util.RedisUtil;

import groovy.util.logging.Log4j;

@Log4j
@Component
public class KafkaSender {
	
		@Autowired
		//@Qualifier("kafkaTemplate")
		private KafkaTemplate<String, String> autokafkaTemplate;
		private KafkaTemplate<String, String> utilKafkaTemplate=KafkaUtil.kafkaTemplate;
	    private Logger log = Logger.getLogger("");
	    /**
	     * 获取kafka操作对象
	     * @return 
	     */
	    public KafkaTemplate<String, String> getTemplate(){
			if (utilKafkaTemplate==null && autokafkaTemplate==null) {
				throw new RuntimeException("未获取到redisTemplate对象");
			}
			if (utilKafkaTemplate==null) {
				return autokafkaTemplate;
			}else {
				return utilKafkaTemplate;
			}
		}
	    /**
	     * Kafka发送消息
	     * @param <T>
	     * @param obj 消息
	     */
	    public <T> void send(T obj){
	        String jsonObj = JSON.toJSONString(obj);
			//TODO 发送消息后期实现可自动化配置,如主题名
	        ListenableFuture<SendResult<String, String>> future = this.getTemplate().send("order_log",jsonObj);
	        //回调通知
	        future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
	            @Override
	            public void onFailure(Throwable throwable) {
	            	log.info("Produce: The message failed to be send: "+throwable.getMessage());
	            }

	            @Override
	            public void onSuccess(SendResult<String, String> stringStringSendResult) {
	                //TODO 业务处理
	                log.info("Produce: The message was send successfully: "+stringStringSendResult.toString());
	            }
	        });
	    }
}

kafka部分告一段落了,下面是ELK的安装及配置

九、ElasticSearch安装

1.解压

elasticsearch-7.3.2-windows-x86_64.zip解压到自定义路径 并记住安装目录 我的是E:\software\elasticsearch-7.3.2

2.改配置文件

config文件夹下的elasticsearch.yml文件添加下面几行

#监听地址和端口
network.host: 127.0.0.1
http.port: 9200
#跨域配置
http.cors.enabled: true
http.cors.allow-origin: "*"

3.启动

bin文件夹下双击执行

elasticsearch.bat

看到started说明启动成功

4.浏览器测试

浏览器访问路径

http://localhost:9200

显示

{
  "name" : "MYCOMPUTER",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "LBr9skGYRNGt1aBYWS5_tg",
  "version" : {
    "number" : "7.3.2",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "1c1faf1",
    "build_date" : "2019-09-06T14:40:30.409026Z",
    "build_snapshot" : false,
    "lucene_version" : "8.1.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

配置成功

十、安装ElasticSearch-head插件

1.安装node环境 nodejs

node-v14.17.6-x64.msi运行后一路next 我的目录还是E:\software\nodejs

2.改配置

在安装目录下,新建两个文件夹,node-cache和node-global

cmd运行以下两条命令

npm config set prefix "E:\software\nodejs\node-global"
npm config set cache "E:\software\nodejs\node-cache"

这样此后所安装的模块都会安装到该路径下。

3.配置环境变量

将nodejs和node-global的路径配置进path

4.测试

cmd运行

npm install -g grunt-cli

nodejs安装grunt测试,看到node-global文件夹中有了grunt,安装成功。

5.安装ElasticSearch-head

1).两种方式 推荐方式二

方式一:文件夹中有elasticsearch-head-master.zip包,直接解压

进入解压后的文件夹下,执行命令:npm install (此处是为安装进行安装pathomjs)

如果安装速度慢,设置成淘宝的镜像重新安装

npm config set registry https://registry.npm.taobao.org
npm install 
npm audit fix

方式二:cmd进入 自定义安装路径,依次运行以下命令

git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm audit fix

6.修改配置文件:

E:\software\elasticsearch-head 的connect: server: options:下添加属性hostname,值为’*’

connect: {
    server: {
        options: {
            hostname:'*',
            port: 9100,
            base: '.',
            keepalive: true
        }
    }
}

7.启动ElasticSearch-head

进安装目录

e:
cd E:\software\elasticsearch-head
npm run start   或者
grunt server

启动head插件

8.测试

浏览器直接访问

http://localhost:9100

测试成功:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2mObujDy-1649298641116)(\img\1.png)]

到此,Elasticsearch和ElasticSearch-head已经装好了。

9.ElasticSearch安装为Windows服务(可不做)

可不做:通过npm命令启动也一样

1.E:\software\elasticsearch-7.3.2\bin 有一个elasticsearch-service.bat

2.cmd在此目录下执行: (!!!管理员模式运行)

elasticsearch-service.bat install

3.打开服务

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1lntDQmw-1649298641117)(\img\2.png)]

可以看到服务已经注册成功。

elasticsearch-service.bat start 服务启动

elasticsearch数据默认存储位置是:

 E:\software\elasticsearch-7.3.2\data

综上,现在要启动的软件变为4个,zookeeper,kafka,elasticsearch,elasticsearch-header

十一、Logstash安装及使用

Logstash是一个接收,处理,转发日志的工具。支持各种类型的日志。

1.解压

logstash-7.3.2.zip解压到E:\software\logstash-7.3.2

2.改配置文件

cofig文件夹下新建logstash.conf文件,修改内容为:

input {
	kafka{
		# 指定Kafka地址,集群则逗号分隔
		bootstrap_servers => "localhost:9092"
		# 订阅的主题
		topics => ["topic1"]
		reset_beginning => true
		group_id => "logstash"
        enable.auto.commit设置为false
	}
}
output{
	stdout { codec => rubydebug}
	elasticsearch {
		# 指定ES服务地址 做了集群的话可指定多个
		hosts => ["localhost:9200"]
		# 指定索引名称,可自定义,但尽量有意义 
		index => "topic1"
	}
}

关于reset_beginning

true:从头开始读取kafka中的消息

false:只消费刚发布的数据

3.启动

cd E:\software\logstash-7.3.2\bin
logstash.bat -f ../config/logstash.conf

4.修改kafka指定消费组的offset

没找到logstash指定offset消费topic的方法,只能手动操作kafka了

cmd进入kafka安装目录中的bin文件夹下

修改kafka指定消费者组的offset偏移量命令:

kafka-consumer-groups.bat  --bootstrap-server localhost:9092 --group group1 --topic topic1 --reset-offsets --to-offset 0 -execute

修改号偏移量再启动logstash,即重复第三步。可以看到数据从头开始往ES中加载了。

5.测试

浏览器访问

http://localhost:9100/

十二、kafka配置重新总结

1.编写kafkautil工具类:

此类提供kafka消费者的一些必须信息props

此类提供kafkaTemplate对象的Setter方法注入

package com.edft.idx.util;

import java.util.Properties;

import javax.annotation.Resource;

import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class KafkaUtil {
	//消费者配置
	public static Properties props = new Properties();
	static{
		KafkaUtil.props.put("bootstrap.servers", "127.0.0.1:9092");
		KafkaUtil.props.put("group.id", "group1");
		KafkaUtil.props.put("enable.auto.commit", true);
		KafkaUtil.props.put("auto.commit.interval.ms", 5000);
		KafkaUtil.props.put("session.timeout.ms", 50000);
		KafkaUtil.props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
		KafkaUtil.props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
		KafkaUtil.props.put("auto.offset.reset", "earliest");
	}
	//生产者  	static不能autoware注入,通过setter注入
	public static KafkaTemplate<String, String> kafkaTemplate=null;
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Resource
	@Qualifier("kafkaTemplate")
	public void setTemp(KafkaTemplate temp) {
		KafkaUtil.kafkaTemplate = temp;
	}
}

2.编写kafka发布者类

此类提供了kafka消息发布方法

package com.edft.idx.service.managecenter;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
import com.alibaba.fastjson.JSON;
import com.edft.idx.util.KafkaUtil;
import groovy.util.logging.Log4j;

@Log4j
@Component
public class KafkaSender {
	
		@Autowired
		private KafkaTemplate<String, String> autokafkaTemplate;
		private KafkaTemplate<String, String> utilKafkaTemplate=KafkaUtil.kafkaTemplate;
	    private Logger log = Logger.getLogger("");
	    /**
	     * 获取kafka操作对象
	     * @return 
	     */
	    public KafkaTemplate<String, String> getTemplate(){
			if (utilKafkaTemplate==null && autokafkaTemplate==null) {
				throw new RuntimeException("未获取到redisTemplate对象");
			}
			if (utilKafkaTemplate==null) {
				return autokafkaTemplate;
			}else {
				return utilKafkaTemplate;
			}
		}
	    /**
	     * kafka 发送信息
	     * @param topic
	     * @param key
	     * @param message
	     */
	    public void send(String topic,String key,Object message){
	        String jsonObj = JSON.toJSONString(message);
			//TODO 发送消息后期实现可自动化配置,如主题名
	        ListenableFuture<SendResult<String, String>> future = this.getTemplate().send(topic,key,jsonObj);
	        //回调通知
	        future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
	            @Override
	            public void onFailure(Throwable throwable) {
	            	log.info("Produce: The message failed to be send: "+throwable.getMessage());
	            }

	            @Override
	            public void onSuccess(SendResult<String, String> stringStringSendResult) {
	                //TODO 业务处理
	                log.info("Produce: The message was send successfully: "+stringStringSendResult.toString());
	            }
	        });
	    }
}

3.编写kafka操作类,接收者类

此类提供 重置offset方法

此类提供 从头开始消费信息方法

此类提供 消费者获取方法

注:!!!此类中方法不适合实时监控消息。实时操作还是用 里的消费者

package com.edft.idx.service.managecenter;

import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;

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.consumer.OffsetAndMetadata;
import org.apache.kafka.common.TopicPartition;

import com.alibaba.fastjson.JSON;
import com.edft.idx.util.KafkaUtil;


public class KafkaReceive {
	//volatile所有线程都去原始位置取值,而不是在线程内存中取值,也就是说多线程都可以改此变量的值,实现线程交互
	private volatile boolean isRunning = true;
	
	/**
	 * 推荐使用带groupId的,此方法默认groupId为group1
	 * @return
	 */
	public KafkaConsumer<?, ?> getConsumer(){
		
		return new KafkaConsumer<>(KafkaUtil.props);
	}
	/**
	 * 设置分组id获取消费者
	 * @param groupId
	 * @return
	 */
	public KafkaConsumer<?, ?> getConsumer(String groupId){
		Properties props = KafkaUtil.props;
		props.put("group.id", groupId);
		return new KafkaConsumer<>(props);
	}
	
	/**
	 * 订阅消息,private,不提供调用接口
	 * @param consumer
	 * @param topicName
	 * @return
	 */
	private Map<?, ?> getReceiveMsg(KafkaConsumer<?, ?> consumer,String topicName) {
		consumer.subscribe(Arrays.asList("topic1"));
		Map<Object, Object> map = new HashMap<>();
		this.isRunning = true;
        try {
            while (this.isRunning) {
            	KafkaReceive that = this;
            	Timer timer = new Timer(true);
                timer.schedule(new TimerTask() {
					@Override
					public void run() {
						that.isRunning=false;
					}
				}, 0, 2000);//2秒定时
            	
                //获取message
            	//Duration 时间戳计算类  
				ConsumerRecords<String, String> consumerRecords = (ConsumerRecords<String, String>) consumer.poll(Duration.ofMillis(500));
                if (!consumerRecords.isEmpty()) {
                    for (ConsumerRecord<String, String> consumerRecord : consumerRecords) {
                        /*System.out.println("TopicName: " + consumerRecord.topic() + " Partition:" +
                                consumerRecord.partition() + " Offset:" + consumerRecord.offset() + "" +
                                " Msg:" + consumerRecord.value());*/
                    	map.put(consumerRecord.offset(), consumerRecord.value());
                    }
                    timer.cancel();
                    this.isRunning=false;
                }
                
            }
            return map;
        }catch (Exception e){
            //处理异常
        	return null;
        }
        finally {
            close(consumer);
        }

    }
	/**
	 * 从头开始消费消息,2秒没获取到消息返回null
	 * @param groupId
	 * @param topicName
	 * @return
	 */
	public Map<?, ?> getMessageFromBegin(String groupId,String topicName){
		KafkaConsumer<?,?> consumer = this.getConsumer(groupId);
		this.resetOffset(consumer, topicName, 0);
		Map<?, ?> receiveMsg = this.getReceiveMsg(consumer,topicName);
		return receiveMsg;
	}
	
	/**
	 * 关闭消费者
	 * @param consumer
	 */
    public void close(KafkaConsumer<?, ?> consumer) {
        if (consumer != null) {
            consumer.close();
        }
    }
    /**
     * 重置offset,完成后关闭消费者
     * @param consumer
     * @param topicName 
     * @param Partition 分区号
     */
    public void resetOffset(KafkaConsumer<?, ?> consumer,String topicName,Integer Partition) {
		//重置offset,可同时设置多个topic和partition
		Map<TopicPartition, OffsetAndMetadata> hashMaps = new HashMap<TopicPartition, OffsetAndMetadata>();
		hashMaps.put(new TopicPartition(topicName, Partition), new OffsetAndMetadata(0));
		consumer.commitSync(hashMaps);
    }
    
    /*public static void main(String[] args) {
		KafkaReceive kafkaReceive = new KafkaReceive();
		Map<?, ?> map = kafkaReceive.getMessageFromBegin("group1", "topic1");
		System.out.println("*********"+JSON.toJSON(map));
	}*/
}

4.删除消费者组的方法

kafka-consumer-groups.bat --bootstrap-server localhost:2181 --group console-consumer-20861 --delete

十三、安装kibana

Kibana 是一个 用于和 Elasticsearch 一起使用的开源的分析与可视化平台。可以用 kibana 搜索、查看、交互存放在Elasticsearch 索引里的数据。

作用主要是通过类似sql语句操作elasticsearch数据库

1.前提

1).保证安装了JDK

2).保证安装node

3).保证安装了elasticSearch

2.解压

kibana-7.3.2-windows-x86_64.zip E:\software\kibana-7.3.2-windows-x86_64

3.修改配置

\ config\ kibana.yml 分别是配置ES ip端口,界面中文显示

elasticsearch.hosts: "http://localhost:9200"
i18n.locale: "zh-CN"

4.启动

/bin下的kibana.bat 双击运行

十四、SpringBoot整合Elasticsearch

SpringBoot整合Spring Data Elasticsearch

);
consumer.commitSync(hashMaps);
}

/*public static void main(String[] args) {
	KafkaReceive kafkaReceive = new KafkaReceive();
	Map<?, ?> map = kafkaReceive.getMessageFromBegin("group1", "topic1");
	System.out.println("*********"+JSON.toJSON(map));
}*/

}




### 4.删除消费者组的方法

kafka-consumer-groups.bat --bootstrap-server localhost:2181 --group console-consumer-20861 --delete


## 十三、安装kibana

Kibana 是一个 用于和 Elasticsearch 一起使用的开源的分析与可视化平台。可以用 kibana 搜索、查看、交互存放在Elasticsearch 索引里的数据。

作用主要是通过类似sql语句操作elasticsearch数据库

### 1.前提

1).保证安装了JDK

2).保证安装node

3).保证安装了elasticSearch

### 2.解压

kibana-7.3.2-windows-x86_64.zip          E:\software\kibana-7.3.2-windows-x86_64

### 3.修改配置

\ config\ kibana.yml    分别是配置ES ip端口,界面中文显示

elasticsearch.hosts: “http://localhost:9200”
i18n.locale: “zh-CN”


### 4.启动

/bin下的kibana.bat  双击运行

## 十四、SpringBoot整合Elasticsearch

SpringBoot整合Spring Data Elasticsearch

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

静安书以沫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值