自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

天天說(shuō)要做性能優(yōu)化,到底在優(yōu)化什么?

開(kāi)發(fā) 前端
連環(huán)炮問(wèn)下來(lái),對(duì)于有做過(guò)優(yōu)化的老司機(jī)來(lái)說(shuō),肯定能抗住。對(duì)于沒(méi)有真正做過(guò)優(yōu)化的小白來(lái)說(shuō),肯定扛不住這一系列的追問(wèn),最后只能以面試失敗而告終。

[[349912]]

 本文轉(zhuǎn)載自微信公眾號(hào)「猿天地」,作者尹吉?dú)g  。轉(zhuǎn)載本文請(qǐng)聯(lián)系猿天地公眾號(hào)。 

面試過(guò)程中經(jīng)常被問(wèn)到:

  • 你做過(guò)性能優(yōu)化嗎?
  • 優(yōu)化了哪些方面?
  • 怎么做優(yōu)化的?
  • 優(yōu)化的效果如何?

連環(huán)炮問(wèn)下來(lái),對(duì)于有做過(guò)優(yōu)化的老司機(jī)來(lái)說(shuō),肯定能抗住。對(duì)于沒(méi)有真正做過(guò)優(yōu)化的小白來(lái)說(shuō),肯定扛不住這一系列的追問(wèn),最后只能以面試失敗而告終。

那么性能優(yōu)化到底在優(yōu)化什么呢?我們來(lái)盤(pán)點(diǎn)下一些常用的優(yōu)化手段。

SQL 優(yōu)化

當(dāng)你開(kāi)發(fā)的接口響應(yīng)時(shí)間超過(guò)了 200ms 的時(shí)候就得優(yōu)化了,當(dāng)然 200ms 不是絕對(duì)值,具體還是看應(yīng)用場(chǎng)景。以 App 舉例,進(jìn)一個(gè)頁(yè)面調(diào)用 5 個(gè)接口(題外話:也可以做聚合),那么總共就是 1s 的時(shí)間,對(duì)用戶來(lái)說(shuō)體驗(yàn)還算可以,當(dāng)然是越快響應(yīng)越好。

接口耗時(shí) 200ms,其中占大頭的還是對(duì)數(shù)據(jù)庫(kù)的操作,一個(gè)接口中會(huì)有 N 次數(shù)據(jù)庫(kù)操作。所以?xún)?yōu)化 SQL 的速度優(yōu)先級(jí)是最高的,大量的慢 SQL 會(huì)拖垮整個(gè)系統(tǒng)。

關(guān)于 SQL 的優(yōu)化不是本文的重點(diǎn),大部分慢 SQL 還是跟各位平時(shí)開(kāi)發(fā)時(shí)的習(xí)慣有關(guān)系。大部分在寫(xiě) SQL 的時(shí)候不太會(huì)去考慮性能,只要寫(xiě)出來(lái)就可以了,join 隨手就來(lái),也不梳理查詢(xún)字段,不加索引,剛開(kāi)始上線沒(méi)問(wèn)題,等到并發(fā)量,數(shù)據(jù)量起來(lái)的時(shí)候就涼涼了。

關(guān)于數(shù)據(jù)庫(kù)的使用規(guī)范大家可以參考下這篇文章:老大讓我整理下公司內(nèi)部mysql使用規(guī)范,分享給大家

當(dāng)數(shù)據(jù)量大了后肯定要做讀寫(xiě)分離和分庫(kù)分表的,這也是優(yōu)化的必經(jīng)之路。

  • 讀寫(xiě)分離
  • 分庫(kù)分表

減少重復(fù)調(diào)用

性能不好的另一個(gè)致命問(wèn)題就是重復(fù)調(diào)用,相同的邏輯在不同的方法中重復(fù)對(duì)數(shù)據(jù)庫(kù)查詢(xún),重復(fù)調(diào)用 RPC 服務(wù)等。

比如下面的代碼:

  1. skuDao.querySkus(productId).stream().map(sku -> { 
  2.    skuDao.getById(sku.getId()); 
  3. }) 

明明數(shù)據(jù)已經(jīng)查詢(xún)出來(lái)了,又根據(jù) ID 重新去查詢(xún)了一次,數(shù)量越多,浪費(fèi)的時(shí)間越多。這里只是舉例,我相信在真實(shí)的項(xiàng)目中大量存在重復(fù)查詢(xún)的情況,之前我還寫(xiě)過(guò)一篇文章,講解如何解決這種重復(fù)查詢(xún)問(wèn)題,感興趣的可以查看這篇文章:簡(jiǎn)直騷操作,ThreadLocal還能當(dāng)緩存用

按需查詢(xún)

很多業(yè)務(wù)邏輯不復(fù)雜的功能,卻響應(yīng)很慢。往往都是寫(xiě)代碼的時(shí)候沒(méi)有思考,隨便就調(diào)用一些已經(jīng)存在的方法,導(dǎo)致整體響應(yīng)變慢,總結(jié)起來(lái)就是:性能問(wèn)題大部分都是代碼寫(xiě)出來(lái)的。

說(shuō)個(gè)場(chǎng)景,大家肯定都見(jiàn)到過(guò)。參數(shù)是一個(gè)商品 ID, 功能是上架商品,需要進(jìn)行狀態(tài)的判斷,符合條件才能上架。這個(gè)場(chǎng)景下只需要獲取商品的狀態(tài)進(jìn)行判斷即可,有的時(shí)候你看到的代碼往往都是下面的方式:

  1. GoodsDetail goods = goodsService.detail(id); 
  2. if (goods.getStatus() == GoodsStatusEnum.XXXX) { 
  3.  

detail 中有大量的邏輯,除了基本的商品信息,還有很多其他的內(nèi)容,這就是慢的原因。

并行調(diào)用

針對(duì)一個(gè)接口,如果設(shè)計(jì)到多個(gè)內(nèi)部 RPC 服務(wù)或者多個(gè)外部接口,在接口之間沒(méi)有關(guān)聯(lián)關(guān)系的情況下,我們可以采用并行調(diào)用的方式來(lái)提高性能。

CompletableFuture 就非常適合并行調(diào)用的場(chǎng)景,關(guān)于 CompletableFuture 的使用本文不做詳細(xì)說(shuō)明,做 Java 的都要會(huì)用。

除了 CompletableFuture 之外,對(duì)于集合類(lèi)的處理,可以用 parallelStream 來(lái)實(shí)現(xiàn)并行調(diào)用。

在微服務(wù)中有一層專(zhuān)門(mén)用于聚合 API, 聚合層就非常適合并行調(diào)用,一個(gè)功能或者一個(gè)頁(yè)面展示會(huì)涉及到多個(gè)接口,通過(guò)聚合層在后端進(jìn)行接口的聚合和數(shù)據(jù)的裁剪,一起響應(yīng)給前端。

上緩存

緩存也是優(yōu)化中最常用的,效果提升最明顯的,成本也不大。對(duì)于緩存,也不要濫用,不是所有場(chǎng)景都可以靠堆緩存來(lái)提高性能的。

首先對(duì)于實(shí)時(shí)性要求不高的業(yè)務(wù)場(chǎng)景可以?xún)?yōu)先使用緩存,也不用太考慮更新的問(wèn)題,自然過(guò)期就行。

實(shí)時(shí)性要求高的業(yè)務(wù)場(chǎng)景,用緩存一定要有完整的緩存更新機(jī)制,否則很容易造成業(yè)務(wù)數(shù)據(jù)和緩存數(shù)據(jù)不一致的情況。

建議的做法是訂閱 binlog 來(lái)統(tǒng)一更新緩存,不要在代碼中去更新或者失效緩存,簡(jiǎn)單的場(chǎng)景還好,入口就那幾個(gè),問(wèn)題不大。有些數(shù)據(jù)在多個(gè)場(chǎng)景下使用,需要更新的入口太多了,

異步處理

有些邏輯,不需要實(shí)時(shí)反饋給用戶那就可以采用異步的方式在后臺(tái)進(jìn)行處理。

異步處理的方式最常見(jiàn)的就是將任務(wù)加到線程池中進(jìn)行處理,線程池需要考慮容量以及對(duì)一些指標(biāo)的監(jiān)控,相關(guān)的文章可以查看我的這篇:一時(shí)技癢,擼了個(gè)動(dòng)態(tài)線程池,源碼放Github了

除了一些指標(biāo)的監(jiān)控,線程池的使用另一個(gè)需要關(guān)注的問(wèn)題就是任務(wù)的持久化。如果你的數(shù)據(jù)本來(lái)就是存儲(chǔ)好了的,然后讀取出來(lái)通過(guò)線程池去執(zhí)行是沒(méi)問(wèn)題的。如果是沒(méi)有持久化直接丟入線程池中進(jìn)行執(zhí)行,就有可能出現(xiàn)丟失的情況,比如服務(wù)重啟之類(lèi)的場(chǎng)景。

關(guān)于持久化,無(wú)論是線程池還是 EventBus 這種,都會(huì)遇到,所以針對(duì)異步的場(chǎng)景我建議大家使用消息隊(duì)列比較好。

消息隊(duì)列可以存儲(chǔ)任務(wù)信息,保證不會(huì)丟失。單獨(dú)消費(fèi)隊(duì)列的消息進(jìn)行邏輯處理,如果想提高消費(fèi)速度,也可以在隊(duì)列的消費(fèi)方使用線程池進(jìn)行多線程消費(fèi),多線程消費(fèi)也要避免消息丟失的情況,可以查看我的這篇文章:噓!異步事件這樣用真的好么?

JVM 參數(shù)調(diào)整

JVM 參數(shù)的調(diào)整,一般情況下我們都不用怎么去調(diào)整。偶爾有些代碼寫(xiě)的不好,導(dǎo)致內(nèi)存溢出了,這個(gè)時(shí)候會(huì)去做一些調(diào)整和優(yōu)化代碼。

參數(shù)調(diào)整主要是去降低 GC 的導(dǎo)致的停頓問(wèn)題,如果你的程序一直在 GC, 一直在停頓,你的接口自然就慢了。

只要沒(méi)有頻繁的 Full GC,在優(yōu)化這塊 JVM 的參數(shù)調(diào)整可以最后再做,優(yōu)先以 SQL 優(yōu)化這些為主。

加機(jī)器

加機(jī)器是最后的終極大招了,并發(fā)量上去的時(shí)候,你在怎么優(yōu)化單機(jī)器和單數(shù)據(jù)庫(kù)抗并發(fā)能力也是有限的,這個(gè)時(shí)候只能水平擴(kuò)展了。

如果是創(chuàng)業(yè)初期,并且在快速發(fā)展,加機(jī)器是最直接的優(yōu)化方式了,雖然說(shuō)成本上去了,但是開(kāi)發(fā)資源也是成本,節(jié)約下來(lái)可以實(shí)現(xiàn)更多的業(yè)務(wù)需求。等到中期穩(wěn)定了再考慮架構(gòu),性能方面整體的優(yōu)化和重構(gòu)。

就像玩游戲一樣,有裝備的玩家才能所向睥睨啊,對(duì)于后端應(yīng)用來(lái)說(shuō)也是一樣,高配的機(jī)器,高配的數(shù)據(jù)庫(kù)配置,高配的緩存等。

關(guān)于作者:尹吉?dú)g,簡(jiǎn)單的技術(shù)愛(ài)好者,《Spring Cloud 微服務(wù)-全棧技術(shù)與案例解析》, 《Spring Cloud 微服務(wù) 入門(mén) 實(shí)戰(zhàn)與進(jìn)階》作者, 公眾號(hào)猿天地發(fā)起人。

原文鏈接:http://cxytiandi.com/blog/user/1

 

責(zé)任編輯:武曉燕 來(lái)源: 猿天地
相關(guān)推薦

2020-03-09 16:43:06

腳本語(yǔ)言瀏覽器JavaScript

2022-08-22 09:25:47

分布式系統(tǒng)單塊系統(tǒng)

2018-03-21 15:02:23

數(shù)據(jù)庫(kù)MySQL分頁(yè)優(yōu)化

2019-07-17 10:10:34

Netty版本Event

2023-06-11 17:02:24

數(shù)字化轉(zhuǎn)型數(shù)字經(jīng)濟(jì)

2019-05-28 09:19:57

5G華為美國(guó)

2021-01-21 10:28:16

自然語(yǔ)言NLP人工智能

2014-12-10 10:12:02

Web

2021-04-19 10:08:48

優(yōu)化CSS性能

2020-10-29 11:08:06

CPUMySQL數(shù)據(jù)庫(kù)

2020-10-19 19:45:58

MySQL數(shù)據(jù)庫(kù)優(yōu)化

2014-07-08 12:29:43

錘子手機(jī)

2021-07-29 14:20:34

網(wǎng)絡(luò)優(yōu)化移動(dòng)互聯(lián)網(wǎng)數(shù)據(jù)存儲(chǔ)

2020-10-30 12:40:04

Reac性能優(yōu)化

2016-04-05 10:21:25

大數(shù)據(jù)元數(shù)據(jù)數(shù)據(jù)分析

2021-03-16 22:47:42

數(shù)據(jù)分析大數(shù)據(jù)崗位

2009-09-08 09:45:23

App Engine性

2022-02-16 14:10:51

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

2021-11-29 11:13:45

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

2017-08-08 09:45:43

Python性能優(yōu)化
點(diǎn)贊
收藏

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