Spring Cloud Alibaba發佈第二個版本,Spring 發來賀電

Spring Cloud Alibaba發佈第二個版本,Spring 發來賀電

還是熟悉的面孔,還是熟悉的味道,不同的是,這次的配方升級了。

今年10月底,Spring Cloud聯合創始人Spencer Gibb在Spring官網的博客頁面宣佈:阿里巴巴開源 Spring Cloud Alibaba,併發布了首個預覽版本。隨後,Spring Cloud 官方Twitter也發佈了此消息。-

傳送門

Spring Cloud Alibaba發佈第二個版本,Spring 發來賀電

時隔 51天,Spencer Gibb再次在Spring官網的博客頁面宣佈:Spring Cloud Alibaba發佈了其開源後的第二個版本0.2.1,隨後,Spring Cloud 官方Twitter也轉發了此消息。聖誕節的前一週,Josh Long向他的老朋友許曉斌發來賀電:

聽聞阿里巴巴官方宣佈使用Spring Cloud,我開心的一晚上沒睡著,下週三我會在Spring Tips小視頻裡介紹Spring Cloud Alibaba。

聖誕快樂,老哥!

愛你

新版本概要

  • 增加了兩個新的模塊, spring-cloud-alibaba-schedulerx 和 spring-cloud-stream-binder-rocketmq 。
  • 在 spring-cloud-alibaba-nacos 和 spring-cloud-alibaba-sentinel 中增加了一些新的 feature 。
  • 修復了之前版本的一些 bug 。

注意: 版本 0.2.1.RELEASE 對應的是 Spring Cloud Finchley 的版本。這次發佈也包含了一個適配 Spring Cloud Edgware 的版本 0.1.1.RELEASE,版本 0.1.1.RELEASE 也包含了 0.2.1.RELEASE 中新增的組件和特性。

Spring Cloud Alibaba RocketMQ

  • 適配了 spring cloud stream 對於 message 抽象的 API。
  • 支持事務消息。
  • Consumer 端支持以 tags、SQL表達式過濾消息。支持順序、併發以及廣播消費模式。

Spring Cloud Alibaba SchedulerX

  • 提供了秒級、精準、高可靠、高可用的定時任務調度服務。
  • 提供了豐富的任務執行模型,包括單機執行,廣播執行,以及子任務的分佈式執行。

Spring Cloud Alibaba Nacos Config

  • 將Nacos Client 的版本升級到 0.6.2 版本。
  • 支持從多個 dataid 和 groupid 中獲取和監聽配置,並支持優先級指定。
  • 優化了 動態監聽的邏輯,只有配置了動態刷新的配置項才會實時刷新。

Spring Cloud Alibaba Nacos Discovery

  • 將Nacos Client 的版本升級到 0.6.2 版本。
  • 支持在 Nacos Console 端將服務實例設置成不可用狀態,服務發現會自動過濾此節點。
  • 支持服務發現在初始化時不使用本地緩存。

Spring Cloud Alibaba Sentinel

  • 支持 Feign,兼容了 @FeignClient 所有的屬性,包括 fallback、fallbackFactory。
  • 支持 熱點參數限流和集群限流。
  • 重構了 ReadableDataSource 的設計,提供了更友好的配置 Sentinel 規則持久化的方式。
  • 優化了 Sentinel 對於 RestTemplate 的降級後的處理。
  • 調整並添加了一些 Sentinel 配置信息對應的屬性,如日誌目錄,日誌文件名等。

新版本背後的思考

Spring Cloud Alibaba Nacos Discovery

Nacos Discovery 在這個版本最大的更新就是支持在初始化的時候不使用本地文件緩存,目前初始化的時候已經默認不使用本地文件緩存。

為什麼要有緩存?首先我們來了解一下本地緩存的概念,為什麼需要這個本地緩存?

我們都知道,服務註冊與發現應該只是服務調用中的輔助性的一個環節,而不是一個關鍵的環節。一個良好的服務註冊與發現的設計,需要保證以下兩點。

  • 服務註冊與發現只是旁路,不應該參與具體的調用過程。
  • 在服務的運行過程中,即使服務註冊中心偶然發生異常宕機後,也儘量不影響正常的業務調用。

要實現以上兩點,緩存就不可或缺,而為了適應不同的場景,緩存又可以分成內存緩存和本地文件緩存,他們的概念和適用場景如下。

內存中的緩存

將服務提供者列表維護在內存中,每次調用時直接從內存中的列表獲取節點即可。內存緩存通過定時任務更新,或者在收到服務註冊中心的推送之後再更新。確保了即使在服務註冊中心宕機的情況下,也能保證服務仍能正常調用。

本地文件緩存

將上述提到的內存中的緩存,保留在本地的某個文件中,這樣在調用服務註冊中心失敗的時候,可以從本機的文件緩存中獲取服務提供者列表。這樣就保證了在服務註冊中心宕機的情況下,應用在重啟後也能找到服務提供者。

為什麼要關閉

有了以上背景知識後,讀者可能會有疑問,既然緩存這麼好,你們為什麼默認要把它置為默認關閉呢?

我們在發佈出第一個版本之後,很多用戶反饋,為什麼我服務下線之後還是有節點,仍舊可以被查詢到呢?這樣導致我這個監控數據完全不準,你們這個有 bug,完全不對。其實這是阿里巴巴在多年業務積累的經驗,對於服務發現來說,一個即使是已經過時的節點,也比沒有任何數據好。而且還有可能其實這個服務只是和服務註冊中心失去了心跳,但是應用本身是正常的。

當然,這也暴露了我們設計中存在的一些問題,沒有把服務發現本身,以及緩存的分層給做好,兩者糅合在一塊。所以在這一次的版本更新中我們還是選擇適配開源標準,默認關閉了本地文件緩存,留了一個開關給用戶自由選擇。

Spring Cloud Alibaba Nacos Config

Nacos Config 在這個版本中有兩個大的特性,支持了“共享配置”,修正了動態刷新的語義和行為。

共享配置的實現

在第一個版本還沒發佈到時候,社區裡對配置管理中心的討論就沒停止過,其中聽到最多的反饋應該就是支持多個應用共享一個配置。我們也通過 github issue 的方式,徵集了很多意見,詳情見 #12 , #141。

後來我們將這個模型抽象了一下,認清這些需求本質是一個應用可以從多個 DataID 和 GroupID 組合中獲取配置,並且這些配置還可以單獨指定優先級和是否動態刷新。

最後我們推薦了這種使用方式,既保證了使用場景的靈活性,又保證了業務語義的明確性。更多詳情可以參考 WIKI。

 # config external configuration
# 1、Data Id 在默認的組 DEFAULT_GROUP,不支持配置的動態刷新
spring.cloud.nacos.config.ext-config[0].data-id=ext-config-common01.properties
# 2、Data Id 不在默認的組,不支持動態刷新
spring.cloud.nacos.config.ext-config[1].data-id=ext-config-common02.properties
spring.cloud.nacos.config.ext-config[1].group=GLOBAL_GROUP

# 3、Data Id 既不在默認的組,也支持動態刷新
spring.cloud.nacos.config.ext-config[2].data-id=ext-config-common03.properties
spring.cloud.nacos.config.ext-config[2].group=REFRESH_GROUP
spring.cloud.nacos.config.ext-config[2].refresh=true
#優先級關係: spring.cloud.nacos.config.ext-config[n].data-id 其中 n 的值越大,優先級越高。

注意 data-id 的值必須帶文件擴展名,文件擴展名支持 properties、yaml 和 yml。通過這種自定義擴展的配置項,既可以支持一個應用從多個配置項中獲取數據,也解決多個應用間配置共享的問題。

頭腦風暴,@fudali 同學還提出了更加靈活的一種方式 #161,就是可以通過一個配置項來配置所有的 DataID 的信息,然後可以通過修改這個配置項,可以修改整體配置項的邏輯。

這是一個非常好的想法,只不過這一期中我們沒有實現,原因是這種方式太靈活了。我們認為配置管理其實是一件很嚴肅的事情,太靈活導致生產中變更比較不可控。

雖然目前的邏輯也可以支持這種用法,但是我們並沒有把這種模式當做推薦模式,後續如果社區有更多的反饋認為這是一個強烈的需求,歡迎提 PR。

動態刷新的修正

簡單好用、實時可監控的動態刷新也許是 Nacos Config 相對於其他開源中間件相比最核心的優勢了,不同於 Spring Cloud Config Server 必須使用 Spring Cloud Bus 才能實現動態刷新,Nacos Config 無需依賴其他任何中間件就可以實現實時動態刷新,而且推送成功與否和刷新歷史還支持實時查詢。

但是我們發現在第一個版本中的實現發現兩個問題:

  • 動態刷新的實現方式不對:不應該直接調用 Context.refresh() 方法,而是應該 publish 一個 RefreshEvent。
  • 是否動態刷新的語義有誤:對於那些被標記為不動態刷新的配置項來說,只是修改他們的時候不會觸發動態刷新。但是當其他支持動態刷新的配置項觸發了動態刷新時,應用的 Context 仍舊會去獲取那些被標記為不動態刷新的配置項的內容,也就意味著這些配置項有可能被連帶刷新了。

在這個版本中,我們修復了這兩個問題。

首先,動態刷新不再是直接去調用 ContextRefresher.refresh() 方法,而是 publish 了一個 RefreshEvent,讓 spring-cloud-commons 裡的 RefreshEventListener 去觸發這個 ContextRefresher.refresh() 方法。

其次,我們修正了動態刷新的語義後,這一次是真正做到了,只有 refresh 屬性為 true 的配置項,才會在運行的過程中變更為新的值,refresh 屬性為 false 的配置項再也不用擔心應用在運行的過程中發生莫名其妙的變更了。

更深入一點,在上個月 SpringOne Tour 中,我們和 Spring Cloud 的創始人 Spencer 聊到 Spring Cloud 的 Context.refresh() 成本太高,會刷新整個 Spring Context。他反覆強調了兩次 Context.refresh() 只對 @RefreshScope 和 @ConfigurationProperties 有效,成本一點也不高。

之前我們接收到很多社區的反饋都是 Nacos Config 動態刷新支不支持 xxxx,支不支持 xxxx。之前我們都是回答只支持 @RefreshScope 和 @ConfigurationProperties ,如果他內置沒有支持,那就得自己加上相應的註解。

今天我們可以很愉快地回覆,他監聽了 RefreshEvent 也能直接支持。而且如果添加 @RefreshScope 和 @ConfigurationProperties 都不滿足你的需求時,可以通過實現自己的 RefreshEventListener 更多高級的玩法。

Spring Cloud Alibaba Sentinel

Sentinel 在這個版本中有三個大的特性:全面支持 FeignClient ,完善了 RestTemplate 的支持,添加了熱點限流、集群限流。

FeignClient 集成 Sentinel

其實在這之前,Sentinel 支持 FeignClient 已經設計了很久了,之前我們的想法做一個兼容性較強的方案,支持 Sentinel 和 Hystrix 在 FeignClient 中同時使用,儘量做到對原有應用的侵入性做到最小。

這個方案我們也思考調研了很久,但是實現難度確實比較大,需要修改 FeignClient 的代碼才能實現兩者共存。正好前段時間在 Spring Cloud 屆最大的新聞就是 Hystrix 宣佈不在維護了,於是我們就換了一個思路,直接使用 Sentinel 替代 Hystrix,不再去追求支持兩者共存。

我們實現了自己的 Feign.Builder,在構建的 FeignClient 執行調用的過程中,通過 SentinelInvocationHandler 完成 Sentinel 的流量統計和保護的動作。如果想使用 Sentinel 為 FeignClient 限流降級,首先需要引入 sentinel-starter 的依賴,然後打開 Sentinel 限流降級的開關 feign.sentinel.enabled=true ,就完成了 Sentinel 的接入。如果需要使用更加定製化的功能,則需要在 @FeignClient 添加 fallback 和 configuration 這些屬性的配置。

注意 @FeignClient 註解中的所有屬性,Sentinel 都做了兼容。

RestTemplate 集成 Sentinel

Spring Cloud Alibaba Sentinel 支持對 RestTemplate 的服務調用使用 Sentinel 進行保護,補全了 Hystrix 這一塊的空白。接入的方式也不復雜,在構造 RestTemplate bean 的時候需要加上 @SentinelRestTemplate 註解,然後在控制檯配置相應的規則即可。

在觸發了限流降級時,默認的處理方式是返回 RestTemplate request block by sentinel 信息。

  • 如果想自定義被限流之後的處理方式,還可以添加 blockHandlerClass,blockHandler 分別定製被限流後的處理類以及對於的處理方法。
  • 如果想自定義被降級之後的處理方式,還可以添加 fallback,fallbackClass 分別定製被降級後的處理類以及對於的處理方法。

RestTemplate 的限流降級 ?Sentinel 也承包了!

熱點參數限流和集群限流

首先解釋一下什麼是熱點參數限流和集群限流。

熱點參數限流會統計傳入參數中的熱點參數,並根據配置的限流閾值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。

集群流控主要解決的問題是:當我們需要控制整個集群流量總量,但是單機流量可能會不均勻,如果是單機維度去限制的話會無法精確地限制總體流量,因此需要引入集群維度的流量控制。

Sentinel v1.4.0 的 新功能 ,也能第一時間愉快地在 Spring Cloud Alibaba 上使用了。

新組件

Spring Cloud Alibaba RocketMQ

Spring Cloud Stream 是一個用於構建基於消息的微服務應用框架,它基於 SpringBoot 來創建具有生產級別的單機 Spring 應用,並且使用 Spring Integration 與 Broker 進行連接。它提供了消息中間件的統一抽象,推出了 publish-subscribe、consumer groups、partition 這些統一的概念。

RocketMQ 是一款開源的分佈式消息系統,基於高可用分佈式集群技術,提供低延時的、高可靠的消息發佈與訂閱服務。具有以下特點:能夠保證嚴格的消息順序、提供豐富的消息拉取模式、高效的訂閱者水平擴展能力、實時的消息訂閱機制、億級消息堆積能力。

在這次的 Spring Cloud Stream Binder RocketMQ 的實現中,我們適配了 Spring Cloud Stream 對於 message 抽象的 API,支持了 RocketMQ 的事務消息。消息訂閱時支持以 tags、SQL 表達式過濾消息,同時還支持順序、併發、延遲以及廣播消費模式。

Spring Cloud Alibaba SchedulerX

SchedulerX 是阿里中間件團隊開發的一款分佈式任務調度產品,提供秒級、精準、高可靠、高可用的定時(基於 Cron 表達式)任務調度服務,同時提供分佈式的任務執行模型,如網格任務,網格任務支持海量子任務均勻分配到所有 Worker(schedulerx-client)上執行。

簡單易用的輕量分佈式任務調度

您不需要關心調度邏輯,只需要在在 JobProcessor 接口的實現中添加業務邏輯即可,然後在自主運維控制檯配置上一個 Job 即可完成使用。

高可用的分佈式任務

不管是 SchedulerX 服務端還是客戶端都是分佈式架構設計,任務可以在多臺客戶端機器裡的任何一臺機器執行,如果客戶端出現宕機的情況,服務端會自動選擇正常運行的客戶端去執行 Job,每個 Job 在服務端的不同機器均有備份,SchedulerX 服務端任意宕掉部分機器仍能保證 Job 正常調度。

友好的用戶界面

SchedulerX 提供了非常友好的頁面方便您創建、刪除或修改 Job,提供了立即觸發執行一次的功能,方便您測試以及關鍵時刻手動立即執行一次,還提供了歷史執行記錄查詢的功能,您可以看到任何一個 Job 過去 100 次的歷史執行記錄。

功能強大

提供了秒級、精準的定時任務調度服務,且提供了豐富的任務執行模型,包括單機執行,廣播執行,以及子任務的分佈式執行。

What's Next?

Spring Cloud Alibaba Cloud SLS 針對日誌類數據的一站式服務,在阿⾥巴巴集團經歷大量大數據場景錘鍊⽽成。您⽆需開發就能快捷地完成日誌數據採集、消費、投遞以及查詢分析等功能,提升運維、運營效率,建立 DT 時代海量日誌處理能力。

Spring Cloud Alibaba Dubbo Dubbo 是一款流行的開源 RPC 框架,我們會把 Dubbo 整合到 Spring Cloud Alibaba 中,讓大家在開發 Dubbo 時也能享受到 Spring Cloud 帶來的便利。

致謝

Spring Cloud Alibaba 從開源建設以來,受到了很多社區同學的關注。社區的每一個 issue ,每一個 PR,都是對整個項目的幫助,都在為建設更好用的 Spring Cloud 添磚加瓦。

我們真心地感謝為這個項目提出過 Issue 和 PR 的同學,特別是這些 contributor:

HaojunRen、xiejiashuai、mengxiangrui007

我們希望有更多社區的同學加入進來,一起把項目做好。

還要特別感謝文檔團隊的傾芸,她幫忙將我們所有的 Reference Doc 翻譯了英文,為Spring Cloud Alibaba 的國際化進程鋪平了道路。

亦盞,阿里巴巴中間件高級開發工程師,長期關注微服務領域,主要負責 Spring Cloud Alibaba 項目的開發和社區維護。

Spring Cloud Alibaba的更多信息:

  • 阿里巴巴開源 Spring Cloud Alibaba,加碼微服務生態建設
  • Spring Cloud Alibaba原理和規範


分享到:


相關文章: