精华内容
下载资源
问答
  • Prometheus动态配置目标

    千次阅读 2018-04-24 12:09:09
    Prometheus动态配置目标 (金庆的专栏 2018.4) 最简单的配置是静态目标: scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090', 'localhost:9100'] labels: group:.....

    Prometheus动态配置目标

    (金庆的专栏 2018.4)

    最简单的配置是静态目标:

    scrape_configs:
      - job_name: 'prometheus'
    
        static_configs:
          - targets: ['localhost:9090', 'localhost:9100']
            labels:
              group: 'prometheus'

    更改此文件后,可以发送 SIGHUP 触发配置重新加载。

    Prometheus 提供了服务发现功能,可以从 consul, dns, kubernetes, file 等等多种来源发现新的目标。
    其中最简单的是从文件发现服务。

    例如 /root/prometheus/prometheus.yml 配置如下:

    global:
      scrape_interval: 15s
      evaluation_interval: 15s
    scrape_configs:
      - job_name: 'prometheus'
        static_configs:
          - targets: ['127.0.0.1:9090', '127.0.0.1:9100']
            labels:
              group: 'prometheus'
      - job_name: 'test'
        file_sd_configs:
          - files: ['/etc/prometheus/test_sd_config/*.yml']
            refresh_interval: 5s

    用 docker 启动 prometheus:

    docker run -d --net=host \
      -v /root/prometheus:/etc/prometheus \
      --name prometheus-server \
      prom/prometheus

    创建 /root/prometheus/test_sd_config/test.yml 如下

    - targets: [ "192.168.93.192:8080" ]
      labels:
        group: "my_test_group"

    5s内就会自动读取 test.yml 并添加新的目标。
    可用浏览器打开Prometheus 9090 端口,
    查看 Status 中的 Configuration, Targets, Service Discovery,
    可以看到新添加的目标。

    展开全文
  • kafka动态配置topic

    千次阅读 热门讨论 2019-01-11 14:18:43
     之前使用@org.springframework.kafka.annotation.KafkaListener这个注解的时候,是在yml文件中配置,然后使用@KafkaListener(topics = {"...昨天改了个需求,希望以后通过配置文件去动态配置生产者和消费者的...

     之前使用@org.springframework.kafka.annotation.KafkaListener这个注解的时候,是在yml文件中配置,然后使用@KafkaListener(topics = {"${kafka.topic.a2b.name}"}),这样去单独监听某一个topic,生产者也固定在代码里定义变量读取配置文件。昨天改了个需求,希望以后通过配置文件去动态配置生产者和消费者的topic(不知道个数和topic名字),而不需要改代码。

    一、踩坑

     刚开始的时候,由于考虑不充分(没有考虑到topic个数未知),想到@KafkaListener注解中的topics本身就是个字符串数组,于是想通过传入变量的形式。产生了以下两种方法:

    1.传入变量方法一

      使用@Value注解提取配置文件中相关配置,@KafkaListener中传入变量

        public static String[] topicArr;
        @Value("${kafka.bootstrap.servers}")
        public void setTopicArr(String[] value){
            String topicArr = value;
        }
        @KafkaListener(topics= topicArr)
    

    emmmm。。。结果可想而知,不行。

    2.传入变量方法二

     还是传入变量,不过这次写了个动态配置的代码

        注解里这么写
        @KafkaListener(topics = "${topicName1}","${topicName2}","${topicName3}")
        提前将yml文件里添加
        topics: topicName1,topicName2,topicName3
        然后加载进来
        @Value("${kafka.topics}")
        public void setTopics(String value){
            topics = value;
        }
        动态配置代码:
        @Configuration
        public class KafkaTopicConfiguration implements InitializingBean {
            @Autowired
            private KafkaConfig kafkaconfig;
            @Override
            public void afterPropertiesSet() throws Exception {
                String[] topicArr = kafkaconfig.split(",");
                int i = 1;
                for(String topic : topicArr){
                    String topicName = "topicName"+i;
                    System.setProperty(topicName, topic);
                }
            }
        }
    

    相比方法一,可行。但是未知topic数量呢。GG。

    3.不用注解

     百度找到几个老哥的动态获取并创建topic的方法

    https://www.cnblogs.com/gaoyawei/p/7723974.html
    https://www.cnblogs.com/huxi2b/p/7040617.html
    https://blog.csdn.net/qq_27232757/article/details/78970830
    

    写了几版,各种各样的问题,还是我太菜。就想再看看有没有别的简单点的解决办法,没有了再回来搞这个。

    4.正则匹配topic

     这期间又找到一个使用正则匹配topic的。直接贴链接

    @KafkaListener(topicPattern = "showcase.*")
    这里使用正则匹配topic,其中【*】之前得加上【.】才能匹配到。
    

    中间模仿写了一版使用正则匹配的,其实也可以糊弄实现需求,除了topic取名的时候一定得规范以外,还得考虑到如果不想用某个topic了又得想怎么去避免他。
    这种方法不太严谨,继续踩坑吧。

    二、问题解决

     用蹩脚的英语google了一下,嗯?好多老哥们也是用的以上差不多的方法。然而最后在某个老哥github的issues中看到了解决办法。老哥的需求跟我差不多,感谢大佬,贴上最终问题解决方案。

    1.kafka消费者监听配置

    还是注解的形式
    @KafkaListener(topics = "#{'${kafka.listener_topics}'.split(',')}")
    

    读取yml文件中kafka.listener_topics的参数,然后根据“,”去split,得到一个topics数组。
    这么做就可以根据配置文件动态的去监听topic。

    2.yml配置文件

    只列出topic相关部分(mqTypes是我用来判断使用哪个topic发送的)
        kafka:
          listener_topics: kafka-topic-a2b,kafka-topic-c2b
          consume:
            topic:
              - name: kafka-topic-a2b
                partitions: 12
                replication_factor: 2
              - name: kafka-topic-c2b
                partitions: 12
                replication_factor: 2
          product:
            topic:
              - name: kafka-topic-b2a
                partitions: 12
                replication_factor: 2
                mqTypes: type1
              - name: kafka-topic-b2c
                partitions: 12
                replication_factor: 2
                mqTypes: type1
    

    3.yml参数解析

    这里我将kafka的topic相关加载到bean中处理。
    创建KafkaConsumerBean和KafkaProducerBean分别用来存储yml中生产者和消费者的topic相关参数

    //KafkaConsumerBean
    @Component
    @ConfigurationProperties(prefix = "kafka.consume")
    public class KafkaConsumerBean {
        private List<Map<String,String>> topic;
        public void setTopic(List<Map<String, String>> topic) {
            this.topic = topic;
        }
        public List<Map<String, String>> getTopic() {
            return topic;
        }
    }
    
    //KafkaProducerBean
    @Component
    @ConfigurationProperties(prefix = "kafka.product")
    public class KafkaProducerBean {
        private List<Map<String,String>> topic;
        public void setTopic(List<Map<String, String>> topic) {
            this.topic = topic;
        }
    
        private Map<String,String> mqType2NameMap = new HashMap<String,String>();
        public List<Map<String, String>> getTopic() {
            return topic;
        }
    
        public String getTopic(String mqType){
            String name = mqType2NameMap.get(mqType);
            if(name != null){
                return name;
            }else{
                for(Map<String,String> topicProperty : topic){
                    if (topicProperty.get("mqTypes").indexOf(mqType) >= 0){
                        name = topicProperty.get("name");
                        mqType2NameMap.put(mqType,name);
                        return name;
                    }
                }
                return null;
            }
    
        }
    }
    
    

    4.创建topic

        List<Map<String,String>> producerTopicList = kafkaProducerBean.getTopic();
        for (Map<String,String> topicProperty : producerTopicList){
            KafkaClient.createTopic(topicProperty.get("name"),Integer.parseInt(topicProperty.get("partitions")),Integer.parseInt(topicProperty.get("replication_factor")));
        }
        List<Map<String,String>> consumerTopicList = kafkaConsumerBean.getTopic();
        for (Map<String,String> topicProperty : consumerTopicList){
            KafkaClient.createTopic(topicProperty.get("name"),Integer.parseInt(topicProperty.get("partitions")),Integer.parseInt(topicProperty.get("replication_factor")));
        }
    

    三、总结

     上面解决问题的方法关键在于

    @KafkaListener(topics = "#{'${kafka.listener_topics}'.split(',')}")
    

    @KafkaListener这个注解会去读取spring的yml配置文件中

    kafka:
          listener_topics: kafka-topic-a2b,kafka-topic-c2b
    

    这块listener_topics配置信息,然后通过’,'分割成topic数组,KafkaListener注解中的 topics 参数,本身就是个数组,如下

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package org.springframework.kafka.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Repeatable;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import org.springframework.messaging.handler.annotation.MessageMapping;
    
    @Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @MessageMapping
    @Documented
    @Repeatable(KafkaListeners.class)
    public @interface KafkaListener {
        String id() default "";
    
        String containerFactory() default "";
    
        String[] topics() default {};
    
        String topicPattern() default "";
    
        TopicPartition[] topicPartitions() default {};
    
        String group() default "";
    }
    

     结合我之前的kafka文章,应该是可以拼出一套成型的。

    展开全文
  • logback 动态配置 写在前面 在做java日志之前,强烈建议大家读一下这篇java日志的前世今生,对理清java日志框架很有帮助! 奉上地址: 一个著名的日志系统是怎么设计出来的 然后说一下,为啥要使用动态日志...

    logback 动态配置

    写在前面

    在做java日志之前,强烈建议大家读一下这篇java日志的前世今生,对理清java日志框架很有帮助!
    

    奉上地址: 一个著名的日志系统是怎么设计出来的

    然后说一下,为啥要使用动态日志配置。对于业务系统来讲,有些日志并非必须日志,但是对于调试是很重要的,当我们需要监控一个时段的日志,而过去这个时段,我们便不需要这些日志了,我们就可以通过命令,或者请求,动态开启日志输出,不想要日志时,动态关闭日志即可。
    对于试运行阶段的项目,我们需要收集比较详细的日志,当我们认为系统稳定了,没有问题了,就可以动态关闭日志。

    再者,有需求,我们的日志输出源发生改变,比如ELK变为了kafka ,我们在不停止服务的情况下,就可以动态操作,修改掉输出对象。

    简述java日志框架

    在这里插入图片描述

    spring boot 默认的日志框架为 slf4j+logback 。这里也强烈建议写日志时面向 slf4j(面向接口),几乎目前主流的日志框架(指java日志框架)都实现了slf4j,因此面向slf4j写日志,日志框架非常容易迁移。
    例如将log4j2 迁移为 logback ,只需要修改部分配置文件即可。

    logback的执行步骤 :

    在这里插入图片描述

    logback的主要对象

    对象 简述
    LoggerContext logback的核心对象,加载配置文件,存储loggerList……是log back的核心容器
    Logger 这个Logger为logback的logger 它实现了slf4j的Logger对象,除了实现了所有的logger方法外,我们动态配置日志输出源,也需要里面的 addAppender(),detachAppender()方法
    Appender 日志输出的最终实现, doAppend(E e)方法,最终实现了日志的输出,如果自定义appender 需要最终实现该接口

    注:以上对象并非logback全部核心对象,对于今天的日志动态输出,仅仅涉及到以上核心对象。

    实现logback 动态改变日志级别

    实现流程如下 :

    在这里插入图片描述

    下面附上测试源代码:

    package com.kgo.logger.logback;
    
    import ch.qos.logback.classic.Level;
    import ch.qos.logback.classic.LoggerContext;
    import com.kgo.logger.appender.DemoAppender;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class ContextTest {
        public static final String demoApName = "demo";
        public static void main(String[] args) {
            // 定义日志输出
            Logger logger = LoggerFactory.getLogger(ContextTest.class);
            logger.debug("=== 我输出了 === ");
            // 第一步:获取日志上下文
            LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
            // 第二步:获取日志对象 (日志是有继承关系的,关闭上层,下层如果没有特殊说明也会关闭)
            ch.qos.logback.classic.Logger logbackLogger = lc.getLogger("com.kgo.logger.logback");
            ch.qos.logback.classic.Logger rootLogger = lc.getLogger("root");
            // 第三步:修改日志级别
            logbackLogger.setLevel(Level.INFO);
            logger.debug("===== 我是 debug  =====");
            logger.info("===== 我是 info  =====");
            logger.error("===== 我是 ERROR  =====");
        }
    }
    
    

    输出结果如下:

    在这里插入图片描述

    可以看到 日志级别修改为INFO之后,日志 “===== 我是 debug =====” 没有输出
    logback 基本选择规则如下 :

    在这里插入图片描述

    动态添加删除 appender

    实现步骤和 修改日志级别基本一致,流程如下:

    在这里插入图片描述

    附上测试代码:

    package com.kgo.logger.logback;
    
    import ch.qos.logback.classic.LoggerContext;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class ChangeAppender {
        public static final String demoApName = "demo";
        public static void main(String[] args) {
            // 定义日志输出
            Logger logger = LoggerFactory.getLogger(ContextTest.class);
            logger.debug("=== 我输出了 === \n ");
            // 第一步:获取日志上下文
            LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();
            // 第二步:获取日志对象 (日志是有继承关系的,关闭上层,下层如果没有特殊说明也会关闭)
            ch.qos.logback.classic.Logger logbackLogger = lc.getLogger("com.kgo.logger.logback");
            ch.qos.logback.classic.Logger rootLogger = lc.getLogger("root");
            // 第三步:移除 appender
            logbackLogger.detachAppender("STDOUT");
            logger.debug("仅仅移除 com.kgo.logger.logback 的 appender");
            logger.debug("===== 我是 debug  =====");
            logger.info("===== 我是 info  =====");
            logger.error("===== 我是 ERROR  =====");
            rootLogger.detachAppender("STDOUT");
            logger.debug("\n 仅仅移除root 的 appender");
            logger.debug("===== 我是 debug  =====");
            logger.info("===== 我是 info  =====");
            logger.error("===== 我是 ERROR  =====");
    
        }
    }
    
    

    在执行这段代码的时候我在本地已经配置的 logback-test.xml ,其中 “STDOUT” 便是在该文件中做的配置,配置如下:

    <configuration>
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
    
        <root level="debug">
            <appender-ref ref="STDOUT" />
        </root>
     <logger name="com.kgo.logger.logback" level="DEBUG" >
            <appender-ref ref="STDOUT" />
        </logger>
    </configuration>
    

    输出结果如下:

    在这里插入图片描述

    • 在配置文件里配置了两个 Logger ,都输出给 STDOUT appender ,因此 “ === 我输出了 === ” 被打印了两次,
    • 当我移除掉了名字为 “ com.kgo.logger.logback” Logger的Appender , 下面的 日志仅输出了一次 (Root 的输出),
    • 当将root的appender 也移除掉后,日志不在输出(没有了输出对象)。

    就先分享到这里,接下里会写一篇 自定义appender ,并且动态添加append的 博客 ,本系列的博客目标 为 实现 日志的 全自动化
    包括:收集,上传,分类 ,自定义字段,实时更新,elk 等。

    如果感觉有用,点个赞再走吧,大佬

    ------------------------------------------------------- 这就是我的底线了 --------------------------------------------------------------

    展开全文
  • 使用nacos注册中心动态配置配置类无法实现实时更新问题解决方案 问题 使用nacos版本:1.3.1 问题说明及详解: 如果只是单一的在配置类上加入@Component和@RefreshScope注解只会在程序启动时回去读取一次配置文件,...

    使用nacos注册中心动态配置配置类无法实现实时更新

    问题


    使用nacos版本:1.3.1
    问题说明及详解:
    如果只是单一的在配置类上加入@Component和@RefreshScope注解只会在程序启动时回去读取一次配置文件,大多数网上demo在介绍nacos做配置中心时都是以Controller作为demo方便看见变化,但是当情况发生在配置类中的时候就不一样了,都了解无论是controller还会service都是交给spring去管理的每次去访问都会重新去读取配置文件,加上@Component或者@Configuration时只会当做一个配置类在项目启动时去访问一次,无论你在什么情况下去读取配置文件中的值都是固定的。

    解决方案

    上面提到了交给spring去管理才行,那把配置文件交给spring去管理就行了,完美解决
    在这里插入图片描述
    菜鸟出山,欢迎指点!

    展开全文
  • Nacos实现动态配置

    千次阅读 2019-07-30 18:24:13
    Nacos实现动态配置先说我遇到的坑然后去网上搜了大神们的博客配置成功之后springboot启动的结果应该是有这两条的 先说我遇到的坑 上面配置的是yaml文件,然后启动栏输出的是去找nacos-config.properties 然后悲剧...
  • SpringBoot动态配置加载

    千次阅读 2018-12-30 16:11:00
    SpringBoot动态配置加载 1、SpringBoot对配置文件集中化进行管理,方便进行管理,也可以使用HttpClient进行对远程的配置文件进行获取。 创建一个类实现EnvironmentPostProcessor 接口,然后可以对...
  • springboot整合Quartz实现动态配置定时任务

    万次阅读 多人点赞 2017-03-09 09:12:20
    在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置,下面就通过一个简单的示例,来实现这个功能。 一、新建一个springboot工程,并添加依赖 org.spring...
  • 当我们要同时启用多个项目而又要使用不同端口或者变换配置属性时,我们可以在配置文件中设置${变量名}的变量来获取启动时传入的参数,从而实现了动态配置参数,使启用项目更加灵活 例子 server: port: ${PORT:50101...
  •   配置中心(v2.7.0)在Dubbo中承担两个职责: 外部化配置。...  启用动态配置(以Zookeeper为例,可查看动态配置配置项详解): <dubbo:config-center address="zookeeper://127.0.0.1:21...
  • Dubbo-Dubbo 动态配置中心

    万次阅读 2019-07-14 15:50:43
    Dubbo 动态配置中心 一、参考文档 http://dubbo.apache.org/zh-cn/docs/user/configuration/config-center.html 三大中心指的:注册中心,元数据中心,配置中心。在 2.7 之前的版本,Dubbo 只配备了注册中心,主流...
  • Seata 动态配置订阅与降级实现原理

    千次阅读 2019-12-22 21:50:29
    Seata 的动态降级需要结合配置中心的动态配置订阅功能。动态配置订阅,即通过配置中心监听订阅,根据需要读取已更新的缓存值,ZK、Apollo、Nacos 等第三方配置中心都有现成的监听器可实现动态刷新配置;动态降级,即...
  • spring schedule 动态配置执行时间

    万次阅读 2019-01-23 09:46:49
    但是最近给银行做的一个小项目,需要本地化部署,所以我不想弄很多的服务,并且他们并没有要求修改以后即时生效,所以我直接采用了 spring schedule结合mysql动态配置执行时间。 之前我们用的schedule通过注解的...
  • 小弟目前在研究关于动态配置规则的需求,遇到一个问题:如果要实现让用户可以动态的自行添加规则的话,那么Fact对象里的属性是不是也要动态的增加?如何实现? 还请各位大神帮帮忙!
  • 动态配置的缓存方案

    千次阅读 2018-03-21 22:21:56
    假设有这样一个问题: 微信有10亿用户,不可能对所有用户的所有操作都打印log(最多只能打印错误log), 现在,微信内部领导经常反馈问题,没有log就不能查问题, 该怎么办?... 动态配置, 利用缓存 ...
  • nginx动态配置配置

    千次阅读 2019-01-04 16:07:11
    nginx中的conf文件配置测试 upstream backServer{ server 127.0.0.1:11111; upsync 192.168.212.134:8500/v1/kv/upstreams/itmayiedu upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong...
  • SpringBoot注解内容的动态配置

    千次阅读 2020-02-11 10:29:54
    大家都知道,注解只能配置常量,在一些构架的开发中,有时候我们需要给注解动态配置一些值,或者想从配置文件中读取配置。直接在注解上配置是无法实现的,但是我们可以在拿到注解的值之后,再对这些值进行另外的操作...
  • Spring Cloud Alibaba实战(一) - Nacos动态配置

    万次阅读 热门讨论 2019-05-13 17:33:59
    (一)Nacos动态配置(二)Nacos注册中心(三)Sentinel之限流(四)Sentinel之熔断(五)Gateway之路由、限流(六)Gateway之鉴权、日志(七)Gateway搭配Nacos实现动态路由(八)Dubbo + Nacos 正文 前两年的Spring微服务世界,...
  • iview表格颜色可动态配置

    千次阅读 2019-05-30 17:52:59
    由于新的功能需求,需要对表格颜色进行动态的配置,iview内部本身有对表格进行颜色设置,但是由于样式都需要提前写好,无法动态配置,所以自己在iview的基础上对dom树进行操作,但会一定程度上影响性能,这里仅展示...
  • spring data elasticsearch 动态配置 indexName,可使用如下方式使用配置文件配置: @Component @Getter public class ConfigBean { @Value("${index.name}") private String indexName; } 然后在Document类上...
  • 1 springboot之动态配置定时任务

    万次阅读 2018-01-16 17:49:32
    最近项目中有关于springboot中动态配置定时任务的需求,查阅各种资料,最终实现了可以动态的开关定时器,以及配置定时器的时间节点。 网上有很多关于springboot定时任务的介绍,之前项目中也用过quartz,和...
  • spring + druid 配置动态配置数据源以及多数据源切换功能实现 数据源连接池使用druid 其他的数据源基本原理相同 spring中配置默认数据源连接池如下: <!-- 数据源配置, 使用 BoneCP 数据库连接池 --> &...
  • zuul动态配置路由规则,从DB读取

    万次阅读 热门讨论 2017-09-11 15:34:58
    zuul作为一个网关,是用户请求的入口,担当鉴权、转发的重任,理应保持高可用性和具备动态配置的能力。我画了一个实际中可能使用的配置框架,如图。当用户发起请求后,首先通过并发能力强、能承担更多用户请求的负载...
  • nacos是阿里用于spring cloud体系下的一个突破吧,可以用作注册发现和配置中心,支持自动刷新配置,我个人更加喜欢他的自动刷新配置功能,比spring cloud 的config和bus的动态配置有更多用法。常见用法就是用于动态...
  • 场景是这样子的:后台管理界面对定时任务进行管理,可动态修改执行时间,然后保存入库,每次任务执行前从库里查询再动态配置触发器,以达到动态修改Cron参数的效果。好了,咱们一起来看看是怎么回事。 1....
  • Springboot 利用 Jedis代码动态配置Redis

    千次阅读 2018-04-17 13:09:05
    Springboot 利用 Jedis代码动态配置Redis 项目需求,甲方需求是处于安全的目的不想让properties里的部分配置信息体现在文件中,而且可能在之后需要通过页面修改对应的配置,所以出的解决方案就是部分配置信息存储在...
  • gradle动态配置appName 和icon

    千次阅读 2018-11-10 22:13:39
    公司项目需要在渠道包里动态配置app名字和icon 如果有相似需求的请往下看: 第一步在app下的gradle的productFlavors的各个渠道比如 developAPP {  applicationId rootProject.applicationId  ...
  • 实现XML的简单动态配置

    千次阅读 2014-09-28 14:53:06
    实现XML的简单动态配置

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 66,718
精华内容 26,687
关键字:

动态配置