1. 程式人生 > >用Zookeeper作為Spring cloud的配置中心

用Zookeeper作為Spring cloud的配置中心

網上對於Spring cloud zookeeper config的資料不是太多,而且工作需要,特此記錄一下對這些天的學習成果,如有錯誤,請大家指正。

Spring Cloud 配置中心的主流實現方式

  1. Spring cloud config
  2. Spring cloud zookeeper config

以下是這兩者的簡介

Srping Cloud Config

Spring cloud config就是和git(svn)整合來實現配置中心。Spring cloud config分服務端、客戶端和git(svn)三部分,服務端負責將Git(SVN)中儲存的配置檔案釋出成REST介面,客戶端可以從服務端REST介面獲取配置(但客戶端並不能主動感知到配置的變化,從而主動去獲取新的配置,這需要每個客戶端通過POST方法觸發各自的/refresh)。其中通過git本身的屬性可以達到配置版本控制的目的。有快取形式,先把config下載到服務端本地再提供給客戶端,提高可靠性。

Srping Cloud Zookeeper Config

該專案通過自動配置並繫結到Spring環境,為Spring Boot應用程式提供Zookeeper整合。Zookeeper提供了一個分層名稱空間,允許客戶端儲存任意資料,如配置資料。Spring Cloud Zookeeper Config是Config Server和Client的替代方案。

兩者的比較
Spring Cloud Config 通過檔案系統,git/svn倉庫來管理配置檔案。包含客戶端、服務端和git/svn倉庫。通過git/svn特性可以達到版本控制

Spring Cloud Zookeeper Config 通過Zookeeper分級名稱空間來儲存配置項資料,另外Zookeeper可以實時監聽節點變化和通知機制。

Zookeeper 初探

Zookeeper簡介

Apache ZooKeeper是Apache軟體基金會的一個軟體專案,他為分散式應用提供高可用、高效能且一致的開源協調服務,它提供了一項基本服務:分散式鎖服務。由於ZooKeeper的開源特性,後來我們的開發者在分散式鎖的基礎上,摸索了出了其他的使用方法:配置維護、組服務、分散式訊息佇列、分散式通知/協調等。 ZooKeeper曾經是Hadoop的一個子專案,但現在是一個獨立的頂級專案。 ZooKeeper的架構通過冗餘服務實現高可用性。

Zookeeper角色

角色

結構圖

這裡寫圖片描述

選舉Leader演算法

Created with Raphaël 2.1.0開始傳送(myid,zxid)接收其他server投票投票是否結束結束其他伺服器能否勝任leader 傳送剛收到其他伺服器投票 再發送推薦自己的投票yesnoyesno

1、 當leader掛了後,其他非observer的機器變更狀態為looking,然後開始選舉流程
2、每個server都會發出一個投票資訊(myid,zxid)
3、接收來自各個伺服器的投票
4、處理投票–判斷zxid,大的zxid成為leader,如果zxid相同,就判斷myid,myid大的做leader
5、統計投票–半數伺服器達成一致意見後,投票結束
6、改變自身的狀態–leader為leading,其他伺服器為following

Zookeeper叢集數為單數

1、容錯

由於在增刪改操作中需要半數以上伺服器通過,來分析以下情況。

2臺伺服器,至少2臺正常執行才行(2的半數為1,半數以上最少為2),正常執行1臺伺服器都不允許掛掉

3臺伺服器,至少2臺正常執行才行(3的半數為1.5,半數以上最少為2),正常執行可以允許1臺伺服器掛掉

4臺伺服器,至少3臺正常執行才行(4的半數為2,半數以上最少為3),正常執行可以允許1臺伺服器掛掉

5臺伺服器,至少3臺正常執行才行(5的半數為2.5,半數以上最少為3),正常執行可以允許2臺伺服器掛掉

6臺伺服器,至少3臺正常執行才行(6的半數為3,半數以上最少為4),正常執行可以允許2臺伺服器掛掉

通過以上可以發現,3臺伺服器和4臺伺服器都最多允許1臺伺服器掛掉,5臺伺服器和6臺伺服器都最多允許2臺伺服器掛掉

但是明顯4臺伺服器成本高於3臺伺服器成本,6臺伺服器成本高於5伺服器成本。這是由於半數以上投票通過決定的。

2、防腦裂

一個zookeeper叢集中,可以有多個follower、observer伺服器,但是必需只能有一個leader伺服器。

如果leader伺服器掛掉了,剩下的伺服器叢集會通過半數以上投票選出一個新的leader伺服器。

叢集互不通訊情況:

一個叢集3臺伺服器,全部執行正常,但是其中1臺裂開了,和另外2臺無法通訊。3臺機器裡面2臺正常執行過半票可以選出一個leader。

一個叢集4臺伺服器,全部執行正常,但是其中2臺裂開了,和另外2臺無法通訊。4臺機器裡面2臺正常工作沒有過半票以上達到3,無法選出leader正常執行。

一個叢集5臺伺服器,全部執行正常,但是其中2臺裂開了,和另外3臺無法通訊。5臺機器裡面3臺正常執行過半票可以選出一個leader。
一個叢集6臺伺服器,全部執行正常,但是其中3臺裂開了,和另外3臺無法通訊。6臺機器裡面3臺正常工作沒有過半票以上達到4,無法選出leader正常執行。

通可以上分析可以看出,為什麼zookeeper叢集數量總是單出現,主要原因還是在於第2點,防腦裂,對於第1點,無非是正本控制,但是不影響叢集正常執行。但是出現第2種裂的情況,zookeeper叢集就無法正常運行了。

Spring Cloud Zookeeper Config

結構圖

這裡寫圖片描述

Spring Cloud Zookeeper Config 主要分為兩部分,client端和zookeeper,client端內嵌在spring-cloud-starter-zookeeper-config中,用的是netflix開源的CuratorFramework 來連線zookeeper獲取配置資料。在微服務啟動時候載入到environment中。

如何使用Spring Cloud Zookeeper Config

1、在客戶端(呼叫方)pom.xml中加入以下依賴

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-config</artifactId>
  </dependency>

2、在客戶端配置檔案bootstrap.yml / bootstrap.properties中加入zookeeper連線資訊

spring:
  application:
    name: testApp
  cloud:
    zookeeper:
      enabled: true  # true:開啟zookeeper外部化配置, false:讀取本地配置; 
      connect-string: IP1:port1,IP2:port2,IP3:port3
      config:
        root: /config/dev
        enabled: true
        watcher:
          enabled: false
屬性詳解:
connect-string:ZooKeeper的地址,如果是叢集,逗號分隔節點,格式:ip:port[,ip2:port2,.....]
root:指定zookeeper中,屬性的根目錄
spring.application.name: 定義你的專案的名稱,zk會在你指定的根目錄下尋找以這個專案名命名的目錄下的配置
watcher.enabled:  預設值是true, 監控配置變更後是否自動更新,需配合Spring Boot Actuators 使用

3、匯入配置檔案到Zookeeper

3.1、屬性命名規則(假設你在上面的root配置項設定為/config/dev):

/config/dev/{application-name},{profile}={key}={value}

服務名和dev (profile名)以逗號隔開,可以設定spring.cloud.zookeeper.config.profile-separator 來用其他符號隔開,譬如”-”等

3.2、配置檔案例子:
testApp-dev.txt

/config/dev/testApp,dev=server.port=8080

3.3、使用ZKUI來視覺化管理Zookeeper,登入ZKUI->import 選擇對應檔案匯入即可。
ZKUI安裝使用請自行百度。

4、客戶端獲取配置方式
我瞭解到有三種,可能還有其他的,大家可以自行百度
4.1、通過@Value註解

@Value("${db.url}")
String dbUrl;    

4.2、配置檔案(xml)中直接使用(用${propertyName})

<bean id="globalDbConfig" class="com.demo.connector.GlobalDbConfig">
    <property name="globalDbUsername" value="${global.username}"/>
    <property name="globalDbPassword" value="${global.password}"/>
</bean>

如何讓客戶端自動更新zookeeper變更的配置

1、客戶端pom.xml新增如下依賴

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2、在bootstrap.yml/bootstrap.properties 配置檔案中開啟watcher

spring.cloud.zookeeper.config.watcher.enabled=true

3、Bean上新增@RefreshScope註解

配置讀取簡介

配置資訊在服務啟動時載入到Spring Environment中。配置資訊預設存放在/config名稱空間下。
例如,應用名為“testApp”,環境“dev”,則下列配置源會被建立:
- config/testApp,dev
- config/testApp
- config/application,dev
- config/application
最為具體的配置源放在最上面,最泛化的放在最下面。config/application名稱空間下的屬性會被用於所有應用。config/testApp名稱空間下的屬性只會被“testApp”服務的例項使用,其他服務不能使用。

配置優先順序

遠端配置(zookeeper等) > 命令列引數配置 > application.yml> bootstrap.yml