最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 淺談 高并發(fā) 處理方案詳解

 更新時間:2021年09月29日 16:02:20   作者:看,未來  
這篇文章主要介紹了淺談Java高并發(fā)解決方案以及高負(fù)載優(yōu)化方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

高性能開發(fā)十大必須掌握的核心技術(shù)

我們循序漸進(jìn),從內(nèi)存、磁盤I/O、網(wǎng)絡(luò)I/O、CPU、緩存、架構(gòu)、算法等多層次遞進(jìn),串聯(lián)起高性能開發(fā)十大必須掌握的核心技術(shù)。

- I/O優(yōu)化:零拷貝技術(shù)
- I/O優(yōu)化:多路復(fù)用技術(shù)
- 線程池技術(shù)
- 無鎖編程技術(shù)
- 進(jìn)程間通信技術(shù)
- RPC && 序列化技術(shù)
- 數(shù)據(jù)庫索引技術(shù)
- 緩存技術(shù) && 布隆過濾器
- 全文搜索技術(shù)
- 負(fù)載均衡技術(shù)

I/O優(yōu)化:零拷貝技術(shù)

從磁盤讀文件、再通過網(wǎng)絡(luò)發(fā)送數(shù)據(jù),數(shù)據(jù)從磁盤到網(wǎng)絡(luò),兜兜轉(zhuǎn)轉(zhuǎn)需要拷貝四次,其中CPU親自搬運都需要兩次。

最近在學(xué)習(xí)nginx的底層設(shè)計,正好有看到這個。后面可以在nginx系列里面補上這個。

在這里插入圖片描述

零拷貝技術(shù),解放CPU,文件數(shù)據(jù)直接從內(nèi)核發(fā)送出去,無需再拷貝到應(yīng)用程序緩沖區(qū),白白浪費資源。

在這里插入圖片描述

Linux API:

ssize_t sendfile(
  int out_fd, 
  int in_fd, 
  off_t *offset, 
  size_t count
);

函數(shù)名字已經(jīng)把函數(shù)的功能解釋的很明顯了:發(fā)送文件。指定要發(fā)送的文件描述符和網(wǎng)絡(luò)套接字描述符,一個函數(shù)搞定!

I/O優(yōu)化:多路復(fù)用技術(shù)

每個線程都要阻塞在recv等待對方的請求,這來訪問的人多了,線程開的就多了,大量線程都在阻塞,系統(tǒng)運轉(zhuǎn)速度也隨之下降。

這個時候,你需要多路復(fù)用技術(shù),使用select模型,將所有等待(accept、recv)都放在主線程里,工作線程不需要再等待。

在這里插入圖片描述

過了一段時間之后,網(wǎng)站訪問的人越來越多了,就連select也開始有點應(yīng)接不暇,老板繼續(xù)讓你優(yōu)化性能。

這個時候,你需要升級多路復(fù)用模型為epoll。

select有三弊,epoll有三優(yōu)。

select底層采用數(shù)組來管理套接字描述符,同時管理的數(shù)量有上限,一般不超過幾千個,epoll使用樹和鏈表來管理,同時管理數(shù)量可以很大。
select不會告訴你到底哪個套接字來了消息,你需要一個個去詢問。epoll直接告訴你誰來了消息,不用輪詢。
select進(jìn)行系統(tǒng)調(diào)用時還需要把套接字列表在用戶空間和內(nèi)核空間來回拷貝,循環(huán)中調(diào)用select時簡直浪費。epoll統(tǒng)一在內(nèi)核管理套接字描述符,無需來回拷貝。

用上了epoll多路復(fù)用技術(shù),開發(fā)了3.0版本,你的網(wǎng)站能同時處理很多用戶請求了。

之前的方案中,工作線程總是用到才創(chuàng)建,用完就關(guān)閉,大量請求來的時候,線程不斷創(chuàng)建、關(guān)閉、創(chuàng)建、關(guān)閉,開銷挺大的。這個時候,你需要:

線程池技術(shù)

我們可以在程序一開始啟動后就批量啟動一波工作線程,而不是在有請求來的時候才去創(chuàng)建,使用一個公共的任務(wù)隊列,請求來臨時,向隊列中投遞任務(wù),各個工作線程統(tǒng)一從隊列中不斷取出任務(wù)來處理,這就是線程池技術(shù)。

在這里插入圖片描述

多線程技術(shù)的使用一定程度提升了服務(wù)器的并發(fā)能力,但同時,多個線程之間為了數(shù)據(jù)同步,常常需要使用互斥體、信號、條件變量等手段來同步多個線程。這些重量級的同步手段往往會導(dǎo)致線程在用戶態(tài)/內(nèi)核態(tài)多次切換,系統(tǒng)調(diào)用,線程切換都是不小的開銷。

在線程池技術(shù)中,提到了一個公共的任務(wù)隊列,各個工作線程需要從中提取任務(wù)進(jìn)行處理,這里就涉及到多個工作線程對這個公共隊列的同步操作。

有沒有一些輕量級的方案來實現(xiàn)多線程安全的訪問數(shù)據(jù)呢?這個時候,你需要:

無鎖編程技術(shù)

多線程并發(fā)編程中,遇到公共數(shù)據(jù)時就需要進(jìn)行線程同步。而這里的同步又可以分為阻塞型同步和非阻塞型同步。

阻塞型同步好理解,我們常用的互斥體、信號、條件變量等這些操作系統(tǒng)提供的機制都屬于阻塞型同步,其本質(zhì)都是要加“鎖”。

在這里插入圖片描述

與之對應(yīng)的非阻塞型同步就是在無鎖的情況下實現(xiàn)同步,目前有三類技術(shù)方案:

Wait-freeLock-freeObstruction-free

三類技術(shù)方案都是通過一定的算法和技術(shù)手段來實現(xiàn)不用阻塞等待而實現(xiàn)同步,這其中又以Lock-free最為應(yīng)用廣泛。

Lock-free能夠廣泛應(yīng)用得益于目前主流的CPU都提供了原子級別的read-modify-write原語,這就是著名的CAS(Compare-And-Swap)操作。在Intel x86系列處理器上,就是cmpxchg系列指令。

我們常常見到的無鎖隊列、無鎖鏈表、無鎖HashMap等數(shù)據(jù)結(jié)構(gòu),其無鎖的核心大都來源于此。在日常開發(fā)中,恰當(dāng)?shù)倪\用無鎖化編程技術(shù),可以有效地降低多線程阻塞和切換帶來的額外開銷,提升性能。


服務(wù)器上線了一段時間,發(fā)現(xiàn)服務(wù)經(jīng)常崩潰異常,排查發(fā)現(xiàn)是工作線程代碼bug,一崩潰整個服務(wù)都不可用了。于是你決定把工作線程和主線程拆開到不同的進(jìn)程中,工作線程崩潰不能影響整體的服務(wù)。這個時候出現(xiàn)了多進(jìn)程,你需要:

進(jìn)程間通信技術(shù)

提起進(jìn)程間通信,你能想到的是什么?

管道
命名管道
socket
消息隊列
信號
信號量
共享內(nèi)存

以上各種進(jìn)程間通信的方式詳細(xì)介紹和比較,推薦一篇文章再探進(jìn)程間通信,這里不再贅述。

Scale-out(橫向拓展)

采用分布式部署的方式把流量分開,讓每個服務(wù)器都承擔(dān)一部分并發(fā)和流量。這也是我最喜歡的一種方法。

緩存

使用緩存來提高系統(tǒng)的性能。

為什么緩存可以大幅度提升系統(tǒng)的性能呢?

那肯定是要更普通磁盤進(jìn)行對比的啊。我們來看看普通磁盤的速度:
普通磁盤的尋道時間是 10ms 左右,而相比于磁盤尋道花費的時間,CPU 執(zhí)行指令和內(nèi)存尋址的時間都在是 ns(納秒)級別,從千兆網(wǎng)卡上讀取數(shù)據(jù)的時間是在μs(微秒)級別。所以在整個計算機體系中,磁盤是最慢的一環(huán),甚至比其它的組件要慢幾個數(shù)量級。因此,我們通常使用以內(nèi)存作為存儲介質(zhì)的緩存,以此提升性能。

至于緩存為什么快,因為它是內(nèi)置的啊,在內(nèi)存中。不過也有個缺點,就是燒內(nèi)存。

異步

在這里插入圖片描述

這是業(yè)務(wù)層面的異步。

內(nèi)核層面的異步,需要調(diào)用內(nèi)核指定的異步函數(shù)(aio族),不然,不論阻塞還是非阻塞都是同步。

高性能、高可用、高拓展 解決方案

以下實踐方案,有些我已經(jīng)試過了,有些還沒體驗但是知道那么一回事兒,有些則不知道啥時候能實踐了。

高性能的實踐方案

1、集群部署,通過負(fù)載均衡減輕單機壓力。
2、多級緩存,包括靜態(tài)數(shù)據(jù)使用CDN、本地緩存、分布式緩存等,以及對緩存場景中的熱點key、緩存穿透、緩存并發(fā)、數(shù)據(jù)一致性等問題的處理。
3、分庫分表和索引優(yōu)化,以及借助搜索引擎解決復(fù)雜查詢問題。
4、考慮NoSQL數(shù)據(jù)庫的使用,比如HBase、TiDB等,但是團(tuán)隊必須熟悉這些組件,且有較強的運維能力。
5、異步化,將次要流程通過多線程、MQ、甚至延時任務(wù)進(jìn)行異步處理。
6、限流,需要先考慮業(yè)務(wù)是否允許限流(比如秒殺場景是允許的),包括前端限流、Nginx接入層的限流、服務(wù)端的限流。
7、對流量進(jìn)行削峰填谷,通過MQ承接流量。
8、并發(fā)處理,通過多線程將串行邏輯并行化。
9、預(yù)計算,比如搶紅包場景,可以提前計算好紅包金額緩存起來,發(fā)紅包時直接使用即可。
10、緩存預(yù)熱,通過異步任務(wù)提前預(yù)熱數(shù)據(jù)到本地緩存或者分布式緩存中。
11、減少IO次數(shù),比如數(shù)據(jù)庫和緩存的批量讀寫、RPC的批量接口支持、或者通過冗余數(shù)據(jù)的方式干掉RPC調(diào)用。
12、減少IO時的數(shù)據(jù)包大小,包括采用輕量級的通信協(xié)議、合適的數(shù)據(jù)結(jié)構(gòu)、去掉接口中的多余字段、減少緩存key的大小、壓縮緩存value等。
13、程序邏輯優(yōu)化,比如將大概率阻斷執(zhí)行流程的判斷邏輯前置、For循環(huán)的計算邏輯優(yōu)化,或者采用更高效的算法。
14、各種池化技術(shù)的使用和池大小的設(shè)置,包括HTTP請求池、線程池(考慮CPU密集型還是IO密集型設(shè)置核心參數(shù))、數(shù)據(jù)庫和Redis連接池等。
15、JVM優(yōu)化,包括新生代和老年代的大小、GC算法的選擇等,盡可能減少GC頻率和耗時。
16、鎖選擇,讀多寫少的場景用樂觀鎖,或者考慮通過分段鎖的方式減少鎖沖突。

上述方案無外乎從計算和 IO 兩個維度考慮所有可能的優(yōu)化點,需要有配套的監(jiān)控系統(tǒng)實時了解當(dāng)前的性能表現(xiàn),并支撐你進(jìn)行性能瓶頸分析,然后再遵循二八原則,抓主要矛盾進(jìn)行優(yōu)化。

高可用的實踐方案

1、對等節(jié)點的故障轉(zhuǎn)移,Nginx和服務(wù)治理框架均支持一個節(jié)點失敗后訪問另一個節(jié)點。
2、非對等節(jié)點的故障轉(zhuǎn)移,通過心跳檢測并實施主備切換(比如redis的哨兵模式或者集群模式、MySQL的主從切換等)。
3、接口層面的超時設(shè)置、重試策略和冪等設(shè)計。
4、降級處理:保證核心服務(wù),犧牲非核心服務(wù),必要時進(jìn)行熔斷;或者核心鏈路出問題時,有備選鏈路。
5、限流處理:對超過系統(tǒng)處理能力的請求直接拒絕或者返回錯誤碼。
6、MQ場景的消息可靠性保證,包括producer端的重試機制、broker側(cè)的持久化、consumer端的ack機制等。
7、灰度發(fā)布,能支持按機器維度進(jìn)行小流量部署,觀察系統(tǒng)日志和業(yè)務(wù)指標(biāo),等運行平穩(wěn)后再推全量。
8、監(jiān)控報警:全方位的監(jiān)控體系,包括最基礎(chǔ)的CPU、內(nèi)存、磁盤、網(wǎng)絡(luò)的監(jiān)控,以及Web服務(wù)器、JVM、數(shù)據(jù)庫、各類中間件的監(jiān)控和業(yè)務(wù)指標(biāo)的監(jiān)控。
9、災(zāi)備演練:類似當(dāng)前的“混沌工程”,對系統(tǒng)進(jìn)行一些破壞性手段,觀察局部故障是否會引起可用性問題。

高可用的方案主要從冗余、取舍、系統(tǒng)運維3個方向考慮,同時需要有配套的值班機制和故障處理流程,當(dāng)出現(xiàn)線上問題時,可及時跟進(jìn)處理。

高擴展的實踐方案

1、合理的分層架構(gòu):比如上面談到的互聯(lián)網(wǎng)最常見的分層架構(gòu),另外還能進(jìn)一步按照數(shù)據(jù)訪問層、業(yè)務(wù)邏輯層對微服務(wù)做更細(xì)粒度的分層
(但是需要評估性能,會存在網(wǎng)絡(luò)多一跳的情況)。
2、存儲層的拆分:按照業(yè)務(wù)維度做垂直拆分、按照數(shù)據(jù)特征維度進(jìn)一步做水平拆分(分庫分表)。
3、業(yè)務(wù)層的拆分:最常見的是按照業(yè)務(wù)維度拆(比如電商場景的商品服務(wù)、訂單服務(wù)等),
也可以按照核心接口和非核心接口拆,還可以按照請求源拆(比如To C和To B,APP和H5)。

總結(jié)

1、最簡單的系統(tǒng)設(shè)計滿足業(yè)務(wù)需求和流量現(xiàn)狀,選擇最熟悉的技術(shù)體系。

2、隨著流量的增加和業(yè)務(wù)的變化,修正架構(gòu)中存在問題的點,如單點問題,橫向擴展問題,性能無法滿足需求的組件。
在這個過程中,選擇社區(qū)成熟的、團(tuán)隊熟悉的組件幫助我們解決問題,在社區(qū)沒有合適解決方案的前提下才會自己造輪子。

3、當(dāng)對架構(gòu)的小修小補無法滿足需求時,考慮重構(gòu)、重寫等大的調(diào)整方式以解決現(xiàn)有的問題。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • ReentrantLock條件變量使多個線程順序執(zhí)行

    ReentrantLock條件變量使多個線程順序執(zhí)行

    這篇文章主要為大家介紹了ReentrantLock條件變量使多個線程順序執(zhí)行,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Java中使用正則表達(dá)式獲取網(wǎng)頁中所有圖片的路徑

    Java中使用正則表達(dá)式獲取網(wǎng)頁中所有圖片的路徑

    這篇文章主要介紹了Java中使用正則表達(dá)式獲取網(wǎng)頁中所有圖片的路徑,本文直接給出實例代碼,需要的朋友可以參考下
    2015-06-06
  • SpringBoot集成pf4j實現(xiàn)插件開發(fā)功能的代碼示例

    SpringBoot集成pf4j實現(xiàn)插件開發(fā)功能的代碼示例

    pf4j是一個插件框架,用于實現(xiàn)插件的動態(tài)加載,支持的插件格式(zip、jar),本文給大家介紹了SpringBoot集成pf4j實現(xiàn)插件開發(fā)功能的示例,文中通過代碼示例給大家講解的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • 配置pom.xml用maven打包java工程的方法(推薦)

    配置pom.xml用maven打包java工程的方法(推薦)

    下面小編就為大家?guī)硪黄渲胮om.xml用maven打包java工程的方法(推薦)。小編覺得挺不錯的, 現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • 使用Spring Boot搭建Java web項目及開發(fā)過程圖文詳解

    使用Spring Boot搭建Java web項目及開發(fā)過程圖文詳解

    這篇文章主要介紹了使用Spring Boot搭建Java web項目及開發(fā)過程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Java8 實現(xiàn)stream將對象集合list中抽取屬性集合轉(zhuǎn)化為map或list

    Java8 實現(xiàn)stream將對象集合list中抽取屬性集合轉(zhuǎn)化為map或list

    這篇文章主要介紹了Java8 實現(xiàn)stream將對象集合list中抽取屬性集合轉(zhuǎn)化為map或list的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Hibernate延遲加載原理與實現(xiàn)方法

    Hibernate延遲加載原理與實現(xiàn)方法

    這篇文章主要介紹了Hibernate延遲加載原理與實現(xiàn)方法,較為詳細(xì)的分析了Hibernate延遲加載的概念,原理與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2016-03-03
  • Java設(shè)計模式之觀察者模式解析

    Java設(shè)計模式之觀察者模式解析

    這篇文章主要介紹了Java設(shè)計模式之觀察者模式解析,觀察者模式,又被稱為發(fā)布/訂閱模式,它定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個主題對象,這個主題對象在狀態(tài)變化時,會通知所有的觀察者對象,使他們能夠自動更新自己,需要的朋友可以參考下
    2023-09-09
  • 五分鐘帶你學(xué)會用java解析json字符串

    五分鐘帶你學(xué)會用java解析json字符串

    這篇文章主要給大家介紹了關(guān)于用java解析json字符串的相關(guān)資料,JSON是一種輕量級的、基于文本的、與語言無關(guān)的數(shù)據(jù)交換格式,易于人和機器讀寫,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • SpringBoot使用spring retry重試機制的操作詳解

    SpringBoot使用spring retry重試機制的操作詳解

    實際工作中由于網(wǎng)絡(luò)波動等原因?qū)е麓a執(zhí)行失敗需要重新執(zhí)行,保證最終能夠完成業(yè)務(wù)功能,通常來說,會用try/catch,while循環(huán)或者定時任務(wù)重處理,但是這樣的做法缺乏統(tǒng)一性,要多寫很多代碼,spring-retry組件可以通過注解優(yōu)雅的實現(xiàn)重處理功能
    2024-12-12

最新評論

贡山| 诏安县| 黑水县| 宿州市| 兴安盟| 武威市| 龙海市| 遵义县| 石家庄市| 康定县| 河池市| 集贤县| 当雄县| 太仆寺旗| 德格县| 怀柔区| 易门县| 黄龙县| 伊川县| 新田县| 内江市| 罗山县| 洛宁县| 唐海县| 新龙县| 汉中市| 旅游| 万宁市| 南汇区| 高碑店市| 姚安县| 竹山县| 屯门区| 平遥县| 高州市| 彰武县| 旺苍县| 陇南市| 弥渡县| 北流市| 息烽县|