分布式配置中心之思考


一、為什么需要分布式配置中心?它能解決什么問題?

從解決問題層面進行切入,它能解決配置混亂難管理的問題。

過去傳統式開發,一個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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM