Redis 數據結構 之 SDS

SDS(simple dynamic string),簡單動態字符串。s同時它被稱為 Hacking String。hack 的地方就在 sds 保存了字符串的長度以及剩餘空間。sds 的實現在 sds.c 中。

C語言字符串使用長度為n+1的字符數組來表示長度為n的字符串,並且字符數組的最後一個元素總是空字符’\0’,這樣的方式存儲,時存在安全隱患的,並且它不能滿足效率方面的需求。

因此Redis沒有使用C原生的string而是自己構建了SDS。在Redis里,C語言字符串只用於一些無須對字符串值進行修改的地方,比如:日誌。

在Redis中,包含字符串值的鍵值對都是使用SDS實現的,除此之外,SDS還被用於AOF緩衝區、客戶端狀態的輸入緩衝區。

SDS定義

struct sdshdr{
     //字節數組
     char buf[]; 
     //buf數組中已使用字節數量
     int len;
     //buf數組中未使用字節數量
     int free;
}

如上圖所示,len表示該SDS保存了一個6字節長度(不包含結束符)的字符串,free表示該SDS還有6個字節的未使用空間,buf是一個char類型的數組 ,保存了該SDS所存儲的字符串值。

高效

相比C語言字符串,使獲取字符串長度時間複雜度降為O(1)而C原生的獲取長度為O(N) 遍歷整個數組。

安全

同時SDS杜絕緩衝區溢出,不會像C那樣造成數組數據不安全,絕對不會越界。

當需要對SDS進行修改時,API會先檢查SDS當前剩餘空間是否滿足修改之後所需的空間,如果不滿足的話API會自動將SDS的空間擴展至足夠用的空間然後才進行下一步操作,所以SDS不會出現緩衝區溢出問題。

減少內存分配

C語言字原生符串底層是使用一個n+1個字符長度的char類型數據實現的,所以每次增長或縮短一個原生字符串,程序都要對這個字符串數組進行一次內存重分配操作:

同時因為內存重分配涉及複雜的算法,並且可能需要執行系統調用,所以它通常是一個比較耗時的操作。Redis經常被用於速度要求嚴苛、數據被頻繁修改的場合,如果每次修改字符串都需要執行一次內存重分配的話,那麼對於性能會造成很大影響。

SDS 在分配了內存之後(往往空間會存在盈餘,也就是空間的預分配),然後自己通過len 和 free 來維護已使用的和未使用的內存,不再依賴系統來重新劃分,這樣能有效的提升性能。

空間預分配

用於字符串增長操作,當字符串增長時,程序會先檢查需不需要對SDS空間進行擴展,如果需要擴展,程序不僅會為SDS分配修改所必要的空間,還會為SDS分配額外的未使用空間,額外分配的未使用空間公式如下:

SDS空間 < 1MB

如果對SDS修改之後,SDS的長度(修改之後len屬性的值)小於1MB,那麼則分配和len屬性同樣大小的未使用空間,這時SDS的len屬性和free屬性的值相同。如:如果修改之後SDS的len將變為10字節,那麼程序也會分配10字節的未使用空間,SDS的buf數組實際長度變為10 + 10 + 1 = 21(額外一個字節用於保存結束符\n)

SDS空間 > 1MB

如果對SDS修改之後,SDS的長度大於等於1MB,那麼程序會分配1MB的未使用空間。如:修改之後的len將變為10MB,那麼程序會分配1MB的未使用空間,SDS的bug數組長度為10MB + 1MB + 1byte

SDS空間 > 512MB

Game over~ 報錯!

惰性空間釋放

用於優化SDS的字符串收縮操作,當字符串收縮時,程序不會立即執行內存重分配來回收收縮后內存多出來的空間,而是使用free屬性記錄下來,以備將來使用。

通過空間預分配,Redis可以減少連續執行字符串增長操作所需的內存重分配次數,通過惰性空間釋放,SDS避免了縮短字符串時所需的內存重分配操作,併為將來由可能的增長操作提供了優化。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

FB行銷專家,教你從零開始的技巧

聚甘新

「大家都累了」 美中仍保守 曼谷氣候談判陷泥沼

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

聚甘新

加州簽了! 2045年100%乾淨能源目標入法

環境資訊中心外電;姜唯 翻譯;林大利 審校;稿源:ENS

加州州長布朗10日簽署參議院100號法案(SB 100),將「100%乾淨電力」正式設立為法定目標。

繼提早四年達成「2020年減排13%、經濟成長26%」目標後,「SB 100」將使加州的再生能源比例標準更加積極,2025年必須達到50%電力由再生能源供應,2030年要達到60%,2045年實現零碳電網。

加州州長布朗簽署參議院100號法案(SB 100)。圖片來源:Office of the Governor

州長訂定碳中和目標  減碳不涉核電

為了確保全球暖化對策不只侷限於電業(佔加州溫室氣體排放量的16%),布朗還發布了一項行政命令,指示加州要在2045年實現碳中和,之後則要實現淨負排碳。

目前全球有20多個國家和40多個地方政府宣布,最晚要在本世紀中實現碳中和。

為了實現目標,加州將持續減少碳污染,同時增加森林、土壤和其他自然地景的碳儲存和空氣品質及公共衛生改善計畫,尤其是在該州受影響最嚴重的社區。

加州也將陸續實施一系列因應暖化的長期行動。上週,布朗簽署了另一項法案,禁止加州沿海進行新的聯邦海上石油鑽探活動,並宣布加州反對聯邦政府擴大加州公共土地上石油鑽探的計畫。1968年至今,加州都沒有開放沿海地區的新石油和天然氣租賃。

雖然加州政府定義的乾淨能源有三種,州政府在其網站上的指出,加州正在逐步淘汰核電,現階段也並不考慮新建核電廠。

減碳聯盟「Under2 Coalition」 規模跨六大洲、佔全球經濟四成

原本加州計畫於2020年達成減排13%、同時經濟成長26%,結果此目標提早四年達成。從2015到2016年,加州減排量大約等於減少240萬輛汽車上路,省下15億加侖的汽柴油燃料。

此外,布朗幫助建立全美和全球的減碳合作聯盟「Under2 Coalition」。該聯盟起源於加州與德國巴登-符騰堡州之間的合作關係,現在已納入橫跨六大洲的206個各級政府,共代表13億人口和30兆美元的GDP,相當於全球人口的17%和全球經濟的40%。

聯盟成員做出了一些重要承諾,包括減少相當於1990年水準80%至95%的溫室氣體排放,以及2050年加州每人每年碳排少於2公噸。

California Passes 100 Percent Clean Electricity Bill SACRAMENTO, California, September 10, 2018 (ENS)

Putting his stamp of approval on California’s global climate leadership, Governor Jerry Brown today signed Senate Bill 100, which sets a 100 percent clean electricity goal for the state. The governor also issued an executive order establishing a new target to achieve carbon neutrality – both by 2045.

With Governor Brown’s executive order, California establishes the most ambitious carbon neutrality commitment of the more than 20 countries and at least 40 cities, states and provinces planning to go carbon neutral by mid-century or sooner.

SB 100 advances the state’s existing Renewables Portfolio Standard, which establishes how much of the electricity system should be powered from renewable energy resources, to 50 percent by 2025 and 60 percent by 2030.

It also puts California on the bold path to implement a zero-carbon electricity grid by 2045.

To ensure California is combating global warming beyond the electric sector, which represents 16 percent of the state’s greenhouse gas emissions, the governor’s executive order directs the state to achieve carbon neutrality by 2045 and net negative greenhouse gas emissions after that.

The state will reach its goals with continued reductions of carbon pollution and increased carbon sequestration in forests, soils and other natural landscapes and programs focused on improving air quality and public health, especially in California’s most impacted communities.

These actions are the latest in a long series of actions by California to deal with the warming climate. Late last week, Governor Brown also signed legislation to block new federal offshore oil drilling along California’s coast and announced the state’s opposition to the federal government’s plan to expand oil drilling on public lands in California. The entirety of the state’s coast has been off-limits to new oil and gas leases for more than 30 years, and the state has not issued a lease for offshore oil or gas production since 1968.

The state has met its 2020 target four years early, reducing emissions 13 percent while growing the economy 26 percent.

From 2015 to 2016, emissions reductions were roughly equal to taking 2.4 million cars off the road, saving 1.5 billion gallons of gasoline and diesel fuel.

In addition, Governor Brown has helped establish and expand coalitions of partners across the nation and globe committed to curbing carbon pollution.

The Under2 Coalition, which originated from a partnership between California and the German state of Baden-Württemberg, now includes 206 jurisdictions on six continents that collectively represent 1.3 billion people and $30 trillion in GDP – equivalent to 17 percent of the global population and 40 percent of the global economy.

Members of the Under2 Coalition have made a number of key commitments, including reducing greenhouse gas emissions equivalent to 80 to 95 percent below 1990 levels or to less than two annual metric tons for each person in California by 2050.

※ 全文及圖片詳見:

作者

如果有一件事是重要的,如果能為孩子實現一個願望,那就是人類與大自然和諧共存。

於特有生物研究保育中心服務,小鳥和棲地是主要的研究對象。是龜毛的讀者,認為龜毛是探索世界的美德。

延伸閱讀

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

聚甘新

創新減廢 啤酒公司淘汰塑膠套環 改用可回收膠

環境資訊中心綜合外電;姜唯 編譯;林大利 審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

FB行銷專家,教你從零開始的技巧

聚甘新

2017第二屆中國中原國際充電站(樁)技術展

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

聚甘新

香港促推電動車用電池回收機制,避免生態汙染

一般的電動車用電池約有7~8 年的使用壽命,但因含有鋰、硫酸等重金屬,若無妥善回收處理,將有環境汙染之虞。香港政府所引入的首批電動車之電池屆臨退役,專家呼籲政府盡速制訂回收辦法,以避免更嚴重的環境破壞。

香港《蘋果日報》報導,香港在豁免電動車首次登記稅後,電動車數量急速從2010年的100輛以下成長到今年8月的6,167輛,其中以Tesla和Volkswagen最受歡迎。以一般電動車用電池約7年的平均壽命來看,香港首批電動車的舊電池已屆臨汰役,但香港目前仍無回收制度;若廢電池隨意丟棄,所造成的重金屬汙染恐怕較傳統柴油車和汽油車更嚴重,完全背離環保的美意。

香港汽車會副會長李耀培表示,車用電池的儲電量若降低到70%,就可能影響電動車行動速度,甚至造成熄火,進而影響行車安全,因此在此階段就會汰役換新。不過,這也意味著汰役的車用電池其實仍有70%的蓄電量,經妥善處理後可進行二次運用。

報導指出,香港過去會將這類廢電池交給有牌照的化學廢物處置設施進行初步處理,之後再出口到海外回收。但李耀培表示,這只是把汙染丟出香港,並沒有解決問題。他呼籲政府應制定長遠的回收機制,或可參考英國、歐洲等國家將汰役的電動車用電池改製為風力、太陽能儲能設備,更能有效利用電池,且也有助環保。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

聚甘新

BMW 2017年目標售出10萬輛電動車

德國媒體報導,汽車廠商BMW CEO Harald Krueger 在接受採訪時表示,電動車的時代即將到來,這一市場還有巨大的潛力,BMW 將在2017 年力爭把電動車的銷量提升到10 萬台,目前該公司2015 年電動車和混合動力車的銷量大約為6 萬台。

BMW CEO Harald Krueger 表示,該公司希望能夠在2017 年大幅提升電動車的銷量,至少提升六成,達到年銷量10 萬台。BMW 2016 年電動車和混合動力車的銷量合計大約為6 萬台,自2013 年發售電動車以來,BMW 電動車的雷軍銷量已經超過了10 萬台。

Harald Krueger 認為電動車的時代即將到來,這一市場還有很大的潛力,需求還沒有完全被發掘。

BMW 旗下唯一的純電動車車款i3 上市以來市場反響不如預期,2015 年i3 僅售出了2.5 萬台,為了提升這款產品的競爭力,BMW 將在2016 年的升級中把i3 系列電動車的續航里程提升50%。

在高階汽車市場中,BMW 的產品銷量已經落後於Benz,該公司希望在2025 年前將電動車和混合動力車的銷量提升到15%-25%。

(本文由《》授權提供。照片來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

聚甘新

電動車有害道路安全?美國規定汽車不能太安靜!

根據外電報導,美國政府正式通過一則汽車行駛新規定,也就是未來一些「安靜的汽車」,如電動汽車或混合動力汽車等,在行駛速度超過時速18.6 英里 (約30 公里)的情況下,必須增加噪音警報裝置,以避免傷及行人、盲人和騎車的路人。

根據美國國家公路交通安全管理局(NHTSA)發布的這則新規定表示,該規定將在2019 年9 月1 日起生效。屆時,包括特斯拉 (TESLA)、日產汽車 (Nisson) 和豐田汽車 (TOYOTA) 等廠商都需要為所有汽車增加噪音裝置。美國政府希望通過此規定,能夠防止每年多達2,400 件的行人受傷事故,並為53 萬輛汽車增設噪音專制。

NHTSA 指出,這項新規每年約會給汽車廠商增加3,900 萬美元的花費。因為,他們要為汽車增設一個外設防水喇叭。但是,能夠透過降低交通事故而每年節省約2.5 億到3.2 億美元的醫療費用。

該規定未來將適用於全美各地區,並且涵蓋路上行駛的電動汽車和混合動力汽車等。另外,包括帶有4 個輪子、總重量低於10,000 磅的車輛,也都必須在向後或向前行駛時,在速度達到每小時30 公里之際發出聲響,以警告周遭的路人與騎車的民眾。不過,NHTSA 也認為,規定汽車喇叭可有可無,因為輪胎和風也可以製造出足夠的噪音聲響,只要該聲響能達到警告的標準即可。

該項新的規定雖然受到全美盲人主組織的歡迎,但是卻讓汽車廠商表示擔憂。因為噪音也許會太大,並且實施起來將可能相當複雜。因為,新規只規定了最低的聲音要求,卻沒有制定必須發出什麼聲音。

(本文由《》授權提供。照片來源:特斯拉)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※超省錢租車方案

※別再煩惱如何寫文案,掌握八大原則!

※回頭車貨運收費標準

※教你寫出一流的銷售文案?

FB行銷專家,教你從零開始的技巧

聚甘新

對 JsonConvert 的認識太膚淺了,終於還是遇到了問題

一:背景

1. 講故事

在開始本文之前,真的好想做個問卷調查,到底有多少人和我一樣,對 JsonConvert 的認識只局限在 SerializeObjectDeserializeObject 這兩個方法上(┬_┬), 這樣我也好結伴同行,不再孤單落魄,或許是這兩個方法基本上能夠解決工作中 80% 的場景,對於我來說確實是這樣,但隨着編碼的延續,終究還是會遇到那剩下的 20% ,所以呀。。。

我的場景是這樣的:前段時間寫業務代碼的時候,我有一個自定義的客戶算法類型的Model,這個Model中有這種算法類型下的客戶群以及Report統計信息,還用了 HashSet 記錄了該類型下的 CustomerID集合,為了方便講述,我把Model簡化如下:


    class CustomerAlgorithmModel
    {
        public string DisplayName { get; set; }

        public int CustomerType { get; set; }

        public ReprotModel Report { get; set; }

        public HashSet<int> CustomerIDHash { get; set; }
    }

    class ReprotModel
    {
        public int TotalCustomerCount { get; set; }

        public int TotalTradeCount { get; set; }
    }

那有意思的就來了,我個人是有記日誌的癖好,就想着以後不會出現死無對證的情況,然後就理所當然的使用 JsonConvert.SerializeObject, 這一下就出問題了,日誌送入到了 ElasticSearch ,然後通過 Kibana 查不出來,為啥呢? 看完上面的 Model 我想你也猜到了原因,json體太大了哈,好歹 CustomerIDHash 中也有幾十萬個撒,這一下全導出成json了,這 size 還能小嗎? 要不我寫段代碼看一看。


        static void Main(string[] args)
        {
            var algorithModel = new CustomerAlgorithmModel()
            {
                CustomerType = 1,
                DisplayName = "",
                Report = new ReprotModel()
                {
                    TotalCustomerCount = 1000,
                    TotalTradeCount = 50
                },
                CustomerIDHash = new HashSet<int>(Enumerable.Range(1, 500000))
            };

            var json = JsonConvert.SerializeObject(algorithModel);

            File.WriteAllText("1.txt", json, Encoding.UTF8);

            Console.WriteLine("寫入完成!");
        }

可以看到,僅一個json就 3.3M,這樣的記錄多來幾打后,在 kibana 上一檢索,瀏覽器就卡的要死,其實 CustomerIDHash 這個字段對我來說是可有可無的,就算存下來了也沒啥大用,所以需求就來了,如何屏蔽掉 CustomerIDHash

二:尋求解決方案

1. 使用 JsonIgnore

有問題就網上搜啊,這一搜馬上就有人告訴你可以使用 JsonIgnoreAttribute 忽略特性,加好這個特性後繼續跑一下程序。


    [Newtonsoft.Json.JsonIgnore]
    public HashSet<int> CustomerIDHash { get; set; }

太好了,終於搞定了,但是靜下心來想一想,總感覺心裏有那麼一點不舒服,為什麼這麼說,一旦你給這個 CustomerIDHash 套上了 JsonIgnore ,這就意味着它在 JsonConvet 的世界中從此消失,也不管是誰在使用這個Model, 但這並不是我的初衷,我的初衷僅僅是為了在記錄日誌的時候踢掉 CustomerIDHash,可千萬不要影響在其他場景下的使用哈,現在這種做法就會給自己,給別人挖坑,埋下了不可預知的bug,我想你應該明白我的意思,還得繼續尋找下一個方案。

2. 使用自定義的 JsonConverter

真的,Newtonsoft 太強大了,我都想寫一個專題好好彌補彌補我的知識盲區,其實在這個場景中不就是想把 HashSet<int> 給屏蔽掉嘛,Newtonsoft 中專門提供了一個針對特定類型的自定義處理類,接下來我就寫一段:


   /// <summary>
   /// 自定義一個 針對 HashSet<int> 的轉換類
   /// </summary>
   public class HashSetConverter : Newtonsoft.Json.JsonConverter<HashSet<int>>
   {
       public override HashSet<int> ReadJson(JsonReader reader, Type objectType, HashSet<int> existingValue, bool hasExistingValue, JsonSerializer serializer)
       {
           return existingValue;
       }

       public override void WriteJson(JsonWriter writer, HashSet<int> value, JsonSerializer serializer)
       {
           writer.WriteNull();
       }
   } 

就是這麼簡單,然後就可以在 SerializeObject 的時候指定下自定義的 HashSetConverter 即可,然後再將程序跑起來看一下。


 var json = JsonConvert.SerializeObject(algorithModel, Formatting.Indented, new HashSetConverter());

從圖中看,貌似也是解決了,但我突然發現自己要鑽牛角尖了,如果我的實體中又來了一個頂級優質客戶群的 TopNCustomerIDHash,但因為這個CustomerID 比較少,我希望在 Json 中能保留下來,然後就是踢掉的那個 CustomerIDHash 我要保留 CustomerIDHash.Length ,哈哈,搞事情哈,那接下來怎麼解決呢?

  • 修改 Model 實體

    class CustomerAlgorithmModel
    {
        public HashSet<int> CustomerIDHash { get; set; }

        // topN 優質客戶群
        public HashSet<int> TopNCustomerIDHash { get; set; }
    }

  • HashSetConverter 增加邏輯鑒別是否為保留字段

        public override void WriteJson(JsonWriter writer, HashSet<int> value, JsonSerializer serializer)
        {
            if (writer.Path == "TopNCustomerIDHash")
            {
                writer.WriteStartArray();

                foreach (var item in value)
                {
                    writer.WriteValue(item);
                }

                writer.WriteEndArray();
            }
            else
            {
                writer.WriteValue(value.Count);
            }
        }

  • 最後給 TopNCustomerIDHash 賦值

            var algorithModel = new CustomerAlgorithmModel()
            {
                CustomerType = 1,
                DisplayName = "",
                Report = new ReprotModel()
                {
                    TotalCustomerCount = 1000,
                    TotalTradeCount = 50
                },
                CustomerIDHash = new HashSet<int>(Enumerable.Range(1, 500000)),
                TopNCustomerIDHash = new HashSet<int>(Enumerable.Range(1, 10)),
            };

三塊都搞定后就可以把程序跑起來了,如下圖:

貌似鑽牛角尖的問題是解決了,既然鑽牛角尖肯定要各種鄙視,比如這裏的 ReportModel 我是不需要的,CustomerType 我也是不需要的,我僅僅需要看一下 DisplayNameTotalCustomerCount 這兩個字段就可以了, 那這個要怎麼解決呢?

3. 使用 匿名類型

確實很多時候記日誌,就是為了跟蹤 Model 中你特別關心的那幾個字段,所以摻雜了多餘的字段確實也是沒必要的,這裏可以用匿名來解決,我就來寫一段代碼:


    var json = JsonConvert.SerializeObject(new
    {
        algorithModel.DisplayName,
        algorithModel.Report.TotalCustomerCount
    }, Formatting.Indented);

三: 總結

雖然阻擊了幾個回合,但同時也發現了 Newtonsoft 中還有特別多的未挖掘功能,真的需要好好研究研究,源碼已下好,接下來準備做個系列來解剖一下,值得一提的是 .Net中已自帶了 System.Text.Json.JsonSerializer 類,目前來看功能還不算太豐富,簡單用用還是可以的,本篇就說到這裏,希望對您有幫助。

如您有更多問題與我互動,掃描下方進來吧~

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

USB CONNECTOR掌控什麼技術要點? 帶您認識其相關發展及效能

台北網頁設計公司這麼多該如何選擇?

※智慧手機時代的來臨,RWD網頁設計為架站首選

※評比南投搬家公司費用收費行情懶人包大公開

※回頭車貨運收費標準

聚甘新

一起玩轉微服務(5)——分層架構

領域驅動設計DDD(Domain Driven Design)提出了從業務設計到代碼實現一致性的要求,不再對分析模型和實現模型進行區分。也就是說從代碼的結構中我們可以直接理解業務的設計,命名得當的話,非程序人員也可以“讀”代碼。這與微服務設計中的約定優於配置不謀而合,如果你熟悉英文,那麼直接根據包名和類名就可以直接解讀出程序開發者所構建的業務的大概意圖。

領域模型包含一些明確定義的類型:

  • 實體是一個對象,它有固定的身份,具有明確定義的”連續性線索”或生命周期。通常列舉的示例是一個 Person(一個實體)。大多數系統都需要唯一地跟蹤一個 Person,無論姓名、地址或其他屬性是否更改。
  • l值對象沒有明確定義的身份,而僅由它們的屬性定義。它們通常不可變,所以兩個相等的值對象始終保持相等。地址可以是與 Person 關聯的值對象。
  • l集合是一個相關對象集群,這些對象被看作一個整體。它擁有一個特定實體作為它的根,並定義了明確的封裝邊界。它不只是一個列表。
  • l服務用於表示不是實體或值對象的自然部分的操作或活動。

領域模型在實現時可大可小,在業務的早期,在系統比較小的情況下,它有可能是一個類。當系統做大了以後,它可能是個庫。再做更大一點的時候,它可能是一個服務,給不同的應用去調用。

要將領域元素轉換為服務,可按照以下一般準則來完成此操作:

  • 使用值對象的表示作為參數和返回值,將集合和實體轉換為獨立的微服務。
  • 將領域服務(未附加到集合或實體的服務)與獨立的微服務相匹配。
  • 每個微服務應處理一個完整的業務功能。

領域模型又可以分為失血、貧血和充血3種。

  • 失血模型:基於數據庫的領域設計方式就是典型的失血模型,只關注數據的增刪改查。
  • 貧血模型:就是在domain object包含了不依賴於持久化的領域邏輯,而那些依賴持久化的領域邏輯被分離到server層。
  • 充血模型:充血模型跟貧血模型差不多,不同的是如何劃分業務邏輯,就是說,約大部分業務應該放到domain object裏面,而service應該是很薄的一層。

設計原則之分層架構

同一公司使用統一應用分層,以減少開發維護學習成本。應用分層這件事情看起來很簡單,但每個程序員都有自己的一套,哪怕是初學者,所以想實施起來並非那麼容易。

最早接觸分層架構的應該是我們最熟悉的MVC(Model-View-Controller)架構,將應用分成了模型、視圖和控制層,可以說引導了絕大多數開發者,而我們現在的應用中非常多的包括框架,架構設計都使用此模式。這后又演化出了MVP(Model-View-Presenter)和MVVM(Model-View-ViewModel)。這些可以說都是隨着技術的不斷髮展,為了應對不同場景所演化出來的模型。而微服務的每個架構都可以再細分成領域模型,下面看一下經典的領域模型架構。

它包括了Domain,Service Layer和Repositories。核心實體(Entity)和值對象(Value Object)應該在Domain層,定義的領域服務(Domain Service)在Service Layer,而針對實體和值對象的存儲和查詢邏輯都應該在Repositories層。值得注意的是,不要把Entity的屬性和行為分離到Domain和Service兩層中去實現,即所謂的貧血模型,事實證明這樣的實現方式會造成很大的維護問題。基於這種設計,工程的結構可以構造為:

– MicroService-Sample/src/

    domain

    gateways

    interface

    repositories

    services

當然,在微服務的架構中,每個微服務不必嚴格遵照這樣的規定,切忌死搬硬套,最重要的是理解,在不同的業務場合,架構的設計可以適當的做調整,畢竟適合的架構一定要具有靈活性。

分層的原則包括:

  • 文件夾分層法

應用分層採用文件夾方式的優點是可大可小、簡單易用、統一規範,可以包括 5 個項目,也可以包括 50 個項目,以滿足所有業務應用的多種不同場景。

  • 調用規約

在開發過程中,需要遵循分層架構的約束,禁止跨層次的調用。

  • 下層為上層服務

以用戶為中心,以目標為導向。上層(業務邏輯層)需要什麼,下層(數據訪問層)提供什麼,而不是下層(數據訪問層)有什麼,就向上層(業務邏輯層)提供什麼。

  • 實體層規約

Entity是數據表對象,不是數據訪問層對象;DTO 是網絡傳輸對象,不是表現層對象;BO 是內存計算邏輯對象,不是業務邏輯層對象,不是只能給業務邏輯層使用 。如果僅限定在本層訪問,則導致單個應用內大量沒有價值的對象轉換。以用戶為中心來設計實體類,可以減少無價值重複對象和無用轉換。

  • U 型訪問

下行時表現層是 Input,業務邏輯層是 Process,數據訪問層是 Output。上行時數據訪問層是 Input,業務邏輯層是 Process,  表現層就 Output。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※教你寫出一流的銷售文案?

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

※超省錢租車方案

※產品缺大量曝光嗎?你需要的是一流包裝設計!

聚甘新