一、KafkaListener消费

    /**
* 手动提交监听.
*
* @param record 消息记录
* @param ack 确认实例
*/
@Override
@KafkaListener(id = ConsumerConst.LISTENER_ID_WARNING, topics = {"${kafka.app.topic.warning}"}, containerFactory = "ackContainerFactory", groupId = "warning")
public void ackListener(ConsumerRecord record, Acknowledgment ack) {
if (LOG.isInfoEnabled()) {
LOG.info("###################预警ackListener接收到消息###################");
} boolean ackFlag = true;
long beginTime = System.currentTimeMillis();
try {
WarningInfo warningInfo = parseConsumerRecord(record);
if (null == warningInfo) {
dingTalkService.sendMessage(MessageFormat.format(ConsumerConst.DING_TALK_MSG_1, new Object[]{record.topic(), record.value()}));
} else {
warningBusinessHandle.doHandle(record, warningInfo);
}
// } catch (BusinessException ex) {
// LOG.error(record.topic() + "消费失败:" + ex.getMessage(), ex);
// // 业务处理失败(目前暂无此场景),把消息发送至重试主题
// this.sendRetryTopic(record, this.interceptErrMessage(ex.getMessage()));
} catch (Exception e) {
LOG.error("[" + record.topic() + "]消费发生运行时异常:" + e.getMessage(), e);
ackFlag = false;
consumerListenerServiceImpl.stopListener(ConsumerConst.LISTENER_ID_WARNING);
dingTalkService.sendMessage(MessageFormat.format(ConsumerConst.DING_TALK_MSG_2, new Object[]{record.topic()}));
} finally {
if (ackFlag) {
// 手动提交offset
ack.acknowledge();
}
LOG.info("###################预警ackListener处理完消息,耗时" + (System.currentTimeMillis()-beginTime) + "ms ###################");
}
}

二、使用KafkaListenerEndpointRegistry实现启动和停止功能

下面参数里面的listenerId值,必须是消费时@KafkaListener注解中指定的id值:@KafkaListener(id = ConsumerConst.LISTENER_ID_WARNING
package com.macaupass.kafka.consumer.service.impl;

import com.macaupass.kafka.consumer.service.KafkaConsumerListenerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.config.KafkaListenerEndpointRegistry;
import org.springframework.stereotype.Service; /**
* Kafka消费监听服务实现类.
*
* @author weixiong.cao
* @date 2019/7/2
*/
@Service
public class KafkaConsumerListenerServiceImpl implements KafkaConsumerListenerService { /**
* LOG.
*/
private static final Logger LOG = LoggerFactory.getLogger(KafkaConsumerListenerServiceImpl.class); /**
* registry.
*/
@Autowired
private KafkaListenerEndpointRegistry registry; /**
* 开启监听.
*
* @param listenerId 监听ID
*/
@Override
public void startListener(String listenerId) {
//判断监听容器是否启动,未启动则将其启动
if (!registry.getListenerContainer(listenerId).isRunning()) {
registry.getListenerContainer(listenerId).start();
}
//项目启动的时候监听容器是未启动状态,而resume是恢复的意思不是启动的意思
registry.getListenerContainer(listenerId).resume();
LOG.info(listenerId + "开启监听成功。");
} /**
* 停止监听.
*
* @param listenerId 监听ID
*/
@Override
public void stopListener(String listenerId) {
registry.getListenerContainer(listenerId).stop();
LOG.info(listenerId + "停止监听成功。");
} }

三、Controller

package com.macaupass.kafka.consumer.controller;

import com.macaupass.kafka.consumer.service.impl.KafkaConsumerListenerServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap;
import java.util.Map; /**
* Kafka消费监听Controller.
*
* @author weixiong.cao
* @date 2019/7/2
*/
@Controller
@RequestMapping(value = "/listener")
public class KafkaConsumerListenerController { /**
* LOG.
*/
private static final Logger LOG = LoggerFactory.getLogger(KafkaConsumerListenerController.class); /**
* 注入监听服务.
*/
@Autowired
private KafkaConsumerListenerServiceImpl kafkaConsumerListenerService; /**
* 开启监听.
*
* @param listenerId 监听ID
*/
@RequestMapping("/start")
@ResponseBody
public Map<String, String> startListener(@RequestParam(required=false) String listenerId) {
if (LOG.isInfoEnabled()) {
LOG.info("开启监听...listenerId=" + listenerId);
} Map<String, String> retMap = new HashMap<>();
try {
kafkaConsumerListenerService.startListener(listenerId);
retMap.put("respCode", "0000");
retMap.put("respMsg", "启动成功。");
} catch (Exception e) {
LOG.error(e.getMessage(), e);
retMap.put("respCode", "0001");
retMap.put("respMsg", "启动失败:" + e.getMessage());
}
return retMap;
} /**
* 停止监听.
*
* @param listenerId 监听ID
*/
@RequestMapping("/stop")
@ResponseBody
public Map<String, String> stopListener(@RequestParam(required=false) String listenerId) {
if (LOG.isInfoEnabled()) {
LOG.info("停止监听...listenerId=" + listenerId);
} Map<String, String> retMap = new HashMap<>();
try {
kafkaConsumerListenerService.stopListener(listenerId);
retMap.put("respCode", "0000");
retMap.put("respMsg", "停止成功。");
} catch (Exception e) {
LOG.error(e.getMessage(), e);
retMap.put("respCode", "0001");
retMap.put("respMsg", "停止失败:" + e.getMessage());
}
return retMap;
} /**
* 访问入口.
*/
@RequestMapping("/index")
public String index() {
return "kafka/listener";
} }

四、JSP界面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>消费监听管理</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../css/common.css">
<script src="../jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
var contextPath = "<%=request.getContextPath() %>"; /**
* 开启监听.
*
* @param listenerId 监听ID
*/
function startListener(listenerId) {
ajaxPostByJson(contextPath + "/listener/start?listenerId=" + listenerId);
} /**
* 停止监听.
*
* @param listenerId 监听ID
*/
function stopListener(listenerId) {
ajaxPostByJson(contextPath + "/listener/stop?listenerId=" + listenerId);
} /**
* ajax请求.
*
* @param url 请求url
*/
function ajaxPostByJson(url) {
$.ajax({
type: "POST",
url: url,
dataType:"json",
contentType : 'application/json;charset=utf-8',
success: function(respData){
alert(respData.respMsg);
},
error: function(res){
alert("系統異常:" + res.responseText);
}
});
}
</script>
</head>
<body text=#000000 bgColor="#ffffff" leftMargin=0 topMargin=4>
<div id="main">
<div id="head">
<dl class="alipay_link">
<a target="_blank" href=""><span>&nbsp;</span></a>
</dl>
<span class="title">Kafka消费手动管理</span>
</div>
<div class="cashier-nav">
</div>
<form name=query method=post>
<div id="body" style="clear:left">
<dl class="content">
<dd>
<span class="new-btn-login-sp">
<button class="new-btn-login" type="button" style="text-align:center;" onclick="startListener('listenerIdWarning')">开启【预警】消费</button>
</span>
<span class="new-btn-login-sp">
<button class="new-btn-login" type="button" style="text-align:center;" onclick="stopListener('listenerIdWarning')">停止【预警】消费</button>
</span>
</dd>
</dl>
</div>
</form>
</div>
</body>
</html>

五、功能界面

Spring-Kafka —— KafkaListener手动启动和停止的更多相关文章

  1. Spring Boot应用的启动和停止(Spring Boot应用通过start命令启动)

    Spring Boot,作为Spring框架对“约定优先于配置(Convention Over Configuration)”理念的最佳实践的产物,它能帮助我们很快捷的创建出独立运行.产品级别的基于S ...

  2. Spring-Kafka —— KafkaListener定时启动和停止

    一.定时启动的应用场景 比如现在单机环境下,我们需要利用Kafka做数据持久化的功能,由于用户活跃的时间为早上10点至晚上12点,那在这个时间段做一个大数据量的持久化可能会影响数据库性能导致用户体验降 ...

  3. 用批处理文件来手动启动和停止Oracle服务

    服务名称 说明 OracleOracle_homeTNSListener  对应于数据库的监听程序 OracleServiceSID   对应于数据库的例程 OracleDBConsoleSID    ...

  4. 手动启动jenkins

    无论Linux还是windows, jenkins都是作为一个后台服务存在的. 所以在Linux下,手动启动或停止jenkins: service jenkins start service jenk ...

  5. Spring Kafka和Spring Boot整合实现消息发送与消费简单案例

    本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...

  6. Spring Kafka整合Spring Boot创建生产者客户端案例

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 创建一个kafka-producer-master的maven工程.整个项目结构如下: ...

  7. Spring Kafka中关于Kafka的配置参数

    #################consumer的配置参数(开始)################# #如果'enable.auto.commit'为true,则消费者偏移自动提交给Kafka的频率 ...

  8. C#操作注册服务卸载服务启动服务停止服务.. .

    using Microsoft.Win32; using System; using System.Collections; using System.Collections.Generic; usi ...

  9. linux 下 apache相关;启动、停止、重启命令;配置文件位置等等

    linux 下 apache启动.停止.重启命 基本的操作方法: 本文假设你的apahce安装目录为/usr/local/apache2,这些方法适合任何情况 apahce启动命令: 推荐/usr/l ...

随机推荐

  1. java线程基础巩固---创建并启动线程

    对于java的并发编程方面的东东,不管是面试还是实际工作开发都是非常重要的,而往往只要涉及到并发相关的东东有点让人觉得有点难,而实际工作中涉及到并发可能就是简单的用下同步块.上锁之类的一些简单的操作, ...

  2. 2019 Petrozavodsk Winter Camp, Yandex Cup C. Diverse Singing 上下界网络流

    建图一共建四层 第一层为N个歌手 第二层为{pi,li} 第三层为{si,li} 第四层为M首歌 除了S和第一层与第三层与T之间的边为[1,INF] 其他边均为[0,1] #include<bi ...

  3. Codeforces 1175F The Number of Subpermutations

    做法①:RMQ(预处理NLOGN+后续跳跃蜜汁复杂度) 满足题意的区间的条件转换: 1.长度为R-L+1则最大值也为R-L+1 2.区间内的数不重复 当RMQ(L,R)!=R-L+1时 因为已经保证了 ...

  4. Python&Selenium 数据驱动【unittest+ddt+xml】

    一.摘要 本博文将介绍Python和Selenium做自动化测试的时候,基于unittest框架,借助ddt模块使用xml文件作为数据文件作为测试输入 二.xml文件 <?xml version ...

  5. Vue入门(三)——模拟网络请求加载本地数据

    1.首先我们需要在webpack.dev.conf.js中const PORT = process.env.PORT && Number(process.env.PORT) 的后面追加 ...

  6. SpringBoot 配置 Tomcat SSL

    SpringBoot 配置 Tomcat SSL SSL(Secure Sockets Layer , 安全套接层)是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密 ...

  7. C语言之volatile

    emOsprey  鱼鹰谈单片机 2月21日 预计阅读时间: 4 分钟 和 const 不同(关于 const 可以看 const 小节),当一个变量声明为 volatile,说明这个变量会被意想不到 ...

  8. 音频转换 wav to wav、mp3或者其它

    1.首先介绍一种NAudio 的方式 需要导入 NAudio.dll 下面请看核心代码 using (WaveFileReader reader = new WaveFileReader(in_pat ...

  9. 06-vue项目02:vuex、Mutation、Action、ElementUI、axios

    1.Vuex 1.为什么使用VueX data从最上面的组件,一层层往下传值,一层层的验证 Vue单向数据流 “中央空调“,代理 VueX 解决数据 传值.. 2.Vuex介绍与安装 (1)Vuex官 ...

  10. laravel各种请求类

    curl请求类 composer require php-curl-class/php-curl-class