Spring-Kafka —— KafkaListener手动启动和停止
一、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> </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手动启动和停止的更多相关文章
- Spring Boot应用的启动和停止(Spring Boot应用通过start命令启动)
Spring Boot,作为Spring框架对“约定优先于配置(Convention Over Configuration)”理念的最佳实践的产物,它能帮助我们很快捷的创建出独立运行.产品级别的基于S ...
- Spring-Kafka —— KafkaListener定时启动和停止
一.定时启动的应用场景 比如现在单机环境下,我们需要利用Kafka做数据持久化的功能,由于用户活跃的时间为早上10点至晚上12点,那在这个时间段做一个大数据量的持久化可能会影响数据库性能导致用户体验降 ...
- 用批处理文件来手动启动和停止Oracle服务
服务名称 说明 OracleOracle_homeTNSListener 对应于数据库的监听程序 OracleServiceSID 对应于数据库的例程 OracleDBConsoleSID ...
- 手动启动jenkins
无论Linux还是windows, jenkins都是作为一个后台服务存在的. 所以在Linux下,手动启动或停止jenkins: service jenkins start service jenk ...
- Spring Kafka和Spring Boot整合实现消息发送与消费简单案例
本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...
- Spring Kafka整合Spring Boot创建生产者客户端案例
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 创建一个kafka-producer-master的maven工程.整个项目结构如下: ...
- Spring Kafka中关于Kafka的配置参数
#################consumer的配置参数(开始)################# #如果'enable.auto.commit'为true,则消费者偏移自动提交给Kafka的频率 ...
- C#操作注册服务卸载服务启动服务停止服务.. .
using Microsoft.Win32; using System; using System.Collections; using System.Collections.Generic; usi ...
- linux 下 apache相关;启动、停止、重启命令;配置文件位置等等
linux 下 apache启动.停止.重启命 基本的操作方法: 本文假设你的apahce安装目录为/usr/local/apache2,这些方法适合任何情况 apahce启动命令: 推荐/usr/l ...
随机推荐
- 常量和iota
定义常量时如果不是必须指定特定类型,可以省略类型,使用默认类型.且数值类型常量(不定义类型)可以直接进行运算 常量的值可以是表达式,但是不允许出现变量 func main() { const a st ...
- php操作kafka
php操作kafka----可以参照网上的安装步骤,先安装ldkafka rdkafka,然乎启动zookeeper和kafka服务器 <?php //$conf = new Rdkafka\P ...
- BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 (LCT维护深度)
要维护深度,就维护一下size就行了.access一下x,那么从根->x这一条链就独立成为一棵splay,那么splay的size节点数就是x的深度. 删边的时候直接access一下,splay ...
- 本地资源图片无法通过 WXSS 获取,可以使用网络图片,或者 base64,或者使用<image/>标签
在微信小程序开发中,当在CSS中使用背景图片格式为png时就会出现: 只要把png格式改掉就可以或者在<image/>标签里面写,我实测用JPG格式和把图片转成base64是没问题的.
- my_note
1.C# $ 内插字符串 Console.WriteLine($"The value of pi is {Math.PI}"); 替代string.format 2. switch ...
- SQL Server孤立用戶
如何解决孤立用户问题 http://blog.csdn.net/zzl1120/article/details/7394468 SQL SERVER孤立用户问题解决方法 http://www.2cto ...
- .net上传整个文件夹
ASP.NET上传文件用FileUpLoad就可以,但是对文件夹的操作却不能用FileUpLoad来实现. 下面这个示例便是使用ASP.NET来实现上传文件夹并对文件夹进行压缩以及解压. ASP.NE ...
- 路由器配置——路由重分布1(rip)
一.实验目的:使用路由重分布达到全网互通 二.拓扑图: 三.具体实验步骤配置 先给各个主机配置ip地址和网关以PC1为例: (1)R1路由器配置 Router>enable --进入特权模式R ...
- 【csp模拟赛2】 序列操作
线性推,开数组太麻烦,可以用指针 代码: #include <iostream> #include <cstdio> #include <queue> using ...
- Go位运算
目录 &(AND) |(OR) ^(XOR) &^(AND NOT) << 和 >> & 位运算 AND | 位运算 OR ^ 位运算 XOR & ...