SpringBoot + Kafka 消费者,用来监听 3 个不同 topic 的加密消息 → 解密 → 解析 → 入库
接收代码
功能拆解:
监听 3 个 Kafka 主题:JD/GD/HF 三种工单
消息是 AES 加密 的,用 | 分割字段
解密后转成对应 DTO
调用 service 插入数据库
java
import static com.zznode.jiake.e2e.common.util.AESUtil.desEncrypt;
@Slf4j
@RefreshScope
@Component
@ConditionalOnProperty(name = "spring.kafka.enabled", havingValue = "true")
public class KfkMessageController {
@Value("${spring.kafka.topic.jd_name}")
private String jdTopicName;
@Value("${spring.kafka.topic.gd_name}")
private String gdTopicName;
@Value("${spring.kafka.topic.hf_name}")
private String hfTopicName;
@Value("${spring.kafka.aesKey}")
private String aeskey;
@Autowired
NewKftsgdServiceImpl kfkService;
// 监听指定的 Topic,动态获取名称
// 监听指定的 Topic,现在直接使用配置项值
@KafkaListener(topics = "${spring.kafka.topic.jd_name}")
public void consumejd(String message) {
log.info("jdTopicName: " + jdTopicName);
this.doit(message, "jd");
}
@KafkaListener(topics = "${spring.kafka.topic.gd_name}")
public void consumegd(String message) {
log.info("gdTopicName: " + gdTopicName);
this.doit(message, "gd");
}
@KafkaListener(topics = "${spring.kafka.topic.hf_name}")
public void consumehf(String message) {
log.info("hfTopicName: " + hfTopicName);
this.doit(message, "hf");
}
public void doit(String message,String type){
log.info("原始消息: " + message);
try {
log.info("aeskey: " + aeskey);
// 1. 分割消息头和消息体(假设格式为 HEADER~BODY)
// String[] parts = message.split("~");
// String header = parts[0]; // 消息头
String body = message; // 消息体
// 2. 按配置的分隔符解析消息体
String[] fields = body.split("\\|");
for(int i=0;i<fields.length;i++){
String str = fields[i];
log.info("encrypt:"+str);
String desEncryptStr = desEncrypt(str, aeskey);
log.info("desEncrypt:"+desEncryptStr+"执行kafka数据接入...");
if(desEncryptStr==null){
log.info("执行失败!");
return;
}else{
if("gd".equals(type)){
doAddInfoGd(desEncryptStr);
}else if ("hf".equals(type)){
doAddInfoZjdf(desEncryptStr);
}else if ("jd".equals(type)){
doAddInfoLd(desEncryptStr);
}
}
}
}catch(Exception e){
log.info("e:"+e);
}
}
/**新一代客服投诉工单-直接答复*/
public void doAddInfoZjdf(String desEncryptStr){
try {
NewkftsgdZjdfDTO dto = JsonUtils.parseObject(desEncryptStr, NewkftsgdZjdfDTO.class);
log.debug("dto:"+JSON.toJSONString(dto, SerializerFeature.WriteMapNullValue));
log.debug("新一代客服投诉工单-直接答复 kafka 数据接入...");
kfkService.insertNewKftsgdZjdf(dto);
}catch(Exception e){
log.error("e:"+e);
}
}
/**新一代客服投诉工单-归档*/
public void doAddInfoGd(String desEncryptStr){
try {
NewkftsgdGdDTO dto = JsonUtils.parseObject(desEncryptStr, NewkftsgdGdDTO.class);
log.debug("dto:"+JSON.toJSONString(dto, SerializerFeature.WriteMapNullValue));
log.debug("新一代客服投诉工单-归档 kafka 数据接入...");
kfkService.insertNewKftsgdGd(dto);
}catch(Exception e){
log.error("e:"+e);
}
}
/**新一代客服投诉工单-立单,现场解决*/
public void doAddInfoLd(String desEncryptStr){
try {
// NewkftsgdLdDTO dto = JsonUtils.parseObject(desEncryptStr, NewkftsgdLdDTO.class);
NewkftsgdLdDTO dto = JsonUtils.parseObject(desEncryptStr, NewkftsgdLdDTO.class);
log.debug("dto:"+JSON.toJSONString(dto, SerializerFeature.WriteMapNullValue));
log.debug("新一代客服投诉工单-现场解决 kafka 数据接入...");
kfkService.insertNewKftsgdLd(dto);
}catch(Exception e){
log.error("e:"+e);
}
}
}
安全认证
证书信息

security.protocol: SASL_PLAINTEXT
sasl.mechanism: GSSAPI
sasl.kerberos.service.name: kafka
sasl.jaas.config: Krb5LoginModule + keytab
公司 Kafka 开启了 Kerberos 安全认证
所以必须配证书、密钥表,否则连不上。
nacos配置
js
spring:
kafka:
enabled: false # 设置为true或false来控制是否启用kafka
aesKey: exhinkplsgjlinsg
bootstrap-servers: ${KAFKA_SERVERS}
consumer:
group-id: kafka-consumer-group
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
auto-offset-reset: latest
#latest
enable-auto-commit: false
properties:
security.protocol: SASL_PLAINTEXT # 根据需要选择SASL_PLAINTEXT或SASL_SSL
sasl.mechanism: GSSAPI
sasl.kerberos.service.name: kafka # 这应与jaas配置中的serviceName匹配
sasl.jaas.config: |
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
keyTab="/data/keytabs/uino.keytab"
principal="uino@BMCC.COM";
listener:
ack-mode: manual_immediate
topic:
jd_name: GD_DXWT_JK_JIANDAN
hf_name: GD_DXWT_JK_HUIFU
gd_name: GD_DXWT_JK_GUIDANG
consumer-group: kafka-consumer-group
header-delimiter: "~"
field-delimiter: "|"
后续补充
修复 ACK 提交
修复分割逻辑
加入异常重试
加入死信队列
加入日志追踪
加入并发配置