首页 文章 精选 留言 我的

精选列表

搜索[批量删除],共10000篇文章
优秀的个人博客,低调大师

spring kafka之如何批量给topic加前缀

前言 最近业务开发部门给我们部门提了一个需求,因为他们开发环境和测试环境共用一套kafka,他们希望我们部门能帮他们实现自动给kafka的topic加上环境前缀,比如开发环境,则topic为dev_topic,测试环境,则topic为test_topic,他们kafka客户端是使用spring-kafka。一开始接到这个需求的时候,我心里是拒绝的,为啥开发环境和测试环境不分别部署一套kafka,还要那么麻烦。但老大都答应接这个需求了,作为小罗罗也只能接了 实现思路 1、生产者端 可以通过生产者拦截器,来给topic加前缀 2、实现步骤 a、编写一个生产者拦截器 @Slf4j public class KafkaProducerInterceptor implements ProducerInterceptor<String, MessageDTO> { /** * 运行在用户主线程中,在消息被序列化之前调用 * @param record * @return */ @Override public ProducerRecord<String, MessageDTO> onSend(ProducerRecord<String, MessageDTO> record) { log.info("原始topic:{}",record.topic()); return new ProducerRecord<String, MessageDTO>(TOPIC_KEY_PREFIX + record.topic(), record.partition(),record.timestamp(),record.key(), record.value()); } /** * 在消息被应答之前或者消息发送失败时调用,通常在producer回调逻辑触发之前,运行在produer的io线程中 * @param metadata * @param exception */ @Override public void onAcknowledgement(RecordMetadata metadata, Exception exception) { log.info("实际topic:{}",metadata.topic()); } /** * 清理工作 */ @Override public void close() { } /** * 初始化工作 * @param configs */ @Override public void configure(Map<String, ?> configs) { } b、配置拦截器 kafka: producer: # 生产者拦截器配置 properties: interceptor.classes: com.github.lybgeek.kafka.producer.interceptor.KafkaProducerInterceptor c、测试 2、消费者端 这个就稍微有点难搞了,因为业务开发部门他们是直接用@KafkaListener的注解,形如下 @KafkaListener(id = "msgId",topics = {Constant.TOPIC}) 像这种也没啥好的办法,就只能通过源码了,通过源码可以发现在如下地方 KafkaListenerAnnotationBeanPostProcessor#postProcessAfterInitialization 会把@KafkaListener的值赋值给消费者,如果对spring有了解的朋友,可能会知道postProcessAfterInitialization是spring后置处理器的方法,主要用来bean初始化后的一些操作,既然我们知道@KafkaListener会在bean初始化后再进行赋值,那我们就可以在bean初始化前,修改掉@KafkaListener的值。具体实现如下 @Component public class KafkaListenerFactoryBeanPostProcesser implements BeanFactoryPostProcessor { @SneakyThrows @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { List<String> packageNames = AutoConfigurationPackages.get(beanFactory); for (String packageName : packageNames) { Reflections reflections = new Reflections(new ConfigurationBuilder() .forPackages(packageName) // 指定路径URL .addScanners(new SubTypesScanner()) // 添加子类扫描工具 .addScanners(new FieldAnnotationsScanner()) // 添加 属性注解扫描工具 .addScanners(new MethodAnnotationsScanner() ) // 添加 方法注解扫描工具 .addScanners(new MethodParameterScanner() ) // 添加方法参数扫描工具 ); Set<Method> methodSet = reflections.getMethodsAnnotatedWith(KafkaListener.class); if(!CollectionUtils.isEmpty(methodSet)){ for (Method method : methodSet) { KafkaListener kafkaListener = method.getAnnotation(KafkaListener.class); changeTopics(kafkaListener); } } } } private void changeTopics(KafkaListener kafkaListener) throws Exception{ InvocationHandler invocationHandler = Proxy.getInvocationHandler(kafkaListener); Field memberValuesField = invocationHandler.getClass().getDeclaredField("memberValues"); memberValuesField.setAccessible(true); Map<String,Object> memberValues = (Map<String,Object>)memberValuesField.get(invocationHandler); String[] topics = (String[])memberValues.get("topics"); System.out.println("修改前topics:" + Lists.newArrayList(topics)); for (int i = 0; i < topics.length; i++) { topics[i] = Constant.TOPIC_KEY_PREFIX + topics[i]; } memberValues.put("topics", topics); System.out.println("修改后topics:" + Lists.newArrayList(kafkaListener.topics())); } } 测试 总结 虽然实现了动态修改topic,但我还是觉得topic不要随便改变,有条件的话,kafka还是得基于物理环境隔离,其次真的客观条件不允许,要动态变更topic,则需做好topic动态变更宣导以及相关wiki的编写,不然很容易掉坑 demo链接 https://github.com/lyb-geek/springboot-learning/tree/master/springboot-mq-idempotent-consume

优秀的个人博客,低调大师

按量付费转包年包月之批量操作篇

考虑以下场景:在购买 ECS 实例的时候,您可能没有确定实例需要使用多长时间,您可以在购买实例的时候付费类型选择按量计费,实例使用一段时间以后,您确定了实例的使用周期以后再将其转换为包年包月实例。您可以登录 ECS控制台 或者使用 ModifyInstanceChargeType 接口将按量实例转为包年包月实例。 ECS控制台 和 ModifyInstanceChargeType 接口每次最多支持 20 个按量实例同时转换,考虑到您需要转换的按量实例可能较多,本文在介绍通过 ECS控制台 和 ModifyInstanceChargeType 接口将按量实例转换为包年包月实例的同时,还将介绍如何快速地将某个 Region 下的按量实例全部转换为包年包月实例。 按量实例转包年包月实例(ECS控制台) 登录 ECS控制台,进入实例列表页,选

优秀的个人博客,低调大师

Python的pxssh实现ssh登录之批量“打杂”

一、简单概要 这是我在生产环境用的一个脚本,根据实际运维情况编写,说白了就是人比较懒,不想打杂。哈哈!不明白的同学可以@我哦!,感谢! 二、代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #!/usr/bin/envpython from pexpect import pxssh import os try : for i in range ( 64 , 65 ): #在这个位置定义起始和结束的数字用于IP的主机号 s = pxssh.pxssh() ipaddr = '192.168.1.%s' % i #生成一个完整的IP地址 os.environ[ 'ip' ] = str (ipaddr) #变量呼唤,python变量可以在shell里拿 print 'sshconnectionhost:%s' % ipaddr s.login(ipaddr, 'root' , '123456' ) #登录主机(ip,用户,密码) print 'loginok!' #提示登录ok而已,仅此而已 print 'Create(/etc/ceph/)directory...' #登录进去就得干活了,比如创建目录 s.sendline( 'mkdir-p/etc/ceph' ) print 'createok!' print 'Issuedbytheconfigurationfile...' os.system( 'sshpass-p123456scp/etc/ceph/*root@$ip:/etc/ceph' ) #这个文件是下发文件,这里跟pxssh没关系 print 'fileissuedok!' print 'Issuedbythescript...' s.sendline( 'mkdir-p/openstack' ) #这里也是在远程主机执行命令,其他的都类似 os.system( 'sshpass-p123456scp/root/osd.shroot@$ip:/openstack' ) os.system( 'sshpass-p123456scp/root/com.txtroot@$ip:/openstack' ) print 'scriptissuedok!' print 'Runthescript...' s.sendline( 'sh/openstack/osd.sh' ) print 'scriptrunok!' s.prompt() print 'host:%scompletes,exitthessh...' % ipaddr s.logout() print 'exitok!' except pxssh.ExceptionPxssh,e: print "pxsshfailedonlogin" print str (e) 本文转自 TtrToby 51CTO博客,原文链接:http://blog.51cto.com/freshair/1866032

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册