精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

九大服務(wù)架構(gòu)性能優(yōu)化方式

開(kāi)發(fā)
本文主要總結(jié)進(jìn)行服務(wù)性能優(yōu)化的幾種方式,每一種方式在我們常用的中間件中都有所體現(xiàn)。

作者 | jialiangsun

最近做了一些服務(wù)性能優(yōu)化,文章池服務(wù)平均耗時(shí)跟p99耗時(shí)都下降80%左右,事件底層頁(yè)服務(wù)平均耗時(shí)下降50%多左右,主要優(yōu)化項(xiàng)目中一些不合理設(shè)計(jì),例如服務(wù)間使用json傳輸數(shù)據(jù),監(jiān)控上報(bào)處理邏輯在主流程中,重復(fù)數(shù)據(jù)每次都請(qǐng)求下游服務(wù),多個(gè)耗時(shí)操作串行請(qǐng)求等,這些問(wèn)題都對(duì)服務(wù)有著嚴(yán)重的性能影響。

在服務(wù)架構(gòu)設(shè)計(jì)時(shí)通常可以使用一些中間件去提升服務(wù)性能,例如使用mysql,redis,kafka等,因?yàn)檫@些中間件有著很好的讀寫(xiě)性能。除了使用中間件提升服務(wù)性能外,也可以通過(guò)探索它們通過(guò)什么樣的底層設(shè)計(jì)實(shí)現(xiàn)的高性能,將這些設(shè)計(jì)應(yīng)用到我們的服務(wù)架構(gòu)中。

常用的性能優(yōu)化方法可以分為以下幾種:

性能優(yōu)化九大方式

1.緩存

性能優(yōu)化,緩存為王,所以開(kāi)始先介紹一下緩存。緩存在我們的架構(gòu)設(shè)計(jì)中無(wú)處不在的,常規(guī)請(qǐng)求是瀏覽器發(fā)起請(qǐng)求,請(qǐng)求服務(wù)端服務(wù),服務(wù)端服務(wù)再查詢(xún)數(shù)據(jù)庫(kù)中的數(shù)據(jù),每次讀取數(shù)據(jù)都會(huì)至少需要兩次網(wǎng)絡(luò)I/O,性能會(huì)差一些,我們可以在整個(gè)流程中增加緩存來(lái)提升性能。首先是瀏覽器測(cè),可以通過(guò)Expires、Cache-Control、Last-Modified、Etag等相關(guān)字段來(lái)控制瀏覽器是否使用本地緩存。

其次我們可以在服務(wù)端服務(wù)使用本地緩存或者一些中間件來(lái)緩存數(shù)據(jù),例如redis。redis之所以這么快,主要因?yàn)閿?shù)據(jù)存儲(chǔ)在內(nèi)存中,不需要讀取磁盤(pán),因?yàn)閮?nèi)存讀取速度通常是磁盤(pán)的數(shù)百倍甚至更多;

然后在數(shù)據(jù)庫(kù)測(cè),通常使用的是mysql,mysql的數(shù)據(jù)存儲(chǔ)到磁盤(pán)上,但是mysql為了提升讀寫(xiě)性能,會(huì)利用bufferpool緩存數(shù)據(jù)頁(yè)。mysql讀取時(shí)會(huì)按照頁(yè)的粒度將數(shù)據(jù)頁(yè)讀取到bufferpool中,bufferpool中的數(shù)據(jù)頁(yè)使用LRU算法淘汰長(zhǎng)期沒(méi)有用到的頁(yè)面,緩存最近訪問(wèn)的數(shù)據(jù)頁(yè)。

此外小到cpu的l1、l2、l3級(jí)cache,大到瀏覽器緩存都是為了提高性能,緩存也是進(jìn)行服務(wù)性能優(yōu)化的重要手段,使用緩存時(shí)需要考慮以下幾點(diǎn):

(1) 使用什么樣的緩存

使用緩存時(shí)可以使用redis或者機(jī)器內(nèi)存來(lái)緩存數(shù)據(jù),使用redis的好處可以保證不同機(jī)器讀取數(shù)據(jù)的一致性,但是讀取redis會(huì)增加一次I/O,使用內(nèi)存緩存數(shù)據(jù)時(shí)可能會(huì)出現(xiàn)讀取數(shù)據(jù)不一致,但是讀取性能好。例如文章的閱讀數(shù)數(shù)據(jù),如果使用機(jī)器內(nèi)存作為緩存,容易出現(xiàn)不同機(jī)器上緩存數(shù)據(jù)的不一致,用戶不同刷次會(huì)請(qǐng)求到不同服務(wù)端機(jī)器,讀取的閱讀數(shù)不一致,可能會(huì)出現(xiàn)閱讀數(shù)變小的情況,用戶體驗(yàn)不好。對(duì)于閱讀數(shù)這種經(jīng)常變更的數(shù)據(jù)比較適合使用redis來(lái)統(tǒng)一緩存。

也可以將兩者結(jié)合提升服務(wù)的性能,例如在內(nèi)容池服務(wù),利用redis跟機(jī)器內(nèi)存緩存熱點(diǎn)文章詳情,優(yōu)先讀取機(jī)器內(nèi)存中的數(shù)據(jù),數(shù)據(jù)不存在的時(shí)候會(huì)讀取redis中的緩存數(shù)據(jù),當(dāng)redis中的數(shù)據(jù)也不存在的時(shí)候,會(huì)讀取下游持久化存儲(chǔ)中的全量數(shù)據(jù)。其中內(nèi)存級(jí)緩存過(guò)期時(shí)間為15s,在數(shù)據(jù)變更的時(shí)候不保證數(shù)據(jù)一致性,通過(guò)數(shù)據(jù)自然過(guò)期來(lái)保證最終一致性。redis中緩存數(shù)據(jù)需要保證與持久化存儲(chǔ)中數(shù)據(jù)一致性,如何保證一致性在后續(xù)講解。可以根據(jù)自己的業(yè)務(wù)場(chǎng)景可以選擇合適的緩存方案。

使用緩存時(shí)可以使用redis或者機(jī)器內(nèi)存來(lái)緩存數(shù)據(jù),使用redis的好處可以保證不同機(jī)器讀取數(shù)據(jù)的一致性,但是讀取redis會(huì)增加一次I/O,使用內(nèi)存緩存數(shù)據(jù)時(shí)可能會(huì)出現(xiàn)讀取數(shù)據(jù)不一致,但是讀取性能好。例如文章的閱讀數(shù)數(shù)據(jù),如果使用機(jī)器內(nèi)存作為緩存,容易出現(xiàn)不同機(jī)器上緩存數(shù)據(jù)的不一致,用戶不同刷次會(huì)請(qǐng)求到不同服務(wù)端機(jī)器,讀取的閱讀數(shù)不一致,可能會(huì)出現(xiàn)閱讀數(shù)變小的情況,用戶體驗(yàn)不好。對(duì)于閱讀數(shù)這種經(jīng)常變更的數(shù)據(jù)比較適合使用redis來(lái)統(tǒng)一緩存。

也可以將兩者結(jié)合提升服務(wù)的性能,例如在內(nèi)容池服務(wù),利用redis跟機(jī)器內(nèi)存緩存熱點(diǎn)文章詳情,優(yōu)先讀取機(jī)器內(nèi)存中的數(shù)據(jù),數(shù)據(jù)不存在的時(shí)候會(huì)讀取redis中的緩存數(shù)據(jù),當(dāng)redis中的數(shù)據(jù)也不存在的時(shí)候,會(huì)讀取下游持久化存儲(chǔ)中的全量數(shù)據(jù)。其中內(nèi)存級(jí)緩存過(guò)期時(shí)間為15s,在數(shù)據(jù)變更的時(shí)候不保證數(shù)據(jù)一致性,通過(guò)數(shù)據(jù)自然過(guò)期來(lái)保證最終一致性。redis中緩存數(shù)據(jù)需要保證與持久化存儲(chǔ)中數(shù)據(jù)一致性,如何保證一致性在后續(xù)講解。可以根據(jù)自己的業(yè)務(wù)場(chǎng)景可以選擇合適的緩存方案。

(2) 緩存常見(jiàn)問(wèn)題

  • 緩存雪崩:緩存雪崩是指緩存中的大量數(shù)據(jù)同時(shí)失效或者過(guò)期,導(dǎo)致大量的請(qǐng)求直接讀取到下游數(shù)據(jù)庫(kù),導(dǎo)致數(shù)據(jù)庫(kù)瞬時(shí)壓力過(guò)大,通常的解決方案是將緩存數(shù)據(jù)設(shè)置的過(guò)期時(shí)間隨機(jī)化。在事件服務(wù)中就是利用固定過(guò)期時(shí)間+隨機(jī)值的方式進(jìn)行文章的淘汰,避免緩存雪崩。
  • 緩存穿透:緩存穿透是指讀取下游不存在的數(shù)據(jù),導(dǎo)致緩存命中不了,每次都請(qǐng)求下游數(shù)據(jù)庫(kù)。這種情況通常會(huì)出現(xiàn)在線上異常流量攻擊或者下游數(shù)據(jù)被刪除的狀況,針對(duì)緩存穿透可以使用布隆過(guò)濾器對(duì)不存在的數(shù)據(jù)進(jìn)行過(guò)濾,或者在讀取下游數(shù)據(jù)不存在的情況,可以在緩存中設(shè)置空值,防止不斷的穿透。事件服務(wù)可能會(huì)出現(xiàn)查詢(xún)文章被刪除的情況,就是利用設(shè)置空值的方法防止被刪除數(shù)據(jù)的請(qǐng)求不斷穿透到下游。
  • 緩存擊穿: 緩存擊穿是指某個(gè)熱點(diǎn)數(shù)據(jù)在緩存中被刪除或者過(guò)期,導(dǎo)致大量的熱點(diǎn)請(qǐng)求同時(shí)請(qǐng)求數(shù)據(jù)庫(kù)。解決方案可以對(duì)于熱點(diǎn)數(shù)據(jù)設(shè)置較長(zhǎng)的過(guò)期時(shí)間或者利用分布式鎖避免多個(gè)相同請(qǐng)求同時(shí)訪問(wèn)下游服務(wù)。在新聞業(yè)務(wù)中,對(duì)于熱點(diǎn)新聞經(jīng)常會(huì)出現(xiàn)這種情況,事件服務(wù)利用golang的singlefilght保證同一篇文章請(qǐng)求在同一時(shí)刻只有一個(gè)會(huì)請(qǐng)求到下游,防止緩存擊穿。
  • 熱點(diǎn)key: 熱點(diǎn)key是指緩存中被頻繁訪問(wèn)的key,導(dǎo)致緩存該key的分片或者redis訪問(wèn)量過(guò)高。可以將可熱點(diǎn)key分散存儲(chǔ)到多個(gè)key上,例如將熱點(diǎn)key+序列號(hào)的方式存儲(chǔ),不同key存儲(chǔ)的值都是相同的,在訪問(wèn)時(shí)隨機(jī)訪問(wèn)一個(gè)key,分散原來(lái)單key分片的壓力;此外還可以將key緩存到機(jī)器內(nèi)存中,避免redis單節(jié)點(diǎn)壓力過(guò)大,在新聞業(yè)務(wù)中,對(duì)于熱點(diǎn)文章就是采用這種方式,將熱點(diǎn)文章存儲(chǔ)到機(jī)器內(nèi)存中,避免存儲(chǔ)熱點(diǎn)文章redis單分片請(qǐng)求量過(guò)大。
key val    =>  key1 val 、  key2 val、  key3 val 、 key4 val

(3) 緩存淘汰

緩存的大小是有限的,因?yàn)樾枰獙?duì)緩存中數(shù)據(jù)進(jìn)行淘汰,通常可以采用隨機(jī)、LRU或者LFU算法等淘汰數(shù)據(jù)。LRU是一種最常用的置換算法,淘汰最近最久未使用的數(shù)據(jù),底層可以利用map+雙端隊(duì)列的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)。

最原生的LRU算法是存在一些問(wèn)題的,不知道大家在使用過(guò)有沒(méi)有遇到過(guò)問(wèn)題。首先需要注意的是在數(shù)據(jù)結(jié)構(gòu)中有互斥鎖,因?yàn)間olang對(duì)于map的讀寫(xiě)會(huì)產(chǎn)生panic,導(dǎo)致服務(wù)異常。使用互斥鎖之后會(huì)導(dǎo)致整個(gè)緩存性能變差,可以采用分片的思想,將整個(gè)LRUCache分為多個(gè),每次讀取時(shí)讀取其中一個(gè)cache片,降低鎖的粒度來(lái)提升性能,常見(jiàn)的本地緩存包通常就利用這種方式實(shí)現(xiàn)的。

type LRUCache struct {
    sync.Mutex
    size int     
    capacity int
    cache map[int]*DLinkNode
    head, tail *DLinkNode
}
type DLinkNode struct {
    key,value int
    pre, next *DLinkNode
}

mysql也會(huì)利用LRU算法對(duì)buffer pool中的數(shù)據(jù)頁(yè)進(jìn)行淘汰。由于mysql存在預(yù)讀,在讀取磁盤(pán)時(shí)并不是按需讀取,而是按照整個(gè)數(shù)據(jù)頁(yè)的粒度進(jìn)行讀取,一個(gè)數(shù)據(jù)頁(yè)會(huì)存儲(chǔ)多條數(shù)據(jù),除了讀取當(dāng)前數(shù)據(jù)頁(yè),可能也會(huì)將接下來(lái)可能用到的相鄰數(shù)據(jù)頁(yè)提前緩存到bufferpool中,如果下次讀取的數(shù)據(jù)在緩存中,直接讀取內(nèi)存即可,不需要讀取磁盤(pán),但是如果預(yù)讀的數(shù)據(jù)頁(yè)一直沒(méi)有被訪問(wèn),那就會(huì)存在預(yù)讀失效的情況,淘汰原來(lái)使用到的數(shù)據(jù)頁(yè)。mysql將buffer pool中的鏈表分為兩部分,一段是新生代,一段是老生代,新老生代的默認(rèn)比是7:3,數(shù)據(jù)頁(yè)被預(yù)讀的時(shí)候會(huì)先加到老生代中,當(dāng)數(shù)據(jù)頁(yè)被訪問(wèn)時(shí)才會(huì)加載到新生代中,這樣就可以防止預(yù)讀的數(shù)據(jù)頁(yè)沒(méi)有被使用反而淘汰熱點(diǎn)數(shù)據(jù)頁(yè)。此外mysql通常會(huì)存在掃描表的請(qǐng)求,會(huì)順序請(qǐng)求大量的數(shù)據(jù)加載到緩存中,然后將原本緩存中所有熱點(diǎn)數(shù)據(jù)頁(yè)淘汰,這個(gè)問(wèn)題通常被稱(chēng)為緩沖池污染,mysql中的數(shù)據(jù)頁(yè)需要在老生代停留時(shí)間超過(guò)配置時(shí)間才會(huì)老生代移動(dòng)到新生代時(shí)來(lái)解決緩存池污染。

redis中也會(huì)利用LRU進(jìn)行淘汰過(guò)期的數(shù)據(jù),如果redis將緩存數(shù)據(jù)都通過(guò)一個(gè)大的鏈表進(jìn)行管理,在每次讀寫(xiě)時(shí)將最新訪問(wèn)的數(shù)據(jù)移動(dòng)到鏈表隊(duì)頭,那樣會(huì)嚴(yán)重影響redis的讀寫(xiě)性能,此外會(huì)增加額外的存儲(chǔ)空間,降低整體存儲(chǔ)數(shù)量。redis是對(duì)緩存中的對(duì)象增加一個(gè)最后訪問(wèn)時(shí)間的字段,在對(duì)對(duì)象進(jìn)行淘汰的時(shí)候,會(huì)采用隨機(jī)采樣的方案,隨機(jī)取5個(gè)值,淘汰最近訪問(wèn)時(shí)間最久的一個(gè),這樣就可以避免每次都移動(dòng)節(jié)點(diǎn)。但是LRU也會(huì)存在緩存污染的情況,一次讀取大量數(shù)據(jù)會(huì)淘汰熱點(diǎn)數(shù)據(jù),因此redis可以選擇利用LFU進(jìn)行淘汰數(shù)據(jù),是將原來(lái)的訪問(wèn)時(shí)間字段變更為最近訪問(wèn)時(shí)間+訪問(wèn)次數(shù)的一個(gè)字段,這里需要注意的是訪問(wèn)次數(shù)并不是單純的次數(shù)累加,而是根據(jù)最近訪問(wèn)時(shí)間跟當(dāng)前時(shí)間的差值進(jìn)行時(shí)間衰減的,簡(jiǎn)單說(shuō)也就是訪問(wèn)越久以及訪問(wèn)次數(shù)越少計(jì)算得到的值也越小,越容易被淘汰。

typedef struct redisObject {
 unsigned type:4;
 unsigned encoding:4;
 unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
 * LFU data (least significant 8 bits frequency
 * and most significant 16 bits access time). */
 int refcount;
 void *ptr;
} obj ;

可以看出不同中間件對(duì)于傳統(tǒng)的LRU淘汰策略都進(jìn)行了一定優(yōu)化來(lái)保證服務(wù)性能,我們也可以參考不同的優(yōu)化策略在自己的服務(wù)中進(jìn)行緩存key的淘汰。

(4) 緩存數(shù)據(jù)一致性

當(dāng)數(shù)據(jù)庫(kù)中的數(shù)據(jù)變更時(shí),如何保證緩存跟數(shù)據(jù)庫(kù)中的數(shù)據(jù)一致,通常有以下幾種方案:更新緩存再更新DB,更新DB再更新緩存,先更新DB再刪除緩存,刪除緩存再更新DB。這幾種方案都有可能會(huì)出現(xiàn)緩存跟數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致的情況,最常用的還是更新DB再刪除緩存,因?yàn)檫@種方案導(dǎo)致數(shù)據(jù)不一致的概率最小,但是也依然會(huì)存在數(shù)據(jù)不一致的問(wèn)題。例如在T1時(shí)緩存中無(wú)數(shù)據(jù),數(shù)據(jù)庫(kù)中數(shù)據(jù)為100,線程B查詢(xún)緩存沒(méi)有查詢(xún)到數(shù)據(jù),讀取到數(shù)據(jù)庫(kù)的數(shù)據(jù)100然后去更新緩存,但是此時(shí)線程A將數(shù)據(jù)庫(kù)中的數(shù)據(jù)更新為99,然后在T4時(shí)刻刪除緩存中的數(shù)據(jù),但是此時(shí)緩存中還沒(méi)有數(shù)據(jù),在T5的時(shí)候線程B才更新緩存數(shù)據(jù)為100,這時(shí)候就會(huì)導(dǎo)致緩存跟數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致。

為保證緩存與數(shù)據(jù)庫(kù)數(shù)據(jù)的一致性。常用的解決方案有兩種,一種是延時(shí)雙刪,先刪除緩存,后續(xù)更新數(shù)據(jù)庫(kù),休眠一會(huì)再刪除緩存。文章池服務(wù)中就是利用這種方案保證數(shù)據(jù)一致性,如何實(shí)現(xiàn)延遲刪除,是通過(guò)go語(yǔ)言中channel實(shí)現(xiàn)簡(jiǎn)單延時(shí)隊(duì)列,沒(méi)有引入第三方的消息隊(duì)列,主要為了防止服務(wù)的復(fù)雜化;另外一種可以訂閱DB的變更binlog,數(shù)據(jù)更新時(shí)只更新DB,通過(guò)消費(fèi)DB的binlog日志,解析變更操作進(jìn)行緩存變更,更新失敗時(shí)不進(jìn)行消息的提交,通過(guò)消息隊(duì)列的重試機(jī)制實(shí)現(xiàn)最終一致性。

2.并行化處理

redis在版本6.0之前都是號(hào)稱(chēng)單線程模型,主要是利用epllo管理用戶海量連接,使用一個(gè)線程通過(guò)事件循環(huán)來(lái)處理用戶的請(qǐng)求,優(yōu)點(diǎn)是避免了線程切換和鎖的競(jìng)爭(zhēng),以及實(shí)現(xiàn)簡(jiǎn)單,但是缺點(diǎn)也比較明顯,不能有效的利用cpu的多核資源。隨著數(shù)據(jù)量和并發(fā)量的越來(lái)越大,I/O成了redis的性能瓶頸點(diǎn),因此在6.0版本引入了多線程模型。redis的多線程將處理過(guò)程最耗時(shí)的sockect的讀取跟解析寫(xiě)入由多個(gè)I/O 并發(fā)完成,對(duì)于命令的執(zhí)行過(guò)程仍然由單線程完成。

mysql的主從同步過(guò)程從數(shù)據(jù)庫(kù)通過(guò)I/Othread讀取住主庫(kù)的binlog,將日志寫(xiě)入到relay log中,然后由sqlthread執(zhí)行relaylog進(jìn)行數(shù)據(jù)的同步。其中sqlthread就是由多個(gè)線程并發(fā)執(zhí)行加快數(shù)據(jù)的同步,防止主從同步延遲。sqlthread多線程化也經(jīng)歷了多個(gè)版本迭代,按表維度分發(fā)到同一個(gè)線程進(jìn)行數(shù)據(jù)同步,再到按行維度分發(fā)到同一個(gè)線程。

小到線程的并發(fā)處理,大到redis的集群,以及kafka的分topic分區(qū)都是通過(guò)多個(gè)client并行處理提高服務(wù)的讀寫(xiě)性能。在我們的服務(wù)設(shè)計(jì)中可以通過(guò)創(chuàng)建多個(gè)容器對(duì)外服務(wù)提高服務(wù)的吞吐量,服務(wù)內(nèi)部可以將多個(gè)串行的I/O操作改為并行處理,縮短接口的響應(yīng)時(shí)長(zhǎng),提升用戶體驗(yàn)。對(duì)于I/O存在相互依賴(lài)的情況,可以進(jìn)行多階段分批并行化處理,另外一種常見(jiàn)的方案就是利用DAG加速執(zhí)行,但是需要注意的是DAG會(huì)存在開(kāi)發(fā)維護(hù)成本較高的情況,需要根據(jù)自己的業(yè)務(wù)場(chǎng)景選擇合適的方案。并行化也不是只有好處沒(méi)有壞處的,并行化有可能會(huì)導(dǎo)致讀擴(kuò)散嚴(yán)重,以及線程切換頻繁存在一定的性能影響。

3.批量化處理

kafka的消息發(fā)送并不是直接寫(xiě)入到broker中的,發(fā)送過(guò)程是將發(fā)送到同一個(gè)topic同一個(gè)分區(qū)的消息通過(guò)main函數(shù)的partitioner組件發(fā)送到同一個(gè)隊(duì)列中,由sender線程不斷拉取隊(duì)列中消息批量發(fā)送到broker中。利用批量發(fā)送消息處理,節(jié)省大量的網(wǎng)絡(luò)開(kāi)銷(xiāo),提高發(fā)送效率。

redis的持久化方式有RDB跟AOF兩種,其中AOF在執(zhí)行命令寫(xiě)入內(nèi)存后,會(huì)寫(xiě)入到AOF緩沖區(qū),可以選擇合適的時(shí)機(jī)將AOF緩沖區(qū)中的數(shù)據(jù)寫(xiě)入到磁盤(pán)中,刷新到磁盤(pán)的時(shí)間通過(guò)參數(shù)appendfsync控制,有三個(gè)值always、everysec、no。其中always會(huì)在每次命令執(zhí)行完都會(huì)刷新到磁盤(pán)來(lái)保證數(shù)據(jù)的可靠性;everysec是每秒批量寫(xiě)入到磁盤(pán),no是不進(jìn)行同步操作,由操作系統(tǒng)決定刷新到寫(xiě)回磁盤(pán),當(dāng)redis異常退出時(shí)存在丟數(shù)據(jù)的風(fēng)險(xiǎn)。AOF命令刷新到磁盤(pán)的時(shí)機(jī)會(huì)影響redis服務(wù)寫(xiě)入性能,通常配置為everysec批量寫(xiě)入到磁盤(pán),來(lái)平衡寫(xiě)入性能和數(shù)據(jù)可靠性。

我們讀取下游服務(wù)或者數(shù)據(jù)庫(kù)的時(shí)候,可以一次多查詢(xún)幾條數(shù)據(jù),節(jié)省網(wǎng)絡(luò)I/O;讀取redis的還可以利用pipeline或者lua腳本處理多條命令,提升讀寫(xiě)性能;前端請(qǐng)求js文件或者小圖片時(shí),可以將多個(gè)js文件或者圖片合并到一起返回,減少前端的連接數(shù),提升傳輸性能。同樣需要注意的是批量處理多條數(shù)據(jù),有可能會(huì)降低吞吐量,以及本身下游就不支持過(guò)多的批量數(shù)據(jù),此時(shí)可以將多條數(shù)據(jù)分批并發(fā)請(qǐng)求。對(duì)于事件底層頁(yè)服務(wù)中不同組件下配置的不同文章id,會(huì)統(tǒng)一批量請(qǐng)求下游內(nèi)容服務(wù)獲取文章詳情,對(duì)于批量的條數(shù)也會(huì)做限制,防止單批數(shù)據(jù)量過(guò)大。

4.數(shù)據(jù)壓縮合并

redis的AOF重寫(xiě)是利用bgrewriteaof命令進(jìn)行AOF文件重寫(xiě),因?yàn)锳OF是追加寫(xiě)日志,對(duì)于同一個(gè)key可能存在多條修改修改命令,導(dǎo)致AOF文件過(guò)大,redis重啟后加載AOF文件會(huì)變得緩慢,導(dǎo)致啟動(dòng)時(shí)間過(guò)長(zhǎng)。可以利用重寫(xiě)命令將對(duì)于同一個(gè)key的修改只保存一條記錄,減小AOF文件體積。

大數(shù)據(jù)領(lǐng)域的Hbase、cassandra等nosql數(shù)據(jù)庫(kù)寫(xiě)入性能都很高,它們的底層存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)就是LSM樹(shù)(log structured merge tree),這種數(shù)據(jù)結(jié)構(gòu)的核心思想是追加寫(xiě),積攢一定的數(shù)據(jù)后合并成更大的segement,對(duì)于數(shù)據(jù)的刪除也只是增加一條刪除記錄。同樣對(duì)一個(gè)key的修改記錄也有多條。這種存儲(chǔ)結(jié)構(gòu)的優(yōu)點(diǎn)是寫(xiě)入性能高,但是缺點(diǎn)也比較明顯,數(shù)據(jù)存在冗余和文件體積大。主要通過(guò)線程進(jìn)行段合并將多個(gè)小文件合并成更大的文件來(lái)減少存儲(chǔ)文件體積,提升查詢(xún)效率。

對(duì)于kafka進(jìn)行傳輸數(shù)據(jù)時(shí),在生產(chǎn)者端和消費(fèi)者端可以開(kāi)啟數(shù)據(jù)壓縮。生產(chǎn)者端壓縮數(shù)據(jù)后,消費(fèi)者端收到消息會(huì)自動(dòng)解壓,可以有效減小在磁盤(pán)的存儲(chǔ)空間和網(wǎng)絡(luò)傳輸時(shí)的帶寬消耗,從而降低成本和提升傳輸效率。需要注意生產(chǎn)者端和消費(fèi)者端指定相同的壓縮算法。

在降本增效的浪潮中,降低redis成本的一種方式,就是對(duì)存儲(chǔ)到redis中的數(shù)據(jù)進(jìn)行壓縮,降低存儲(chǔ)成本,重構(gòu)后的內(nèi)容微服務(wù)通過(guò)持久化存儲(chǔ)全量數(shù)據(jù),采用snappy壓縮,壓縮后只是原來(lái)數(shù)據(jù)的40%-50%;還有一種方式是將服務(wù)之間的調(diào)用從http的json改為trpc的pb協(xié)議,因?yàn)閜b協(xié)議編碼后的數(shù)據(jù)更小,提升傳輸效率,在服務(wù)優(yōu)化時(shí),將原來(lái)請(qǐng)求tab的協(xié)議從json轉(zhuǎn)成pb,降低幾毫秒的時(shí)延,此外內(nèi)容微服務(wù)存儲(chǔ)的數(shù)據(jù)采用flutbuffer編碼,相比較于protobuffer有著更高的壓縮比跟更快的編解碼速度;對(duì)于JS/CSS多個(gè)文件下發(fā)也可以進(jìn)行混淆和壓縮傳遞;對(duì)于存儲(chǔ)在es中的數(shù)據(jù)也可以手動(dòng)調(diào)用api進(jìn)行段合并,減小存儲(chǔ)數(shù)據(jù)的體積,提高查詢(xún)速度;在我們工作中還有一個(gè)比較常見(jiàn)的問(wèn)題是接口返回的冗余數(shù)據(jù)特別多,一個(gè)接口服務(wù)下發(fā)的數(shù)據(jù)大而全,而不是對(duì)于當(dāng)前場(chǎng)景做定制化下發(fā),不滿足接口最小化原則,白白浪費(fèi)了很多帶寬資源和降低傳輸效率。

5.無(wú)鎖化

redis通過(guò)單線程避免了鎖的競(jìng)爭(zhēng),避免了線程之間頻繁切換才有這很好的讀寫(xiě)性能。

go語(yǔ)言中提供了atomic包,主要用于不同線程之間的數(shù)據(jù)同步,不需要加鎖,本質(zhì)上就是封裝了底層cpu提供的原子操作指令。此外go語(yǔ)言最開(kāi)始的調(diào)度模型時(shí)GM模型,所有的內(nèi)核級(jí)線程想要執(zhí)行g(shù)oroutine需要加鎖從全局隊(duì)列中獲取,所以不同線程之間的競(jìng)爭(zhēng)很激烈,調(diào)度效率很差。

后續(xù)引入了P(Processor),每一個(gè)M(thread)要執(zhí)行G(gorontine)的時(shí)候需要綁定一個(gè)P,其中P中會(huì)有一個(gè)待執(zhí)行G的本地隊(duì)列,只由當(dāng)前M可以進(jìn)行讀寫(xiě)(少數(shù)情況會(huì)存在偷其他協(xié)程的G),讀取P本地隊(duì)列時(shí)不需要進(jìn)行加鎖,通過(guò)降低鎖的競(jìng)爭(zhēng)大幅度提升調(diào)度G的效率。

mysql利用mvcc實(shí)現(xiàn)多個(gè)事務(wù)進(jìn)行讀寫(xiě)并發(fā)時(shí)保證數(shù)據(jù)的一致性和隔離型,也是解決讀寫(xiě)并發(fā)的一種無(wú)鎖化設(shè)計(jì)方案之一。它主要通過(guò)對(duì)每一行數(shù)據(jù)的變更記錄維護(hù)多個(gè)版本鏈來(lái)實(shí)現(xiàn)的,通過(guò)隱藏列rollptr和undolog來(lái)實(shí)現(xiàn)快照讀。在事務(wù)對(duì)某一行數(shù)據(jù)進(jìn)行操作時(shí),會(huì)根據(jù)當(dāng)前事務(wù)id以及事務(wù)隔離級(jí)別判斷讀取那個(gè)版本的數(shù)據(jù),對(duì)于可重復(fù)讀就是在事務(wù)開(kāi)始的時(shí)候生成readview,在后續(xù)整個(gè)事務(wù)期間都使用這個(gè)readview。mysql中除了使用mvcc避免互斥鎖外,bufferpool還可以設(shè)置多個(gè),通過(guò)多個(gè)bufferpool降低鎖的粒度,提升讀寫(xiě)性能,也是一種優(yōu)化方案。

日常工作 在讀多寫(xiě)少的場(chǎng)景下可以利用atomic.value存儲(chǔ)數(shù)據(jù),減少鎖的競(jìng)爭(zhēng),提升系統(tǒng)性能,例如配置服務(wù)中數(shù)據(jù)就是利用atomic.value存儲(chǔ)的;syncmap為了提升讀性能,優(yōu)先使用atomic進(jìn)行read操作,然后再進(jìn)行加互斥鎖操作進(jìn)行dirty的操作,在讀多寫(xiě)少的情況下也可以使用syncmap。

秒殺系統(tǒng)的本質(zhì)就是在高并發(fā)下準(zhǔn)確的增減商品庫(kù)存,不出現(xiàn)超賣(mài)少賣(mài)的問(wèn)題。因此所有的用戶在搶到商品時(shí)需要利用互斥鎖進(jìn)行庫(kù)存數(shù)量的變更。互斥鎖的存在必然會(huì)成為系統(tǒng)瓶頸,但是秒殺系統(tǒng)又是一個(gè)高并發(fā)的場(chǎng)景,所以如何進(jìn)行互斥鎖優(yōu)化是提高秒殺系統(tǒng)性能的一個(gè)重要優(yōu)化手段。

無(wú)鎖化設(shè)計(jì)方案之一就是利用消息隊(duì)列,對(duì)于秒殺系統(tǒng)的秒殺操作進(jìn)行異步處理,將秒殺操作發(fā)布一個(gè)消息到消息隊(duì)列中,這樣所有用戶的秒殺行為就形成了一個(gè)先進(jìn)先出的隊(duì)列,只有前面先添加到消息隊(duì)列中的用戶才能搶購(gòu)商品成功。從隊(duì)列中消費(fèi)消息進(jìn)行庫(kù)存變更的線程是個(gè)單線程,因此對(duì)于db的操作不會(huì)存在沖突,不需要加鎖操作。

另外一種優(yōu)化方式可以參考golang的GMP模型,將庫(kù)存分成多份,分別加載到服務(wù)server的本地,這樣多機(jī)之間在對(duì)庫(kù)存變更的時(shí)候就避免了鎖的競(jìng)爭(zhēng)。如果本地server是單進(jìn)程的,因此也可以形成一種無(wú)鎖化架構(gòu);如果是多進(jìn)程的,需要對(duì)本地庫(kù)存加鎖后在進(jìn)行變更,但是將庫(kù)存分散到server本地,降低了鎖的粒度,提高整個(gè)服務(wù)性能。

6.順序?qū)?/h4>

mysql的InnoDB存儲(chǔ)引擎在創(chuàng)建主鍵時(shí)通常會(huì)建議使用自增主鍵,而不是使用uuid,最主要的原因是InnoDB底層采用B+樹(shù)用來(lái)存儲(chǔ)數(shù)據(jù),每個(gè)葉子結(jié)點(diǎn)是一個(gè)數(shù)據(jù)頁(yè),存儲(chǔ)多條數(shù)據(jù)記錄,頁(yè)面內(nèi)的數(shù)據(jù)通過(guò)鏈表有序存儲(chǔ),數(shù)據(jù)頁(yè)間通過(guò)雙向鏈表存儲(chǔ)。由于uuid是無(wú)序的,有可能會(huì)插入到已經(jīng)空間不足的數(shù)據(jù)頁(yè)中間,導(dǎo)致數(shù)據(jù)頁(yè)分裂成兩個(gè)新的數(shù)據(jù)頁(yè)以便插入新數(shù)據(jù),影響整體寫(xiě)入性能。

此外mysql中的寫(xiě)入過(guò)程并不是每次將修改的數(shù)據(jù)直接寫(xiě)入到磁盤(pán)中,而是修改內(nèi)存中buffer pool內(nèi)存儲(chǔ)的數(shù)據(jù)頁(yè),將數(shù)據(jù)頁(yè)的變更記錄到undolog和binlog日志中,保證數(shù)據(jù)變更不丟失,每次記錄log都是追加寫(xiě)到日志文件尾部,順序?qū)懭氲酱疟P(pán)。對(duì)數(shù)據(jù)進(jìn)行變更時(shí)通過(guò)順序?qū)憀og,避免隨機(jī)寫(xiě)磁盤(pán)數(shù)據(jù)頁(yè),提升寫(xiě)入性能,這種將隨機(jī)寫(xiě)轉(zhuǎn)變?yōu)轫樞驅(qū)懙乃枷朐诤芏嘀虚g件中都有所體現(xiàn)。

kakfa中的每個(gè)分區(qū)是一個(gè)有序不可變的消息隊(duì)列,新的消息會(huì)不斷的添加的partition的尾部,每個(gè)partition由多個(gè)segment組成,一個(gè)segment對(duì)應(yīng)一個(gè)物理日志文件,kafka對(duì)segment日志文件的寫(xiě)入也是順序?qū)憽m樞驅(qū)懭氲暮锰幨潜苊饬舜疟P(pán)的不斷尋道和旋轉(zhuǎn)次數(shù),極大的提高了寫(xiě)入性能。

順序?qū)懼饕獣?huì)應(yīng)用在存在大量磁盤(pán)I/O操作的場(chǎng)景,日常工作中創(chuàng)建mysql表時(shí)選擇自增主鍵,或者在進(jìn)行數(shù)據(jù)庫(kù)數(shù)據(jù)同步時(shí)順序讀寫(xiě)數(shù)據(jù),避免底層頁(yè)存儲(chǔ)引擎的數(shù)據(jù)頁(yè)分裂,也會(huì)對(duì)寫(xiě)入性能有一定的提升。

7.分片化

redis對(duì)于命令的執(zhí)行過(guò)程是單線程的,單機(jī)有著很好的讀寫(xiě)性能,但是單機(jī)的機(jī)器容量跟連接數(shù)畢竟有限,因此單機(jī)redis必然會(huì)存在讀寫(xiě)上限跟存儲(chǔ)上限。redis集群的出現(xiàn)就是為了解決單機(jī)redis的讀寫(xiě)性能瓶頸問(wèn)題,redis集群是將數(shù)據(jù)自動(dòng)分片到多個(gè)節(jié)點(diǎn)上,每個(gè)節(jié)點(diǎn)負(fù)責(zé)數(shù)據(jù)的一部分,每個(gè)節(jié)點(diǎn)都可以對(duì)外提供服務(wù),突破單機(jī)redis存儲(chǔ)限制跟讀寫(xiě)上限,提高整個(gè)服務(wù)的高并發(fā)能力。除了官方推出的集群模式,代理模式codis等也是將數(shù)據(jù)分片到不同節(jié)點(diǎn),codis將多個(gè)完全獨(dú)立的redis節(jié)點(diǎn)組成集群,通過(guò)codis轉(zhuǎn)發(fā)請(qǐng)求到某一節(jié)點(diǎn),來(lái)提高服務(wù)存儲(chǔ)能力和讀寫(xiě)性能。

同樣的kafka中每個(gè)topic也支持多個(gè)partition,partition分布到多個(gè)broker上,減輕單臺(tái)機(jī)器的讀寫(xiě)壓力,通過(guò)增加partition數(shù)量可以增加消費(fèi)者并行消費(fèi)消息,提高kafka的水平擴(kuò)展能力和吞吐量。

新聞每日會(huì)生產(chǎn)大量的圖文跟視頻數(shù)據(jù),底層是通過(guò)tdsql存儲(chǔ),可以分采分片化的存儲(chǔ)思想,將圖文跟視頻或者其他介質(zhì)存儲(chǔ)到不同的數(shù)據(jù)庫(kù)或者數(shù)據(jù)表中,同一種介質(zhì)每日的生產(chǎn)量也會(huì)很大,這時(shí)候就可以對(duì)同一種介質(zhì)拆分成多個(gè)數(shù)據(jù)表,進(jìn)一步提高數(shù)據(jù)庫(kù)的存儲(chǔ)量跟吞吐量。另外一種角度去優(yōu)化存儲(chǔ)還可以將冷熱數(shù)據(jù)分離,最新的數(shù)據(jù)采用性能好的機(jī)器存儲(chǔ),之前老數(shù)據(jù)訪問(wèn)量低,采用性能差的機(jī)器存儲(chǔ),節(jié)省成本。

在微服務(wù)重構(gòu)過(guò)程中,需要進(jìn)行數(shù)據(jù)同步,將總庫(kù)中存儲(chǔ)的全量數(shù)據(jù)通過(guò)kafka同步到內(nèi)容微服務(wù)新的存儲(chǔ)中,預(yù)期同步qps高達(dá)15k。由于kafka的每個(gè)partition只能通過(guò)一個(gè)消費(fèi)者消費(fèi),要達(dá)到預(yù)期qps,因此需要?jiǎng)?chuàng)建750+partition才能夠?qū)崿F(xiàn),但是kafka的partition過(guò)多會(huì)導(dǎo)致rebalance很慢,影響服務(wù)性能,成本和可維護(hù)行都不高。采用分片化的思想,可以將同一個(gè)partition中的數(shù)據(jù),通過(guò)一個(gè)消費(fèi)者在內(nèi)存中分片到多個(gè)channel上,不同的channel對(duì)應(yīng)的獨(dú)立協(xié)程進(jìn)行消費(fèi),多協(xié)程并發(fā)處理消息提高消費(fèi)速度,消費(fèi)成功后寫(xiě)入到對(duì)應(yīng)的成功channel,由統(tǒng)一的offsetMaker線程消費(fèi)成功消息進(jìn)行offset提交,保證消息消費(fèi)的可靠性。

避免請(qǐng)求

為提升寫(xiě)入性能,mysql在寫(xiě)入數(shù)據(jù)的時(shí)候,對(duì)于在bufferpool中的數(shù)據(jù)頁(yè),直接修改bufferpool的數(shù)據(jù)頁(yè)并寫(xiě)redolog;對(duì)于不在內(nèi)存中的數(shù)據(jù)頁(yè)并不會(huì)立刻將磁盤(pán)中的數(shù)據(jù)頁(yè)加載到bufferpool中,而是僅僅將變更記錄在緩沖區(qū),等后續(xù)讀取磁盤(pán)上的數(shù)據(jù)頁(yè)到bufferpool中時(shí)會(huì)進(jìn)行數(shù)據(jù)合并,需要注意的是對(duì)于非唯一索引才會(huì)采用這種方式,對(duì)于唯一索引寫(xiě)入的時(shí)候需要每次都將磁盤(pán)上的數(shù)據(jù)讀取到bufferpool才能判斷該數(shù)據(jù)是否已存在,對(duì)于已存在的數(shù)據(jù)會(huì)返回插入失敗。

另外mysql查詢(xún)例如select * from table where name = 'xiaoming' 的查詢(xún),如果name字段存在二級(jí)索引,由于這個(gè)查詢(xún)是*,表示需要所在行的所有字段,需要進(jìn)行回表操作,如果僅需要id和name字段,可以將查詢(xún)語(yǔ)句改為select id , name from tabler where name = 'xiaoming' ,這樣只需要在name這個(gè)二級(jí)索引上就可以查到所需數(shù)據(jù),避免回表操作,減少一次I/O,提升查詢(xún)速度。

web應(yīng)用中可以使用緩存、合并css和js文件等,避免或者減少http請(qǐng)求,提升頁(yè)面加載速度跟用戶體驗(yàn)。

在日常移動(dòng)端開(kāi)發(fā)應(yīng)用中,對(duì)于多tab的數(shù)據(jù),可以采用懶加載的方式,只有用戶切換到新的tab之后才會(huì)發(fā)起請(qǐng)求,避免很多無(wú)用請(qǐng)求。服務(wù)端開(kāi)發(fā)隨著版本的迭代,有些功能字段端上已經(jīng)不展示,但是服務(wù)端依然會(huì)返回?cái)?shù)據(jù)字段,對(duì)于這些不需要的數(shù)據(jù)字段可以從數(shù)據(jù)源獲取上就做下線處理,避免無(wú)用請(qǐng)求。另外在數(shù)據(jù)獲取時(shí)可以對(duì)請(qǐng)求參數(shù)的合法性做準(zhǔn)確的校驗(yàn),例如請(qǐng)求投票信息時(shí),運(yùn)營(yíng)配置的投票ID可能是“” 或者“0”這種不合法參數(shù),如果對(duì)請(qǐng)求參數(shù)不進(jìn)行校驗(yàn),可能會(huì)存在很多無(wú)用I/O請(qǐng)求。另外在函數(shù)入口處通常會(huì)請(qǐng)求用戶的所有實(shí)驗(yàn)參數(shù),只有在實(shí)驗(yàn)期間才會(huì)用到實(shí)驗(yàn)參數(shù),在實(shí)驗(yàn)下線后并沒(méi)有下線ab實(shí)驗(yàn)平臺(tái)的請(qǐng)求,可以在非實(shí)驗(yàn)期間下線這部分請(qǐng)求,提升接口響應(yīng)速度。

8.池化

golang作為現(xiàn)代原生支持高并發(fā)的語(yǔ)言,池化技術(shù)在它的GMP模型就存在很大的應(yīng)用。對(duì)于goroutine的銷(xiāo)毀就不是用完直接銷(xiāo)毀,而是放到P的本地空閑隊(duì)列中,當(dāng)下次需要?jiǎng)?chuàng)建G的時(shí)候會(huì)從空閑隊(duì)列中直接取一個(gè)G復(fù)用即可;同樣的對(duì)于M的創(chuàng)建跟銷(xiāo)毀也是優(yōu)先從全局隊(duì)列中獲取或者釋放。此外golang中sync.pool可以用來(lái)保存被重復(fù)使用的對(duì)象,避免反復(fù)創(chuàng)建和銷(xiāo)毀對(duì)象帶來(lái)的消耗以及減輕gc壓力。

mysql等數(shù)據(jù)庫(kù)也都提供連接池,可以預(yù)先創(chuàng)建一定數(shù)量的連接用于處理數(shù)據(jù)庫(kù)請(qǐng)求。當(dāng)請(qǐng)求到來(lái)時(shí),可以從連接池中選擇空閑連接來(lái)處理請(qǐng)求,請(qǐng)求結(jié)束后將連接歸還到連接池中,避免連接創(chuàng)建和銷(xiāo)毀帶來(lái)的開(kāi)銷(xiāo),提升數(shù)據(jù)庫(kù)性能。

在日常工作中可以創(chuàng)建線程池用來(lái)處理請(qǐng)求,在請(qǐng)求到來(lái)時(shí)同樣的從鏈接池中選擇空閑的線程來(lái)處理請(qǐng)求,處理結(jié)束后歸還到線程池中,避免線程創(chuàng)建帶來(lái)的消耗,在web框架等需要高并發(fā)的場(chǎng)景下非常常見(jiàn)。

9.異步處理

異步處理在數(shù)據(jù)庫(kù)中同樣應(yīng)用廣泛,例如redis的bgsave,bgrewriteof就是分別用來(lái)異步保存RDB跟AOF文件的命令,bgsave執(zhí)行后會(huì)立刻返回成功,主線程fork出一個(gè)線程用來(lái)將內(nèi)存中數(shù)據(jù)生成快照保存到磁盤(pán),而主線程繼續(xù)執(zhí)行客戶端命令;redis刪除key的方式有del跟unlink兩種,對(duì)于del命令是同步刪除,直接釋放內(nèi)存,當(dāng)遇到大key時(shí),刪除操作會(huì)讓redis出現(xiàn)卡頓的問(wèn)題,而unlink是異步刪除的方式,執(zhí)行后對(duì)于key只做不可達(dá)的標(biāo)識(shí),對(duì)于內(nèi)存的回收由異步線程回收,不阻塞主線程。

mysql的主從同步支持異步復(fù)制、同步復(fù)制跟半同步復(fù)制。異步復(fù)制是指主庫(kù)執(zhí)行完提交的事務(wù)后立刻將結(jié)果返回給客戶端,并不關(guān)心從庫(kù)是否已經(jīng)同步了數(shù)據(jù);同步復(fù)制是指主庫(kù)執(zhí)行完提交的事務(wù),所有的從庫(kù)都執(zhí)行了該事務(wù)才將結(jié)果返回給客戶端;半同步復(fù)制指主庫(kù)執(zhí)行完后,至少一個(gè)從庫(kù)接收并執(zhí)行了事務(wù)才返回給客戶端。有多種主要是因?yàn)楫惒綇?fù)制客戶端寫(xiě)入性能高,但是存在丟數(shù)據(jù)的風(fēng)險(xiǎn),在數(shù)據(jù)一致性要求不高的場(chǎng)景下可以采用,同步方式寫(xiě)入性能差,適合在數(shù)據(jù)一致性要求高的場(chǎng)景使用。    此外對(duì)于kafka的生產(chǎn)者跟消費(fèi)者都可以采用異步的方式進(jìn)行發(fā)送跟消費(fèi)消息,但是采用異步的方式有可能會(huì)導(dǎo)致出現(xiàn)丟消息的問(wèn)題。對(duì)于異步發(fā)送消息可以采用帶有回調(diào)函數(shù)的方式,當(dāng)發(fā)送失敗后通過(guò)回調(diào)函數(shù)進(jìn)行感知,后續(xù)進(jìn)行消息補(bǔ)償。

在做服務(wù)性能優(yōu)化中,發(fā)現(xiàn)之前的一些監(jiān)控上報(bào),曝光上報(bào)等操作都在主流程中,可以將這部分功能做異步處理,降低接口的時(shí)延。此外用戶發(fā)布新聞后,會(huì)將新聞寫(xiě)入到個(gè)人頁(yè)索引,對(duì)圖片進(jìn)行加工處理,標(biāo)題進(jìn)行審核,或者給用戶增加活動(dòng)積分等操作,都可以采用異步處理,這里的異步處理是將發(fā)送消息這個(gè)動(dòng)作發(fā)送消息到消息隊(duì)列中,不同的場(chǎng)景消費(fèi)消息隊(duì)列中的消息進(jìn)行各自邏輯的處理,這種設(shè)計(jì)保證了寫(xiě)入性能,也解耦不同場(chǎng)景業(yè)務(wù)邏輯,提高系統(tǒng)可維護(hù)性。

總結(jié)

本文主要總結(jié)進(jìn)行服務(wù)性能優(yōu)化的幾種方式,每一種方式在我們常用的中間件中都有所體現(xiàn),我想這也是我們常說(shuō)多學(xué)習(xí)這些中間件的意義,學(xué)習(xí)它們不僅僅是學(xué)會(huì)如何去使用它們,也是學(xué)習(xí)它們底層優(yōu)秀的設(shè)計(jì)思想,理解為什么要這樣設(shè)計(jì),這種設(shè)計(jì)有什么好處,后續(xù)我們?cè)诩軜?gòu)選型或者做服務(wù)性能優(yōu)化時(shí)都會(huì)有一定的幫助。此外性能優(yōu)化方式也給出了具體的落地實(shí)踐,

希望通過(guò)實(shí)際的應(yīng)用例子加強(qiáng)對(duì)這種優(yōu)化方式的理解。此外要做服務(wù)性能優(yōu)化,還是要從自身服務(wù)架構(gòu)出發(fā),分析服務(wù)調(diào)用鏈耗時(shí)分布跟cpu消耗,優(yōu)化有問(wèn)題的rpc調(diào)用和函數(shù)。

責(zé)任編輯:趙寧寧 來(lái)源: 騰訊技術(shù)工程
相關(guān)推薦

2010-04-22 17:27:22

Oracle性能

2016-08-24 16:23:36

服務(wù)架構(gòu)

2021-11-29 11:13:45

服務(wù)器網(wǎng)絡(luò)性能

2022-02-16 14:10:51

服務(wù)器性能優(yōu)化Linux

2017-02-05 17:33:59

前端優(yōu)化Web性能

2011-07-03 19:58:34

SEO

2024-06-05 11:29:54

微服務(wù)監(jiān)控工具

2010-07-26 12:50:45

Perl性能

2010-07-26 16:35:34

Perl性能

2024-08-06 16:31:32

2023-11-18 19:46:07

GPU架構(gòu)

2022-09-26 09:19:38

服務(wù)器優(yōu)化

2022-05-05 09:27:31

Linux服務(wù)器優(yōu)化

2023-07-13 17:05:33

物聯(lián)網(wǎng)物聯(lián)網(wǎng)設(shè)備

2014-10-28 16:11:37

AndroidApp性能優(yōu)化

2025-02-20 09:27:46

2017-06-22 08:58:06

2009-12-22 13:25:58

WCF性能計(jì)數(shù)器內(nèi)存

2011-07-19 10:46:49

Windows 7優(yōu)化

2023-03-08 18:43:50

GPU模型隔離
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲精品自拍第一页| 99v久久综合狠狠综合久久| 亚洲最新在线视频| 9l视频白拍9色9l视频| 麻豆视频免费在线观看| 国产乱人伦偷精品视频免下载| 欧美日韩国产二区| 大黑人交xxx极品hd| 欧洲精品久久久久毛片完整版| 亚洲黄一区二区三区| 久久久久久99| 91无套直看片红桃| 亚洲国产国产亚洲一二三| 亚洲午夜女主播在线直播| 91免费视频污| 欧美成a人片在线观看久| 亚洲另类色综合网站| 久久综合九色欧美狠狠| av小说天堂网| 久热精品在线| 久久精品视频在线播放| 麻豆精品免费视频| 综合欧美亚洲| 欧美色欧美亚洲另类二区| 91精品国产91久久久久麻豆 主演| 男人天堂资源在线| 成人免费视频国产在线观看| 国产日韩亚洲欧美| 男人天堂2024| 在线免费观看欧美| 欧美另类99xxxxx| 后入内射无码人妻一区| 久久精品色综合| 日韩一区二区三区在线视频| 午夜视频你懂的| 欧美sm一区| 亚洲综合丝袜美腿| 欧洲xxxxx| 东凛在线观看| 久久综合五月天婷婷伊人| 99在线视频播放| 国产精品久久久午夜夜伦鲁鲁| 日日欢夜夜爽一区| 91高清免费视频| 国产精品第一页在线观看| 一本一道久久综合狠狠老| 中文日韩在线观看| 黄色片网站免费| 一区三区在线欧| 日韩精品视频免费| 7788色淫网站小说| av自拍一区| 精品国产凹凸成av人网站| 99久久99精品| 国产在线不卡一区二区三区| 777色狠狠一区二区三区| 亚洲欧美日韩三级| 欧洲亚洲精品久久久久| 精品视频在线视频| 日韩大片一区二区| 日韩毛片免费视频一级特黄| 欧美日韩1区2区| 成人免费在线观看视频网站| 国产福利亚洲| 91精品国产高清一区二区三区蜜臀| 国产喷水theporn| 亚洲怡红院av| 麻豆亚洲精品| 国产91精品在线播放| 秋霞av一区二区三区| 久久亚洲美女| 国产精品无av码在线观看| 在线观看毛片视频| 国产一区在线看| 99精彩视频| 午夜视频福利在线观看| 久久久久久久免费视频了| 日韩一本精品| 黄色免费在线看| 一区二区在线观看av| 亚洲 欧美 综合 另类 中字| 欧美aa一级| 欧美日韩在线精品一区二区三区激情| 高清一区在线观看| 精品三级久久久| 亚洲国产欧美一区二区丝袜黑人| 中文文字幕文字幕高清| 国产精选一区| 久久精品精品电影网| 久久久久久久久久久久久久免费看| 亚洲国产日本| 国产精品久久久久久中文字 | 亚洲日本在线天堂| 蜜臀av色欲a片无码精品一区| 国产网站在线| 欧美日本一区二区在线观看| 乱码一区二区三区| 欧洲三级视频| 欧美国产日韩一区二区三区| √资源天堂中文在线| 久久99久国产精品黄毛片色诱| 国产高清精品一区二区| 高清国产福利在线观看| 一区二区三区鲁丝不卡| 成人精品小视频| 欧美二区观看| 在线观看欧美www| 久久成人在线观看| 老司机精品视频导航| 国产精品视频福利| 欧美激情办公室videoshd| 婷婷开心激情综合| 一级做a免费视频| 日韩mv欧美mv国产网站| 美女久久久久久久久久久| 国产三级精品三级在线观看| 国产精品99精品久久免费| 欧美亚洲免费高清在线观看| gogo在线高清视频| 欧美色图一区二区三区| 欧美做受喷浆在线观看| 在线精品国产| 国产精品欧美久久久| 亚州精品国产精品乱码不99按摩| 亚洲美女偷拍久久| 超碰在线97免费| 美女少妇全过程你懂的久久| 欧美激情影音先锋| www.激情五月| 综合婷婷亚洲小说| 男操女免费网站| 免费精品国产的网站免费观看| 欧美激情亚洲另类| 国产成人精品一区二三区四区五区 | 三级在线免费看| 欧美日韩大片免费观看| 久久99国产综合精品女同| 91肉色超薄丝袜脚交一区二区| 国产区在线观看成人精品| 欧美在线观看www| 国产乱人伦精品一区| 欧美理论电影在线播放| 国产色综合视频| 亚洲欧美一区二区视频| 国产91色在线观看| 国内黄色精品| 国产高清视频一区三区| 可以免费看污视频的网站在线| 精品国产福利在线| 成人手机在线免费视频| 在线不卡欧美| 久久久综合亚洲91久久98| 丁香花视频在线观看| 欧美不卡在线视频| 国产一卡二卡在线播放| av在线不卡电影| av免费观看网| 综合综合综合综合综合网| 欧美在线国产精品| 欧美日韩国产亚洲沙发| 91久久一区二区| 青青青视频在线播放| 麻豆精品在线观看| 最新av在线免费观看| 国产日本亚洲| 久久久亚洲影院| 日韩美女一级视频| 在线观看中文字幕不卡| youjizz亚洲女人| 韩日精品视频一区| 香港三级日本三级a视频| 欧美xxxx在线| 日本精品在线视频| 日本三级视频在线观看| 日韩亚洲欧美综合| 国产成人亚洲欧洲在线| 国产午夜精品一区二区三区视频| 特级丰满少妇一级| 66国产精品| 国产精品免费一区二区三区在线观看| 川上优av中文字幕一区二区| 亚洲天堂影视av| 97人妻精品一区二区三区| 亚洲一区二区三区在线| 丰满少妇在线观看资源站| 日韩影院精彩在线| 黄色一级视频播放| 日韩深夜福利| 国产欧美精品一区二区| 不卡的av影片| 一区二区三区美女xx视频| 国产日韩欧美视频在线观看| 午夜电影网亚洲视频| 女人十八毛片嫩草av| 国产盗摄精品一区二区三区在线| 中国丰满人妻videoshd| 99精品视频在线观看播放| 国产私拍一区| 图片一区二区| 久久久久久伊人| 91高清在线| 亚洲成人激情图| 中文字幕一区二区人妻| 亚洲午夜久久久久中文字幕久| 精品无码在线观看| 成人午夜私人影院| 五月天激情播播| 国产精品五区| 特大黑人娇小亚洲女mp4| 国产精品一区二区av交换| 国产精品国产亚洲精品看不卡15| 成人国产精选| 2025国产精品视频| 色婷婷在线播放| 中文字幕亚洲欧美| 日本韩国一区| 精品播放一区二区| 国产永久免费视频| 91成人看片片| 天天爽夜夜爽夜夜爽精品| 亚洲激情成人在线| 国产一区二区精彩视频| 久久九九全国免费| 97香蕉碰碰人妻国产欧美| 国产美女主播视频一区| 亚洲77777| 日韩经典一区二区| 日韩人妻精品无码一区二区三区| 欧美午夜在线| 300部国产真实乱| 五月天久久网站| 亚洲欧美日韩精品久久久| 亚洲春色h网| 精品一区在线播放| 黑色丝袜福利片av久久| 99九九电视剧免费观看| 4438五月综合| 成人免费视频a| 成人国产激情| 国产精品av在线| 韩国成人在线| 国产精品久久一| 成人精品高清在线视频| 国产精品露脸自拍| 在线观看精品| 国产精品久久久久久久久久小说 | 亚洲成人精品影院| 久久久久久久9999| 亚洲综合一区二区| 国产大片中文字幕在线观看| 亚洲综合色噜噜狠狠| 精品无码免费视频| 亚洲自拍偷拍九九九| 久久久久久福利| 午夜精品福利一区二区三区av| 久久亚洲成人av| 亚洲国产精品久久艾草纯爱| 国产精品二区一区二区aⅴ| 亚洲国产精品嫩草影院| 少妇一级淫片免费放中国| 色老汉一区二区三区| 中文字幕乱伦视频| 欧美久久久久免费| 99久久久久久久| 精品国产一二三区| 青青草视频免费在线观看| 亚洲人成77777在线观看网| 高清日韩av电影| 久久久成人的性感天堂| 男女视频在线| 欧美在线亚洲一区| 久久av日韩| 国产精品成人一区二区三区| 色婷婷综合久久久久久| 色视频一区二区三区| 日本久久黄色| 日本老太婆做爰视频| 亚洲激情二区| 青青青在线视频免费观看| 久久99日本精品| yjizz视频| 久久综合色8888| 久久久久久久久久97| 亚洲成av人片在www色猫咪| 国产精品久久久久久久妇| 欧美色图免费看| 六月婷婷综合网| 亚洲天堂av在线免费| 在线你懂的视频| 欧美一区二三区| 日韩在线电影| 精品一区二区不卡| 天天超碰亚洲| 欧美精品99久久| 狠狠色狠狠色综合系列| 精品人妻一区二区免费| 国产拍欧美日韩视频二区| 国产十六处破外女视频| 91传媒视频在线播放| 国产精品老熟女视频一区二区| 精品乱人伦小说| 爱爱爱免费视频在线观看| 欧美极品美女视频网站在线观看免费| 毛片无码国产| 春色成人在线视频| 日韩欧美网址| 日本黄色三级大片| 国产成人精品免费| 手机看片日韩av| 精品美女国产在线| 精品人妻一区二区三区蜜桃 | 成人黄色网址| 国产成人欧美在线观看| 盗摄牛牛av影视一区二区| 一区二区三区四区国产| 天堂蜜桃91精品| 国产高清成人久久| 亚洲精品国产一区二区精华液 | 日韩成人免费电影| 国产精品一区二区人妻喷水| 亚洲欧美视频在线观看视频| 国产男人搡女人免费视频| 日韩av在线最新| 亚洲小说区图片区都市| 国产日韩精品入口| 不卡在线一区| 日韩精品一区二区三区不卡 | 国产精品免费在线| 中文字幕日韩欧美精品高清在线| 国产又大又黄又粗又爽| 欧美高清在线一区| www.色国产| 日韩av在线一区| 亚洲精华液一区二区三区| 国产在线一区二区三区欧美| 伊人天天综合| 性高潮免费视频| 亚洲在线免费播放| www.激情五月| 欧美激情图片区| 国产一区丝袜| 欧美又粗又长又爽做受| 岛国一区二区在线观看| 久操视频免费在线观看| 欧美成人vr18sexvr| 污污网站在线观看| 成人三级视频在线观看| 91久色porny| 日本网站在线播放| 欧美zozo另类异族| 青草在线视频在线观看| 成人黄动漫网站免费| 正在播放日韩欧美一页| 无套白嫩进入乌克兰美女| 国产精品理伦片| 国产视频www| 久久999免费视频| 国产丝袜一区| 中文字幕一区二区三区不卡在线| 四虎成人精品永久免费av| 亚洲国产成人在线播放| 在线观看网站免费入口在线观看国内| 六月婷婷久久| 老牛嫩草一区二区三区日本 | 国产a精品视频| 在线看成人av| 亚洲老司机av| 福利一区和二区| 三级网在线观看| 成人禁用看黄a在线| 91video| 国产亚洲欧美日韩一区二区| 久久久久伊人| www插插插无码免费视频网站| 不卡高清视频专区| 青青国产在线视频| 久久视频中文字幕| 国产+成+人+亚洲欧洲在线| 国产成人无码一二三区视频| 国产精品视频你懂的| 性少妇videosexfreexxx片| 国内精品美女av在线播放| 岳的好大精品一区二区三区| 成 人 黄 色 小说网站 s色| 亚洲国产精品人人做人人爽| 欧美日韩视频精品二区| 亚洲va久久久噜噜噜久久天堂| 日韩一区二区久久| 五月婷婷六月香| 亚洲国内精品在线| 久久亚洲资源中文字| 大陆av在线播放| 欧美国产日本视频| 黄色av小说在线观看| 国产精品日韩欧美综合| 欧美午夜久久| 国产福利在线导航| 亚洲精品成人av| 青娱乐极品盛宴一区二区| 日本国产在线播放|