激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

2022-03-04 18:02劍客阿良_ALiang Java教程

高并發(fā)(High Concurrency)是互聯(lián)網(wǎng)分布式系統(tǒng)架構(gòu)設計中必須考慮的因素之一,它通常是指,通過設計保證系統(tǒng)能夠同時并行處理很多請求,高并發(fā)相關(guān)常用的一些指標有響應時間(Response Time),吞吐量(Throughput),每秒查詢率Q

 

前言

隨著互聯(lián)網(wǎng)與軟件的發(fā)展,除了程序員,架構(gòu)師也是越來越火的職業(yè)。他們伴隨著項目的整個生命過程,他們更像是傳統(tǒng)工業(yè)的設計師,將項目當做生命一般細心雕琢。

目前對于項目架構(gòu)而言,基本都會需要設計的幾個架構(gòu)。

 

1、業(yè)務架構(gòu)

項目或者產(chǎn)品的市場定位、需求范圍、作用場景都是需要在項目啟動初期進行系統(tǒng)性分析的。在設計業(yè)務架構(gòu)中,架構(gòu)師還需要明確角色。我看過很多關(guān)于架構(gòu)的文章,談到角色的很少。

什么是角色?

例如:商場作為一個整體系統(tǒng),角色就有消費者、店員、收費員、保安等等。各個角色完成好自己角色所需要承擔的任務,整體系統(tǒng)就能完美的運行。

對應到軟件系統(tǒng)中,根據(jù)產(chǎn)品的定位和需求,也會有著對照的角色,比如:用戶、數(shù)據(jù)審核者、產(chǎn)品制作者、運維人員等。在項目啟動初期,架構(gòu)師需要對項目中的每個角色做好職責定位,我相信在這點上,大部分開發(fā)同學在工作中,或多或少都有過職責不明確帶來的困擾。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

 

2、技術(shù)架構(gòu)

在軟件項目研發(fā)過程中,我們會用到許多外部組件。在使用組件中,架構(gòu)師必須結(jié)合業(yè)務需求合理的選擇各個組件。項目是個生命,她會成長,架構(gòu)師需要明白如果一開始就選擇重量級組件會讓還是個孩童的項目不受重負,架構(gòu)師也需要明白如果技術(shù)架構(gòu)的設計不具備拓展性,那么這個孩子無法茁壯成長。所以技術(shù)架構(gòu)尤為重要。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

 

3、物理架構(gòu)

物理架構(gòu)又叫做部署架構(gòu),項目產(chǎn)品如果要在生產(chǎn)環(huán)境穩(wěn)定運行,一個穩(wěn)定又高效的物理架構(gòu)是必不可少的。而且往往物理架構(gòu)和技術(shù)架構(gòu)是相輔相成的,性能監(jiān)控、異常告警、業(yè)務日志等等設計,都是為了讓項目做更好的自己。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

 

高并發(fā)任務執(zhí)行架構(gòu)

在我十年的工作中,業(yè)務相關(guān)、中間件、大數(shù)據(jù)都有做過。本文主要分享一下高并發(fā)任務執(zhí)行框架設計,會由淺入深的講述一下設計演化過程。如果你不只是想做業(yè)務后端開發(fā),那么本文會給你一個全新的視野。

 

需求場景

我們列一下該項目的需求場景,看看工作中是否遇到過。

1、有個復雜的數(shù)據(jù)需要制作,而且制作的時間很長,無法讓請求方持續(xù)等待。所以請求方只能給你個回調(diào)地址,需要你完成這個制作后將產(chǎn)物通知他。

2、復雜的制作過程需要消耗資源,而且資源有限,無法無限量提供。如果你有接觸過AI,就會比較了解資源有限的感受。除了ASR、TTS這類識別類型的AI功能能做到近實時的反饋,大部分的算法在運行的時候都會消耗整張顯卡,而且耗時很長。

初看場景,很多后端可能會第一時間想到elastic-job(一個分布式任務調(diào)度框架)。即便你熟悉使用elastic-job,一開始就選擇重框架是不是有種殺雞用牛刀的感覺。不著急,我們一步步分析,一步步設計。

 

業(yè)務架構(gòu)設計

高度抽象一下我們的業(yè)務,對產(chǎn)品設計者而言,貌似是個簡單的不能再簡單的東西。等到了技術(shù)架構(gòu),我們深入分析其中演化的功能點,就會發(fā)現(xiàn)這是個龐大的機器。我們先給他起個簡單的名字:Task Execution Engine(縮寫:TEE)

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

 

技術(shù)架構(gòu)設計

下面我們開始進行核心模塊的技術(shù)架構(gòu)設計,按照我們的初始需求開始我們的設計旅程。

 

初始設計

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

設計說明:

1、業(yè)務后端發(fā)出q1請求,我們首先需要對該請求的參數(shù)做矯正,為了可用性考慮。

2、參數(shù)校驗過后,給到執(zhí)行引擎模塊。執(zhí)行引擎主要的職責有從資源表獲取資源數(shù)據(jù)、將任務參數(shù)與資源參數(shù)封裝到任務對象內(nèi)、將任務提交線程池。有一點要說明執(zhí)行引擎最好使用隊列模式,任務先進隊列,可以通過while循環(huán)方式或者定時線程池都可以,后面會推薦更好的。

3、任務執(zhí)行的狀態(tài)與結(jié)果需要同步到數(shù)據(jù)庫中,建議使用mysql。

小結(jié):

按照初始需求,該設計相對比較簡單,完全夠用了。但是按照產(chǎn)品的迭代,業(yè)務方的需求不會僅限于此。繼續(xù)演化。

 

演化階段一

隨著業(yè)務的上線,業(yè)務端會馬上迎來新的問題。

1、由于提交的任務太多了,排在后面的任務遲遲無法等到自己獲取到資源執(zhí)行任務。當然我們可以完全靠增加資源來解決,但是資源的數(shù)量在產(chǎn)品前期是不可知的。所以需要有一些策略,比如讓用戶可以取消自己任務,而不是一直等待。

2、任務的種類開始增加,業(yè)務端不滿足于單一制作,開始要求多樣化。

3、任務的執(zhí)行過程開始需要用到其他資源,不再是一個資源對一個任務的模式了。

4、任務的整體執(zhí)行情況不可知,需要一定的量化分析,至少讓業(yè)務組知道每天的任務成功率。

按照需求進行第二版的設計,在盡量不改變原來整體設計的情況下,補充功能。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

設計說明:

1、為了解決排隊問題,增加了雙隊列算法來解決。用圖解的方式解釋一下雙隊列。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

邏輯簡單說明一下,任務優(yōu)先提交至執(zhí)行隊列,引擎的定時讀取隊列的順序優(yōu)先為等待隊列。如果等待隊列中的任務可以獲取所需資源,則立即啟動線程執(zhí)行,否則原封不動回到等待隊列。引擎其次讀取執(zhí)行隊列,如果無法獲取資源則進入等待隊列,如獲取資源,則立即啟動線程執(zhí)行。

那么取消隊列,則只需要將隊列中的任務踢出隊列即可。在送回隊里的過程中,一定要保證隊列的有序性。

2、創(chuàng)建了任務池,增加了任務封裝層,在任務池中挑選需要執(zhí)行的任務類。

3、增加了策略機模塊,添加資源調(diào)度策略,由資源調(diào)度策略堆任務所需資源合理分配??梢杂蓸I(yè)務方提供分配方案,盡可能保證任務的公平性。

4、數(shù)據(jù)庫增加統(tǒng)計表,可以考慮使用定時任務,將任務表的數(shù)據(jù)統(tǒng)計存入統(tǒng)計表。

小結(jié):

現(xiàn)在看上去已經(jīng)比較完善了,合理了任務調(diào)度、增加了任務種類、合理的資源調(diào)度,好像還不錯。但是產(chǎn)品總會有新要求的,那么繼續(xù)演化。

 

演化階段二

漸漸的,你設計的引擎還不錯。那么新的挑戰(zhàn)來了。

1、更多的業(yè)務方找到你,希望也使用你的項目進行任務制作,但是他們并不想共享資源,而是希望有自己的獨立資源,和獨立的隊列。但并不是所有的資源都需要獨立,一些可以支持高并發(fā)的資源,是可以共享的。簡而言之,更多的業(yè)務方,由業(yè)務方為維度的獨立隊列,獨立和共享的資源分配。

2、業(yè)務方找到你,說如果把任務1的結(jié)果給到任務2,其實就能拿到我要的結(jié)果。問題來了,原子任務要具備可以編排成復雜任務的能力。

3、任務的狀態(tài)過程無法監(jiān)控。OK,任務狀態(tài)機。

4、既然大家都需要對接你的項目,能不能提供標準的sdk,我只需要引入就可以完美的對接你的系統(tǒng)。

5、相同的任務參數(shù),是不是制作出來的結(jié)果一致呢?那么是否需要增加結(jié)果緩存,降低對資源的消耗呢?

6、完正的生產(chǎn)項目必然需要將日志、告警等關(guān)鍵信息傳遞出來,一旦發(fā)生問題可以馬上定位到問題的起因。

這些問題對于新人來說還是很有挑戰(zhàn)的,需要對系統(tǒng)深層的含義有充足的理解。沒事,我來好好來說下設計所需要掌握的知識點。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

設計說明:

1、需要在資源表中區(qū)別資源類型,共享資源組所有業(yè)務組都可以使用,獨立資源則資源具備業(yè)務標識。在執(zhí)行引擎的隊列管理中,也需要區(qū)分業(yè)務組,避免共用排隊。這里給一個建議,共享的資源一定要是可以支持并發(fā)或者可以部署多個實例的,避免所有的業(yè)務組產(chǎn)品制作癱瘓。

2、增加了高級任務概念,高級任務可以將任意的原子任務進行組合編排,形成全新的任務。需要定義專屬于TEE的語法規(guī)則。對語法規(guī)則引擎的開發(fā),有一些建議。你可能會選擇規(guī)則引擎,建議其實可以自己開發(fā),畢竟語法不會太過復雜,沒必要引入三方的引擎。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

3、增加任務狀態(tài)機,執(zhí)行引擎在提交線程的同時,也想任務狀態(tài)機提交任務線程信息。任務的進度狀態(tài)可以同步給任務狀態(tài)機中,同時一旦任務執(zhí)行過長的時間,除了任務自己的超時機制外,也可由狀態(tài)機的看門狗程序?qū)⒖ㄋ谰€程釋放、資源回收。

4、研發(fā)屬于TEE的SDK,作為內(nèi)部系統(tǒng)不建議SDK增加鑒權(quán)模塊。畢竟你對接的往往都是業(yè)務后端,鑒權(quán)不通過的話根本滲透不到TEE層面。給開發(fā)SDK一些建議,盡量引用較少的包,避免業(yè)務端引入帶來的包沖突。SDK也需要添加一些回調(diào)Consumer或者Function,盡可能讓業(yè)務端對接起來代碼簡單。

5、增加了緩存策略,可以設想一下,大部分情況下,相同的參數(shù)制作出來的結(jié)果也必然相同。使用redis,將任務參數(shù)與任務結(jié)果進行緩存,主鍵可以采用任務參數(shù)的MD5值。任務在提交給任務執(zhí)行引擎前,檢查緩存中是否已經(jīng)存在結(jié)果。緩存的過期時間按照具體情況而定。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

6、增加日志系統(tǒng)和監(jiān)控系統(tǒng)的對接,狀態(tài)機與任務執(zhí)行中的信息接入到日志系統(tǒng)中。對于日志系統(tǒng)的建議是,最好采用成熟的ELK架構(gòu)??梢钥紤]兩種方式

a、將日志異步推送到消息隊列(例如:kafka),使用flink將kafka存入es。

b、使用logstash將日志內(nèi)容清洗處理,推送到es。

兩種方式都可以,但是一定要異步推送日志,避免任務阻塞。

告警系統(tǒng)的接入可以使用Prometheus,將TEE的指標信息開放出來,特別是告警信息。在Prometheus的告警監(jiān)控規(guī)則中,可以將告警信息按照某些策略發(fā)送郵件或者短信,通知運維人員。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

小結(jié):

做到這里,我們再看看我們的技術(shù)架構(gòu)圖,是不是感到很滿足。但是這真的夠了嗎?

 

演化階段三

隨著業(yè)務愈發(fā)繁重,一個新的問題出現(xiàn)。

1、TEE在本機運行很順利,但是每個任務都是需要消耗線程的,單臺模式線程必然不是無限的,總有吃滿的時候。問題來了,TEE得支持分布式部署結(jié)構(gòu)。但是有資源管理的存在,你無法通過加實例的方式來實現(xiàn),因為資源調(diào)度必然混亂。

2、假設TEE掛掉,則等于業(yè)務組此刻提交的任務均失敗,容災機制需要建立。

到了這一步,很多小伙伴可能覺著一陣頭大,分布式不是大數(shù)據(jù)的東西嗎?不是的,不是大數(shù)據(jù)就不能分布式部署嗎?就不能有主從節(jié)點嗎?就不能有注冊中心嗎?要跨過內(nèi)心的固有思想,我們往下看。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

設計說明:

1、需要先將TEE項目做一下代碼分解,將管理調(diào)度模塊與任務執(zhí)行模塊拆解開了。消耗性能和線程較高的是任務執(zhí)行模塊,定義為TEE執(zhí)行節(jié)點。消耗性能和線程較低,卻需要參數(shù)校驗、任務封裝、資源調(diào)度、隊列管理的是管理調(diào)度模塊,定義為TEE管理節(jié)點。

2、TEE執(zhí)行節(jié)點可以多實例,形成節(jié)點池。管理節(jié)點可以考慮做成共享任務隊列的管理池。這里有個難點,如何共享任務隊列。建議使用zookeeper或者緩存方式,但是不管哪種方式都要注意使用集群,避免單點故障導致隊列數(shù)據(jù)丟失。

3、關(guān)于注冊中心,可以使用開源組件,nacos、zookeeper都可以。在該架構(gòu)設計中,其實注冊中心并沒有太多功能,如果你對自己有信心,可以嘗試自己寫一個注冊中心,核心功能就是服務注冊與心跳檢測。可以用netty架構(gòu)做一做,提高一下自己的代碼能力。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

4、在管理池的調(diào)用方面,增加網(wǎng)關(guān)代理,可以使用nginx、konga等。主要功能是業(yè)務端調(diào)用的時候,隨機打到管理節(jié)點上,就算一個管理節(jié)點掛了,也不會影響使用,保證了生產(chǎn)線的穩(wěn)定。

小結(jié):

分布式架構(gòu),主從節(jié)點模式也好、哨兵模式也好、選舉模式也好,按照自己的業(yè)務需求選擇最適合自己的。不是大數(shù)據(jù)才有分布式,它是一種設計思想,要知道開發(fā)大數(shù)據(jù)組件的大佬們,也是一行行java寫出來的。大佬們可以,為什么你不可以呢?

 

代碼設計

在著手開發(fā)該系統(tǒng)的時候,我給大家一些代碼開發(fā)的建議:

1、定時任務的實現(xiàn),從最簡單的while死循環(huán)加sleep,到定時線程池,或者springboot的@Scheduled注解,都可以實現(xiàn)。我在這里推薦一下時間輪算法TimeWheel,有興趣的可以去了解一下。

2、異步消息處理,如果你只是想在項目內(nèi)部使用消息總線,推薦使用guava包內(nèi)的EventBus。按照消息的數(shù)量級,考慮使用RabbitMQ或者Kafka作為消息中間件。

3、任務執(zhí)行,推薦使用CompletableFuture進行異步非阻塞任務編程。

4、在資源的使用中,可能存在多種協(xié)議類型http、ws、tcp等。所以代碼設計中,盡可能提供完整全面的協(xié)議工具類。

 

總結(jié)

最近和一個同事閑聊的時候,他和我說了說最近面試高級研發(fā)的情況??偨Y(jié)一下,現(xiàn)在想招一個做過高并發(fā)場景的太難了,大部分人選只做業(yè)務相關(guān)。這讓我想到了十年前,我剛工作的時候。那時候沒有那么多框架,大部分功能需要看很多資料研究底層的原理與算法。隨著軟件行業(yè)的日益成熟,從以前拿著谷歌翻譯看國外的組建說明,到從阿里云直接對接功能,軟件研發(fā)的成本和時間也在大大縮短。漸漸失去了研究分析的動力,框架什么都有為什么要抓破腦袋自己寫。

怎么成長?怎么進步?

上面給出的架構(gòu)圖,看上去都挺好理解。但真要自己去代碼實現(xiàn),中間各個環(huán)節(jié)出現(xiàn)的問題真的好解決嗎?冰凍三尺,非一日之寒。沒有日積月累的學習,是很難成功的。不要懼怕那些你看上去遙遠的東西,獲取你的幾個晚上的學習,它就成了你最趁手的武器。對學習而言,難的永遠不是過程,而是踏出第一步。

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

高并發(fā)任務執(zhí)行架構(gòu)中,有一個模塊看上去很不起眼,但是在你研發(fā)的過程就會發(fā)現(xiàn)他會給你制造大麻煩-資源調(diào)度。以后有時間我會單獨做一篇關(guān)于資源調(diào)度的架構(gòu)設計,與大家說道說道里面的坑。

最后說一句:為什么不ban猛犸?

Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏

到此這篇關(guān)于Java 高并發(fā)編程之最實用的任務執(zhí)行架構(gòu)設計建議收藏的文章就介紹到這了,更多相關(guān)Java 高并發(fā)編程內(nèi)容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務器之家!

原文鏈接:https://huyi-aliang.blog.csdn.net/article/details/120916096

延伸 · 閱讀

精彩推薦
  • Java教程每日六道java新手入門面試題,通往自由的道路第二天

    每日六道java新手入門面試題,通往自由的道路第二天

    這篇文章主要為大家分享了最有價值的6道java面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對hashCode方法的設計、垃圾收集...

    太子爺哪吒6222021-09-23
  • Java教程Java源碼解析阻塞隊列ArrayBlockingQueue介紹

    Java源碼解析阻塞隊列ArrayBlockingQueue介紹

    今天小編就為大家分享一篇關(guān)于Java源碼解析阻塞隊列ArrayBlockingQueue介紹,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起...

    李燦輝9012021-06-30
  • Java教程java字符串求并集的方法

    java字符串求并集的方法

    這篇文章主要介紹了java字符串求并集的方法,涉及Java字符串操作中union方法的使用,是Java字符串操作中非常實用的基本技巧,需要的朋友可以參考下 ...

    shichen20146552019-12-06
  • Java教程淺談javap命令拆解字節(jié)碼文件

    淺談javap命令拆解字節(jié)碼文件

    這篇文章主要介紹了拆解字節(jié)碼文件javap命令,對反編譯感興趣的同學可以參考下...

    2048102410422021-09-02
  • Java教程java設計模式之外觀模式學習筆記

    java設計模式之外觀模式學習筆記

    這篇文章主要為大家詳細介紹了java設計模式之外觀模式學習筆記,具有一定的參考價值,感興趣的小伙伴們可以參考一下 ...

    翡青2392020-06-24
  • Java教程Java中Lambda表達式的進化之路詳解

    Java中Lambda表達式的進化之路詳解

    本文通過示例大家給大家介紹了Java中Lambda表達式的進化之路,感興趣的的朋友一起看看吧,希望能夠給你帶來幫助...

    Thales_ZeeWay4512022-03-10
  • Java教程Java基礎知識匯總

    Java基礎知識匯總

    這篇文章對Java編程語言的基礎知識作了一個較為全面的匯總,在這里給大家分享一下。需要的朋友可以參考。...

    李子園的夢想5212021-01-06
  • Java教程Java之SpringBoot集成ActiveMQ消息中間件案例講解

    Java之SpringBoot集成ActiveMQ消息中間件案例講解

    這篇文章主要介紹了Java之SpringBoot集成ActiveMQ消息中間件案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可...

    愚蠢的土撥鼠~10402021-10-29
主站蜘蛛池模板: 日韩视频在线观看免费 | 欧美一级www片免费观看 | 神马久久蜜桃 | 被玩坏了的女老师(高h np) | 把娇妻调教成暴露狂 | 国产日韩欧美 | 在线观看免费污视频 | 国产毛片在线看 | 成人辣文 | 999精品久久久 | 欧美一级欧美 | 特级黄毛片 | 精品久久久久久久久久久久久久久久久久久 | www.99tv| 久久不射电影 | 香蕉黄色网 | 亚洲第一成人在线视频 | 一级成人毛片 | 精品一区二区三区中文字幕老牛 | 中国嫩模一级毛片 | 国产美女白浆 | 久久国产乱子伦精品 | 91看片欧美| 少妇的肉体的满足毛片 | 日韩每日更新 | 黄色网战入口 | 免费a级毛片大学生免费观看 | 日产精品久久久一区二区福利 | 精品国产一区二区三区成人影院 | 港台三级在线观看 | 久久久久女人精品毛片九一 | 欧美日本另类 | 免费黄色小视频网站 | 福利在线免费 | 九九视屏 | 久久色网站 | 日韩精品久久久久久久九岛 | 日韩视频一区在线 | 国产成年人视频 | 成人免费看毛片 | 国产精品久久久久久久久久三级 |