架構之美-軟件實現分析之道

      網友投稿 926 2025-04-01

      在一個系統中,模型和接口是相對穩定的部分。

      但同樣的模型和接口,若采用不同實現,穩定性、可擴展性和性能等諸多方面相差極大。只有熟悉實現,才有改代碼寫新需求的基礎。

      “看實現”的確是個大難題,因有無數細節怪在等你。所以,團隊的新人都需要幾個月試用期去熟悉代碼細節。

      你不可能記住項目所有細節,但這不妨礙你工作。但若你心中沒有一份關于項目實現的地圖,你就一定會迷失。

      新人一般用幾個月熟悉代碼,就是在通過代碼一點點展開地圖,但是,這不僅極其浪費時間,也很難形成整體認知。

      推薦你應該直接把地圖展開。怎么展開?

      要找到兩個關鍵點:軟件的結構和關鍵的技術。

      以Kafka為例,了解一個軟件設計三步走:“模型、接口、實現”。

      先看Kafka的模型和接口。

      MQ的模型與接口

      Kafka自我介紹是個分布式流平臺,這是它現在的發展方向,但更多人覺得它是個MQ。

      MQ是Kafka這個軟件的核心模型,而流平臺顯然是這個核心模型存在之后的擴展。所以,要先把焦點放在Kafka的核心模型——MQ。

      MQ(Messaging Queue)是一種進程間通信方式,發消息的一方(即生產者)將消息發給MQ,收消息的一方(即消費者)將隊列中的消息取出并處理。

      看模型,MQ是很簡單的,不就是生產者發消息,消費者消費消息,還有個topic,區分發給不同目標的消息。

      基本接口也很簡單:

      生產者發消息:

      消費者收消息:

      看完模型和接口,你會感覺MQ本身并不難。

      但MQ實現有很多,Kafka只是其中一種,為什么會有這么多不同MQ實現呢?因為每個MQ實現有所側重,有其適用場景。

      MQ還提供一定的消息存儲能力。當

      Pro發消息速度>Con處理消息速度

      1

      MQ可起到緩沖作用。所以MQ還能“削峰填谷”:在消息量特別大時,先把消息收下來,慢慢處理,以減小系統壓力。

      Kafka之所以突出于一大堆MQ實現,關鍵在于它針對消息寫入做優化,它的生產者寫入特快,即吞吐力特強。

      顯然,接口和模型不足以將Kafka與其他MQ實現區分。所以,必須開始了解它的實現。

      看軟件實現時的關鍵:

      架構之美-軟件實現分析之道

      軟件的結構

      關鍵的技術

      模型是個抽象概念,被抽象的對象可以是某個聚合實體(訂單中心中的訂單),也可以是某個流程或功能(Java內存模型中的主存與緩存同步的規則)。

      分層對模型來說是實現層面的東西,是一種水平方向的拆分,是一個實現上的規范;

      模型的細粒度拆分(父模型、子模型),應該是一種垂直維度的拆分,子模型的功能要高內聚,其復雜性不該發散到外部。

      軟件結構

      軟件結構也是軟件模型,只不過,它不是整體上的模型,而是展開實現細節之后的模型。模型是分層的。

      對每個軟件,當你從整體去了解它時,它是完整的一塊。但當你打開它的時候,就成了多模塊組合,這也是“分層”意義。上一層只要使用下一層提供給它的接口。

      所以,當打開一個層次,了解其實現時,先從大處著手。最好找到一張結構圖,準確了解它的結構。

      如果你能夠找到這樣一張圖,你還是很幸運的。因為在真實的項目中,你可能會碰到各種可能性:

      結構圖混亂:你找到一張圖,上面包含了各種內容。比如,有的是模塊設計,有的是具體實現,更有甚者,還包括了一些流程

      結構圖復雜:一個比較成熟的項目,圖上畫了太多的內容。確實,隨著項目的發展,軟件解決的問題越來越多,它必然包含了更多的模塊。但對于初次接觸這個項目的我們而言,它就過于復雜了

      無結構圖

      想辦法畫一張

      先了解模型和接口,因為它們永遠是你的主線。

      假設:現在你有了一張結構圖,你打算做什么?

      了解它的結構?是,但不夠。不僅要知道一個設計的結果,最好還要推斷出設計原因。

      所以,一種更好的做法:帶問題上路。

      假設自己就是這個軟件設計者,問問自己要怎么做。再去對比別人的設計,你就會發現,自己的想法和別人想法的相同或不同。

      讓你來設計MQ,你會怎么做?

      Kafka網上能搜到各種架構圖,看個 最簡單的架構圖,因為最貼近MQ基礎模型:

      你能看到什么?

      Kafka的生產者一端將消息發給Kafka集群

      消費者一端將消息取出來進行處理

      這樣的結構和你想的是不是一樣?

      進一步設計,會干啥?

      生產者端封裝出一個 SDK,負責消息的發送

      消費者端封裝出一個 SDK,負責消息的接收

      設計一個集群系統,作為生產者和消費者之間的連接

      可以問自己更多的問題:

      生產端如果出現網絡抖動,消息沒有成功發送,怎么重試?

      消費端處理完的消息,如何保證集群不重復發送?

      為什么要設計一個集群呢?要防止出現單點的故障,而一旦有了集群,就會牽扯到下一個問題,集群內的節點如何保證消息的同步呢?

      消息在集群里是怎么存儲的?

      生產端也好,消費端也罷,如果一個節點徹底掉線,集群該怎么處理呢?

      ……

      有了更多問題,你就會在代碼里更深入探索。你可根據需要,打開對應模塊,進一步了解實現:

      比如消息重發問題,可看生產端是如何解決的。當問題細化到具體實現時,就可以打開源碼,去尋找答案。

      結構上,Kafka不是一個特復雜系統。所以,若你的項目更復雜,層次更多,推薦把各層次逐一展開,先把整體結構放在心中,再做細節探索。

      核心技術

      就是能夠讓這個軟件的“實現”與眾不同的地方。

      了解關鍵技術可保證我們對代碼的調整不會使項目出現明顯劣化。

      大多數項目都愿意把自己的關鍵技術講出來,所以,找到這些信息不難。

      Kafka

      對寫入做了專門優化,使其整體吞吐能力很強。

      咋做到的?

      MQ實現消息存儲的方式通常是把它寫入磁盤,而Kafka不同之處在于,它利用磁盤順序讀寫特性。

      普通機械硬盤

      隨機寫,需按機械硬盤方式尋址,然后磁頭做機械運動,寫入很慢

      順序寫,會大幅減少磁頭運動

      可以這樣實現,也是充分利用MQ本身特性:有序,技術實現與需求完美結合的產物。還可進一步優化:利用內存映射文件減少用戶空間到內核空間復制的開銷。

      若站在了解實現的角度,你會覺得這都很自然。

      但要想從設計角度學到更多,還是應帶著問題上路,多問自己,為什么其它MQ不這么做?

      這的確值得深思。Kafka這個實現到底是哪里不容易想到呢?

      軟硬結合。

      其它MQ實現也會把消息寫入文件,但文件對于它們只是個通用接口。開發者并沒有想過利用硬件的特性做開發。而Kafka開發者突破此限制,把硬件特性利用起來,取得更好結果。

      LMAX Disruptor

      最強勁的線程通信庫。經典代碼片段:

      要理解這段代碼,必須理解CPU緩存行,這也是軟硬結合的設計。

      Disruptor緩存行填充中的填充字段。Disruptor中的一個元素是個volatile long類型,占用8字節。

      一但一個元素被修改,則與其在同一緩存行的所有元素的緩存都會失效。這就導致變更索引位1的元素,會導致索引位0的元素緩存也失效(操作時需重新從主內存加載)。

      所以,Disruptor做了一個緩存行填充的優化,在目標元素的前后都加7個類型字段,兩邊都占據掉56個字節。故而保證每個元素都獨占緩存行。是一種用空間換時間的思想。

      總結

      理解一個實現,是以對模型和接口的理解為前提。

      如果想了解一個系統的實現,應從軟件結構和關鍵技術兩個方面著手。無論是軟件結構,還是關鍵技術,我們都需要帶著自己的問題入手,而問題的出發點就是我們對模型和接口的理解。

      了解軟件的結構,其實,就是把分層的模型展開,看下一層模型:

      要知道這個層次給你提供了怎樣的模型

      要帶著自己的問題去了解這些模型為什么要這么設計

      Kafka的實現主要是針對機械硬盤做的優化,現在的SSD硬盤越來越多,成本越來越低,這個立意的出發點已經不像以前那樣穩固了。

      軟件的結構和核心技術應該分開,kafka之所以是:

      MQ,看的是對MQ這個模型結構的實現

      就沒必看存儲的實現,應該看路由信息管理、消息生產、消息消費等核心實現及其旁支功能的選擇(限制消息大小、故障節點延后、延遲消費)

      kafka,看的是其消息存儲核心技術實現

      如果想知道kafka為什么在 MQ如此突出,那就得了解其核心技術實現,即這里的軟硬結合的存儲設計。

      理解實現,帶著自己的問題,了解軟件的結構和關鍵的技術。

      Kafka

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何將一個excel表格的數據導入到另一個表中
      下一篇:怎嗎給別人發(如何給別人發短信)
      相關文章
      国产精品亚洲午夜一区二区三区| 亚洲第一成年网站大全亚洲| 亚洲中文字幕乱码熟女在线| 亚洲另类小说图片| 亚洲色偷偷av男人的天堂| 亚洲高清视频在线观看| 久久亚洲国产成人亚| 亚洲人成亚洲人成在线观看| 最新精品亚洲成a人在线观看| 亚洲av午夜精品一区二区三区| 亚洲av无码一区二区三区四区| 亚洲AV无码无限在线观看不卡| 亚洲AV无码精品蜜桃| 亚洲大香人伊一本线| 亚洲国产成人综合| 亚洲va乱码一区二区三区| 亚洲五月综合网色九月色| 中文字幕无码精品亚洲资源网久久| 亚洲综合小说另类图片动图| 亚洲性无码AV中文字幕| 亚洲成AV人片在WWW| 国产成人不卡亚洲精品91 | 无码不卡亚洲成?人片| 国产精品亚洲片在线花蝴蝶| 亚洲av午夜精品一区二区三区| 亚洲一级黄色视频| 亚洲精品高清国产一线久久| 亚洲成a人片在线观看中文动漫| 亚洲AV人无码综合在线观看| 色婷婷六月亚洲婷婷丁香| 亚洲综合激情视频| 亚洲人成在线免费观看| 亚洲中文精品久久久久久不卡| 亚洲欧美不卡高清在线| 亚洲国产成人爱av在线播放| 国产亚洲精久久久久久无码AV| 国产成人精品日本亚洲| 亚洲第一成年网站大全亚洲| 亚洲精品伊人久久久久| 亚洲国产精品美女久久久久| 亚洲熟伦熟女新五十路熟妇|