zoukankan      html  css  js  c++  java
  • 分布式配置中心之思考

    一、为什么需要分布式配置中心?它能解决什么问题?

    从解决问题层面进行切入,它能解决配置混乱难管理的问题。

    过去传统式开发,一个SSM框架开发的单体应用通常会有如下配置:

    • spring-mybatis.xml;
    • spring-mvc.xml;
    • mybatis.xml;
    • web.xml;
    • jdbc.properties;
    • log4j.properties;
    • spring-redis.xml;
    • spring-mongodb.xml;
    • mapper目录下有若干xml。

    当这个单体应用因为某种原因(新来的架构师按照微服务的方式进行重构以及拆分(逐步开展)、项目经理为了新的需求-新建项目(一般老项目不能轻易动,保险起见)等),这个时候就涉及到一个问题,新的项目目录结构与原来的可能一致,但配置文件基本上相同,这时将老项目的配置文件复制到新的项目,除非新的项目采取新的技术,否则仍然按照之前老项目的规范来,这个场景相信不少的朋友都遇到过。假如是两三个项目还好,如果这时要拆分为七八个甚至二十个,那么这样的工作将非常繁琐,同时维护上会很困难(稍不留神漏掉一个,最后一上线发现数据不对,原来连的还是开发环境的数据库,这时只得重新部署)。由此看来,分布式配置中心的主要作用在于对配置文件的统一管理,减少重复性工作,提高整体研发团队的效率(开发、测试、运维等)
    除此外统一管理体现的好处有安全性(可采用某种加密的方式进行关键配置数据加密,同时过去配置在代码里,如果代码被人反编译破解就可能导致密码之类的东西被泄漏等)、时效性(从两个方面来说,第一个方面是修改后重启才能生效,第二个是当时修改即刻生效)。
    归纳地概括,因为多个项目场景中面临配置文件过于分散、修改追根溯源困难、环境容易搞混、代码与配置文件耦合等问题,我们需要分布式配置中心,而分布式配置中心恰好就能解决这样的问题。

    二、分布式配置中心在实际中会面临哪些问题?

    以Nacos为例,目前我使用Nacos作为分布式服务注册中心,而Nacos恰好集成了分布式配置管理。Nacos中的配置管理,就是管理配置文件的,而这些配置文件内容存储在MySQL。如果MySQL遭遇一些意外如磁盘空间满了、黑客攻击、连接过多、低效率的SQL导致内存消耗极大等,那么Nacos也会处于挂掉或死机状态(停止服务)等,这样也会直接导致一些微服务处理故障,虽然不在一个服务器上或者是连接的业务数据库不一样,但共同点都是读取Nacos统一管理下的配置。针对这样的问题一般从三个方面入手:

    • 第一个方面,运维从监控策略(提前预警,做好应对)、服务器安全策略(防止攻击)、服务可用性策略(包含集群)等;
    • 第二个方面,开发从写代码入手,遵守规范(代码规范),逻辑严谨(程序逻辑考虑较为全面),合理调用API(明白每个API的优缺点,进行合理组装,避免性能瓶颈)等;
    • 第三个方面,测试从性能测试入手,模拟多人使用或非法攻击的场景等。

    上面列举的仅仅是配置中心在实际落中面临的重大问题之一,除此之外还有就是如何规范管理配置(因为并不是所有的配置都需要放到配置中心进行统一管理,如果所有的微服务配置均放到分布式配置中心来管理,那么也会面临一个大问题就是如何管理好这些配置,一旦管理不好,就可能变成了体力劳动,违背了分布式配置中心的初衷)。

    在提到规范管理之前,回到一个问题上,这个问题是究竟什么样的配置文件应该放在分布式配置中心?
    我的回答是通用性配置,以我博客为例,application-dev.yml配置内容(我将jwt和鉴权、ribbon、hystrix等通用性配置放入了Nacos的配置管理):

    # JWT配置
    jwt:
      # 密匙KEY
      secret: JWTSecret
      # HeaderKEY
      tokenHeader: Authorization
      # Token前缀字符
      tokenPrefix: challenger-
      # 过期时间 单位秒 1天后过期=86400 7天后过期=604800
      expiration: 86400
      # 配置不需要认证的接口
      antMatchers: /login/**,/user/register,/api-doc/**,/login/**,/favicon.ico,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs/**,/druid/**,/cnblogs/**,/user/**
      # 有效时间
      validTime: 7
    ribbon:
      okhttp:
        enabled: true #
      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 默认为;轮询,这里改为随机
      ConnectTimeout: 5000 # 连接超时时间(ms)
      ReadTimeout: 5000 # 通信超时时间(ms)
    hystrix:
      enabled: true
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 6000 #

    那么在规范性方面该如何落地?这与公司的实际情况有关,每家公司的业务、研发团队的综合素质等均存在差异性,而在规范性上就需要找到适合该公司研发团队的。但适合很难,都是从坑坑洼洼中摸索出来的。

    以我个人经验来看(结合近来的坑),从以下入手:

    • 通用性配置管理,公共通用性配置文件和业务通用性配置文件,放入分布式配置中心进行管理;
    • 分类配置管理,不同环境(dev、test、prod)放入不同的分布式配置中心进行管理;
    • 差异性配置管理,差异性配置文件放入具体的微服务项目,衡量差异性的标准是该配置只在此处用到,其它微服务均不涉及。

    三、分布式配置中心的技术选型

    关于这一方面,我特别查阅了相关资料,有博友将分布式配置中心的技术选型归纳为如下:

    • Disconf;
    • Spring Cloud Config;
    • Apollo;
    • Nacos。

    目前用的比较多的,一个是SpringCloud Config,相当于是SpringCloud原生自带,不过该分布式配置中心的存储主要为SVN和Git,也有部分人采用本地存储的方式(存储在某个服务器上),另一个是Apollo,然后就是Nacos,至于Disconf早就不维护了,相当于落伍,GitHub如图:

    对于早就不维护的,一般技术选型不考虑,关于技术选型需要考虑哪些东西,感兴趣的朋友可以阅读我的这篇文章:
    从单体架构到分布式微服务架构的思考

    四、SpringCloud Alibaba之分布式配置中心整合(以Nacos作为分布式配置中心)

    1.添加Maven依赖

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    
    <!-- SpringCloud Ailibaba Nacos Config -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>

    2.bootstrap.yml配置

    cloud:
       nacos:
         discovery:
           # 服务注册地址
           server-addr: 127.0.0.1:8848
         config:
           # 配置中心地址
           server-addr: 127.0.0.1:8848
           # 配置文件格式
           file-extension: yml
           # 共享配置
           shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

    3.例子

    (1)通过nacos新建一个配置文件

    (2)bootstrap.yml配置

    cloud:
       nacos:
         discovery:
           # 服务注册地址
           server-addr: 127.0.0.1:8848
         config:
           # 配置中心地址
           server-addr: 127.0.0.1:8848
           # 配置文件格式
           file-extension: yml
           # 共享配置
           shared-dataids: blog.properties,application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

    (3)代码读取

    a.Environment读取
    @Autowired
    private Environment env
    
    env.getProperty("api_url")
    b.注解读取
    @Value("${api_url}")
    private String apiUrl;

    (4)如果想实时更新的话需要配置两个地方(两者缺一不可,nacos版本为1.3.1)

    a.配置文件
    cloud:
      nacos:
        discovery:
          # 服务注册地址
          server-addr: 127.0.0.1:8848
        config:
          # 配置中心地址
          server-addr: 127.0.0.1:8848
          # 配置文件格式
          file-extension: yml
          # 共享配置
          shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension},blog.properties
          refresh-enabled: true
          refreshable-dataids: blog.properties
    b.注解
    @RefreshScope
  • 相关阅读:
    【scala语言入门】二、匿名函数
    【scala语言入门】 一、apply与unapply
    关于timeOut超时后是否会回滚的思考
    [算法]-插入排序
    【oenCV系列】 写视频
    【Opencv系列】
    Factory Method模式精解(C++版本)
    Template Method模式精解(C++版本)
    Adapter模式精解(C++版本)
    迭代器模式精解(C++版本)
  • 原文地址:https://www.cnblogs.com/youcong/p/14800146.html
Copyright © 2011-2022 走看看