maven配置:
<properties>
<java.version>1.8</java.version>
<oracle.version>11.2.0.4</oracle.version>
</properties>
<!--kafka-->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<!--oracle-->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
yml:
#省内集中调度平台资源查询
server:
port: 9080
spring:
datasource:
driver-class-name: oracle.jdbc.OracleDriver
# url: jdbc:oracle:thin:@10.216.86.211:1521/irmsdb
# username: hbrmw6
# password: ZIYhbrmw6.184
url: ${rmsdb_url:jdbc:oracle:thin:@10.110.74.166:1521/rmsdb}
username: ${rmsdb_username:uirms_yn}
password: ${rmsdb_password:uirms_yn}
kafka:
bootstrap-servers: 127.0.0.1:9092 # kafka集群信息
producer: # 生产者配置
retries: 3 # 设置大于0的值,则客户端会将发送失败的记录重新发送
batch-size: 16384 #16K
buffer-memory: 33554432 #32M
acks: 1
# 指定消息key和消息体的编解码方式
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
consumer:
group-id: zhTestGroup # 消费者组
enable-auto-commit: false # 关闭自动提交
auto-offset-reset: earliest # 当各分区下有已提交的offset时,从提交的offset开始消费;无提交的offset时,从头开始消费
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
listener:
# 当每一条记录被消费者监听器(ListenerConsumer)处理之后提交
# RECORD
# 当每一批poll()的数据被消费者监听器(ListenerConsumer)处理之后提交
# BATCH
# 当每一批poll()的数据被消费者监听器(ListenerConsumer)处理之后,距离上次提交时间大于TIME时提交
# TIME
# 当每一批poll()的数据被消费者监听器(ListenerConsumer)处理之后,被处理record数量大于等于COUNT时提交
# COUNT
# TIME | COUNT 有一个条件满足时提交
# COUNT_TIME
# 当每一批poll()的数据被消费者监听器(ListenerConsumer)处理之后, 手动调用Acknowledgment.acknowledge()后提交
# MANUAL
# 手动调用Acknowledgment.acknowledge()后立即提交,一般使用这种
# MANUAL_IMMEDIATE
ack-mode: manual_immediate
生产者:
package com.inspur.resource.module.kafka;
import com.alibaba.fastjson.JSON;
import com.inspur.resource.util.DataShareUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author :fengwenzhe
* @date :Created in 2022/11/14 10:43
* 文件说明: </p>
*/
@Component
@ConditionalOnProperty(value = "spring.profiles.active",havingValue = "kafka")
@Slf4j
public class KafkaTimer {
@Autowired
private KafkaTemplate kafkaTemplate;
@Autowired
private JdbcTemplate jdbcTemplate;
@Scheduled(cron = "*/20 * * * * ?") // 每20秒执行一次
//@Scheduled(cron = "0 */2 * * * ?") //每2分钟执行一次
@PostConstruct
public void loopSendKafka(){
//查询数据库 如果有指定数据 则发送对应kafka消息
String sql = "select * from RMS_KAFKA_ACCESS_ORDER where stateflag ='0' ";
List<Map<String,Object>> list = this.jdbcTemplate.queryForList(sql);
if(null != list){
for(Map map:list){
//需要发送kafka消息的入网工单数据
log.info("需要发送kafka消息的入网工单数据"+ map.toString());
System.out.println("sendkafka");
kafkaTemplate.send("test", JSON.toJSONString(map));
}
}
}
}
消费者:
package com.inspur.resource.module.kafka;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
@ConditionalOnProperty(value = "spring.profiles.active",havingValue = "kafka")
@Slf4j
public class KafkaConsumer {
private final Logger logger = LoggerFactory.getLogger(KafkaConsumer.class);
//不指定group,默认取yml里配置的
@KafkaListener(topics = {"test"},groupId = "${spring.kafka.consumer.group-id}")
public void onMessage1(ConsumerRecord<?, ?> consumerRecord, Acknowledgment ack) {
//消费者必须手动调用ack.acknowledge();不然会重复消费 因为在yml中配置了
//ack-mode: manual_immediate
ack.acknowledge();
Optional<?> optional = Optional.ofNullable(consumerRecord.value());
if (optional.isPresent()) {
Object msg = optional.get();
logger.info("message:{}", msg);
}
}
}