[Spring Cloud Stream]1 流式微服務(wù)核心概念

概述

流式微服務(wù)主要用于實(shí)時(shí)處理源源不斷的數(shù)據(jù)流摊灭,相對(duì)于應(yīng)用微服務(wù)咆贬,它對(duì)開發(fā)人員提出了更多的技術(shù)要求。數(shù)據(jù)本身不像是純業(yè)務(wù)應(yīng)用斟或,相對(duì)來說它是抽象的素征、復(fù)雜的,且在傳輸萝挤,存儲(chǔ)御毅,分析等方面都比應(yīng)用微服務(wù)提出了更高的性能要求。

在設(shè)計(jì)上怜珍,Spring Cloud Stream 是一個(gè)用于構(gòu)建消息驅(qū)動(dòng)的微服務(wù)框架端蛆,它基于Spring Boot來創(chuàng)建對(duì) DevOps 提供良好支持的微服務(wù)應(yīng)用,通過 Spring Integration 集成工具為消息連接與傳播提供一個(gè)統(tǒng)一的酥泛、靈活的操作平臺(tái)今豆。該操作平臺(tái)是可配置的,比如配置 生產(chǎn)者/消費(fèi)者 柔袁、消費(fèi)者所屬消費(fèi)者組甚至是消息分區(qū)(需要消息中間件提供商本身的支持)呆躲。

Spring Cloud Stream的使用非常簡(jiǎn)單,在應(yīng)用的main啟動(dòng)類上加上 @EnableBinding 注解就可以連接消息中間件捶索,創(chuàng)建一個(gè)流式微服務(wù)插掂。通過在方法上添加 @StreamListener 注解就可以異步處理所接收到的消息。

快速開始

下面通過一個(gè)簡(jiǎn)單的 sink 應(yīng)用來演示Stream應(yīng)用的消息接收者用法腥例。

@SpringBootApplication
@EnableBinding(Sink.class)
public class VoteRecordingSinkApplication {

  public static void main(String[] args) {
    SpringApplication.run(VoteRecordingSinkApplication.class, args);
  }

  @StreamListener(Sink.INPUT)
  public void processVote(Vote vote) {
      votingService.recordVote(vote);
  }
}

@EnableBinding注解可以接收一個(gè)或多個(gè)輸入/輸出通道接口類作為參數(shù)(本示例中注解的參數(shù)只有 Sink 一個(gè)接口)辅甥,Spring Cloud Task默認(rèn)提供了 Source, Sink, 和 Processor接口來定義消息源,接收者和處理通道燎竖。通道支持之定義擴(kuò)展璃弄。

下面是 Sink 消息接收者通道的接口定義代碼。

public interface Sink {
  String INPUT = "input";

  @Input(Sink.INPUT)
  SubscribableChannel input();
}

@Input注解定義了輸入通道构回,通過這個(gè)注解可以接收進(jìn)入應(yīng)用的消息夏块。@Output注解定義了消息輸出通道法疏咐,通過這個(gè)注解可以定義應(yīng)用發(fā)布消息的通道。這兩個(gè)注解的參數(shù)為輸入/輸出消息通道的名稱脐供,如果沒有給注解指定參數(shù)凳鬓,默認(rèn)使用注解所標(biāo)注的方法的方法名作為通道名稱。

Spring Cloud Stream會(huì)通過動(dòng)態(tài)代理技術(shù)自動(dòng)為消息通道接口創(chuàng)建實(shí)現(xiàn)類患民。下面代碼是測(cè)試消息通道是否創(chuàng)建成功的方法。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = VoteRecordingSinkApplication.class)
@WebAppConfiguration
@DirtiesContext
public class StreamApplicationTests {

  @Autowired
  private Sink sink;

  @Test
  public void contextLoads() {
    assertNotNull(this.sink.input());
  }
}

核心概念

Spring Cloud Stream為簡(jiǎn)化消息驅(qū)動(dòng)微服務(wù)設(shè)計(jì)了許多抽象和基礎(chǔ)組件垦梆,其核心簡(jiǎn)要概述如下所示匹颤。

  • Spring Cloud 流式微服務(wù)模型
  • Binder 抽象消息中間件
  • 持續(xù)發(fā)布/訂閱支持
  • 支持消費(fèi)者組
  • 支持消息分區(qū)
  • 可拔插的 Binder API

1. 流式微服務(wù)模型

一個(gè) Spring Cloud Stream 應(yīng)用以消息中間件為核心,應(yīng)用通過Spring Cloud Stream注入的輸入/輸出通道 channels 與外部進(jìn)行通信托猩。channels 通過特定的Binder實(shí)現(xiàn)與外部消息中間件進(jìn)行通信印蓖。如圖1Spring Cloud Stream 應(yīng)用架構(gòu)示意圖所示。

Spring Cloud Stream 應(yīng)用架構(gòu)示意圖

2. 對(duì)消息中間件的抽象

Spring Cloud Stream提供了對(duì)Kafka和Rabbit MQ的抽象Binder來代表消息中間件京腥,其自身也提供了測(cè)試用的中間件 TestSupportBinder赦肃,可以直接向通道發(fā)送可靠的消息并進(jìn)行斷言測(cè)試,據(jù)此可以使用擴(kuò)展API編寫自己的Binder公浪。

Spring Cloud Stream使用通用的Spring Boot配置方式他宛,抽象的Binder為靈活配置如何連接消息中間件及發(fā)送消息提供了良好的支持。例如欠气,消息發(fā)布者可以在運(yùn)行時(shí)動(dòng)態(tài)的選擇通道要連接的目標(biāo)(kafka的topic或 RabbitMQ的exchanges)厅各,這些外部屬性配置可以通過Spring Boot給出(通過應(yīng)用參數(shù),環(huán)境變量预柒,application.yml或者application.properties配置文件)队塘。

Spring Cloud Stream會(huì)自動(dòng)發(fā)現(xiàn)并使用 classpath 中可用的 綁定器(binder),你可以通過在構(gòu)建項(xiàng)目時(shí)依賴不同的中間件來使同一份代碼支持多種消息中間件宜鸯。在復(fù)雜的應(yīng)用場(chǎng)景下憔古,你也可以在事先指定好每個(gè)通道綁定哪個(gè)Binder,直接打包多個(gè)binders淋袖。

3. 持續(xù)發(fā)布/訂閱支持

流式微服務(wù)應(yīng)用之間通過發(fā)布/訂閱模型通信鸿市,通過共享的話題topic來傳播數(shù)據(jù)。圖2展示了流式微服務(wù)集合的部署架構(gòu)圖适贸,直觀的說明了多個(gè)流式微服務(wù)之間的關(guān)系灸芳。


Spring Cloud Stream 發(fā)布訂閱模型示意圖

經(jīng)過HTTP接口的數(shù)據(jù)被轉(zhuǎn)發(fā)到raw-sensor-data目標(biāo)主題。計(jì)算平均時(shí)間窗口和持久化數(shù)據(jù)到HDFS兩個(gè)相互獨(dú)立的微服務(wù)共同消費(fèi)這個(gè)主題拜姿。

這個(gè)基于發(fā)布訂閱的通信模型可以減少生產(chǎn)者和消費(fèi)者的復(fù)雜性烙样,且能夠在不破壞現(xiàn)有數(shù)據(jù)流的情況下擴(kuò)充拓?fù)溥壿嫛1热缛锓剩憧梢栽谟?jì)算平均時(shí)間窗口服務(wù)后增加一個(gè)用于監(jiān)控和展示最高值的應(yīng)用谒获,甚至還可以在同一個(gè)數(shù)據(jù)流中添加一個(gè)計(jì)算平均錯(cuò)誤時(shí)間的應(yīng)用蛤肌。微服務(wù)間通過共享主題的方式進(jìn)行通信比點(diǎn)對(duì)點(diǎn)通信的方式大大降低了服務(wù)之間的耦合。

發(fā)布訂閱模型并非新概念批狱,Spring Cloud Stream只是通過一些額外的步驟裸准,使發(fā)布訂閱模型成為構(gòu)建微服務(wù)的一種極佳選擇。通過對(duì)本地消息中間提供支持赔硫,Spring Cloud Stream可以簡(jiǎn)潔的構(gòu)建跨平臺(tái)的發(fā)布訂閱模型炒俱。

4. 消費(fèi)者組

發(fā)布訂閱模型讓應(yīng)用間通過共享話題topic通信連接變得相當(dāng)容易,不過在為高可用部署多個(gè)應(yīng)用實(shí)例時(shí)爪膊,還需要防止應(yīng)用對(duì)該話題topic中的消息重復(fù)消費(fèi)权悟。多個(gè)應(yīng)用實(shí)例之間應(yīng)該是一個(gè)競(jìng)爭(zhēng)消費(fèi)的關(guān)系,一條消息應(yīng)該只能被一個(gè)消費(fèi)者消費(fèi)推盛。

Spring Cloud Stream通過消費(fèi)者組的概念來模擬上述需求峦阁。每個(gè)消費(fèi)者輸入通道綁定器可以使用spring.cloud.stream.bindings.<channelName>.group屬性來指定其所屬消費(fèi)者組。

4.1 持久的消費(fèi)者組

與Spring Cloud Stream的可獨(dú)立運(yùn)行服務(wù)模型一樣耘成,消費(fèi)者組的訂閱也是持久的榔昔。這句話的意思是說綁定器默認(rèn)自己自己所屬的消費(fèi)者組是持久存在的,只要該消費(fèi)者組中的某一個(gè)消費(fèi)者被創(chuàng)建瘪菌,除非所有的消費(fèi)者都被停止掉撒会,否則該組將不停的接收消息。

通常情況下控嗜,在已知消息目的地的時(shí)候茧彤,我們都會(huì)指定消費(fèi)者組,在升級(jí)到Spring Cloud Stream應(yīng)用時(shí)疆栏,你必須要為美俄輸入綁定器指定其所屬消費(fèi)者組曾掂,這樣的話就可以避免在部署多個(gè)應(yīng)用實(shí)例時(shí)重復(fù)消費(fèi)消息。

分區(qū)支持

Spring Cloud Stream為多個(gè)生產(chǎn)者實(shí)例的應(yīng)用提供消息分區(qū)的支持壁顶。在分區(qū)的情景下珠洗,物理上連接的媒體被視為多分區(qū)的結(jié)構(gòu),一個(gè)或多個(gè)生產(chǎn)者發(fā)送數(shù)據(jù)到多個(gè)消費(fèi)者若专,并保證某個(gè)具有某些特征的數(shù)據(jù)僅被某一個(gè)消費(fèi)者實(shí)例消費(fèi)许蓖。

Spring Cloud Stream提供公用的抽象,以統(tǒng)一的方式實(shí)現(xiàn)分區(qū)處理调衰。具體的分區(qū)策略可以由提供分區(qū)機(jī)制的消息中間件來實(shí)現(xiàn)膊爪。

Spring Cloud Stream 分區(qū)模型示意圖

分區(qū)是狀態(tài)處理中重要的概念。為確保相關(guān)數(shù)據(jù)能夠被一個(gè)服務(wù)一起處理嚎莉,無論在性能方面還是一致性方面米酬,分區(qū)的概念都是非常重要的。

關(guān)于

示例源碼

spring-cloud-stream-learning 的 stream-simple-listener 子項(xiàng)目

后記

Spring Cloud Stream提供的流式微服務(wù)是一個(gè)全新的概念趋箩,以消息驅(qū)動(dòng)為服務(wù)通信方式赃额,異步高性能的進(jìn)行數(shù)據(jù)流實(shí)時(shí)處理加派。不過其并未采用什么新技術(shù),而是以優(yōu)美的設(shè)計(jì)跳芳,來抽象各個(gè)消息中間件芍锦,屏蔽其內(nèi)部實(shí)現(xiàn)原理,使服務(wù)間的通信變得更為簡(jiǎn)單友好飞盆。

本文內(nèi)容主要是對(duì) Spring Cloud Stream Elmhurst 官方文檔的翻譯娄琉,不過作者水平有限,有不盡然的地方敬請(qǐng)指出吓歇。本項(xiàng)目和文檔中所用的內(nèi)容僅供學(xué)習(xí)和研究之用车胡,轉(zhuǎn)載或引用時(shí)請(qǐng)指明出處。如果你對(duì)文檔有疑問或問題照瘾,請(qǐng)?jiān)陧?xiàng)目中給我留言或發(fā)email到
weiwei02@vip.qq.com 我的github:
https://github.com/weiwei02/ 我相信技術(shù)能夠改變世界 。

鏈接

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丧慈,一起剝皮案震驚了整個(gè)濱河市析命,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逃默,老刑警劉巖鹃愤,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異完域,居然都是意外死亡软吐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門吟税,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凹耙,“玉大人,你說我怎么就攤上這事肠仪⌒けВ” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵异旧,是天一觀的道長(zhǎng)意述。 經(jīng)常有香客問我,道長(zhǎng)吮蛹,這世上最難降的妖魔是什么荤崇? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮潮针,結(jié)果婚禮上术荤,老公的妹妹穿的比我還像新娘。我一直安慰自己然低,他們只是感情好喜每,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布务唐。 她就那樣靜靜地躺著,像睡著了一般带兜。 火紅的嫁衣襯著肌膚如雪枫笛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天刚照,我揣著相機(jī)與錄音刑巧,去河邊找鬼。 笑死无畔,一個(gè)胖子當(dāng)著我的面吹牛啊楚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浑彰,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼恭理,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了郭变?” 一聲冷哼從身側(cè)響起颜价,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诉濒,沒想到半個(gè)月后周伦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡未荒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年专挪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片片排。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡寨腔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出率寡,到底是詐尸還是另有隱情脆侮,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布勇劣,位于F島的核電站靖避,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏比默。R本人自食惡果不足惜幻捏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望命咐。 院中可真熱鬧篡九,春花似錦、人聲如沸醋奠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至沛善,卻和暖如春航揉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背金刁。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工帅涂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尤蛮。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓媳友,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親产捞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子醇锚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容