成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

8000字 + 25圖探秘Xxl-Job核心架構(gòu)原理

開發(fā) 架構(gòu)
從架構(gòu)圖中也可以看出來,本文除了日志部分的內(nèi)容沒有提到,其它的整個核心邏輯基本上都講到了,而日志部分其實是個輔助的作用,讓你更方便查看任務的運行情況,對任務的觸發(fā)邏輯是沒有影響的,所以就沒講了.

核心概念

這里還是老樣子,為了保證文章的完整性和連貫性,方便那些沒有使用過的小伙伴更加容易接受文章的內(nèi)容,快速講一講Xxl-Job中的概念和使用

如果你已經(jīng)使用過了,可直接跳過本節(jié)和下一節(jié),快進到后面原理部分講解

1、調(diào)度中心

調(diào)度中心是一個單獨的Web服務,主要是用來觸發(fā)定時任務的執(zhí)行

它提供了一些頁面操作,我們可以很方便地去管理這些定時任務的觸發(fā)邏輯

調(diào)度中心依賴數(shù)據(jù)庫,所以數(shù)據(jù)都是存在數(shù)據(jù)庫中的

調(diào)度中心也支持集群模式,但是它們所依賴的數(shù)據(jù)庫必須是同一個

所以同一個集群中的調(diào)度中心實例之間是沒有任何通信的,數(shù)據(jù)都是通過數(shù)據(jù)庫共享的

圖片圖片

2、執(zhí)行器

執(zhí)行器是用來執(zhí)行具體的任務邏輯的

執(zhí)行器你可以理解為就是平時開發(fā)的服務,一個服務實例對應一個執(zhí)行器實例

每個執(zhí)行器有自己的名字,為了方便,你可以將執(zhí)行器的名字設置成服務名

3、任務

任務什么意思就不用多說了

一個執(zhí)行器中也是可以有多個任務的

總的來說,調(diào)用中心是用來控制定時任務的觸發(fā)邏輯,而執(zhí)行器是具體執(zhí)行任務的,這是一種任務和觸發(fā)邏輯分離的設計思想,這種方式的好處就是使任務更加靈活,可以隨時被調(diào)用,還可以被不同的調(diào)度規(guī)則觸發(fā)。

圖片圖片

來個Demo

1、搭建調(diào)度中心

調(diào)度中心搭建很簡單,先下載源碼

https://github.com/xuxueli/xxl-job.git

然后改一下數(shù)據(jù)庫連接信息,執(zhí)行一下在項目源碼中的/doc/db下的sql文件

圖片圖片

啟動可以打成一個jar包,或者本地啟動就是可以的

啟動完成之后,訪問下面這個地址就可以訪問到控制臺頁面了

http://localhost:8080/xxl-job-admin/toLogin

用戶名密碼默認是 admin/123456

2、執(zhí)行器和任務添加

添加一個名為sanyou-xxljob-demo執(zhí)行器

圖片圖片

任務添加

圖片圖片

執(zhí)行器選擇我們剛剛添加的,指定任務名稱為TestJob,corn表達式的意思是每秒執(zhí)行一次

創(chuàng)建完之后需要啟動一下任務,默認是關閉狀態(tài),也就不會執(zhí)行

圖片圖片

創(chuàng)建執(zhí)行器和任務其實就是CRUD,并沒有復雜的業(yè)務邏輯

按照如上配置的整個Demo的意思就是

每隔1s,執(zhí)行一次sanyou-xxljob-demo這個執(zhí)行器中的TestJob任務

3、創(chuàng)建執(zhí)行器和任務

引入依賴

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.2.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.xuxueli</groupId>
        <artifactId>xxl-job-core</artifactId>
        <version>2.4.0</version>
    </dependency>
</dependencies>

配置XxlJobSpringExecutor這個Bean

@Configuration
public class XxlJobConfiguration {

    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        //設置調(diào)用中心的連接地址
        xxlJobSpringExecutor.setAdminAddresses("http://localhost:8080/xxl-job-admin");
        //設置執(zhí)行器的名稱
        xxlJobSpringExecutor.setAppname("sanyou-xxljob-demo");
        //設置一個端口,后面會講作用
        xxlJobSpringExecutor.setPort(9999);
        //這個token是保證訪問安全的,默認是這個,當然可以自定義,
        // 但需要保證調(diào)度中心配置的xxl.job.accessToken屬性跟這個token是一樣的
        xxlJobSpringExecutor.setAccessToken("default_token");
        //任務執(zhí)行日志存放的目錄
        xxlJobSpringExecutor.setLogPath("./");
        return xxlJobSpringExecutor;
    }

}

XxlJobSpringExecutor這個類的作用,后面會著重講

通過@XxlJob指定一個名為TestJob的任務,這個任務名需要跟前面頁面配置的對應上

@Component
public class TestJob {

    private static final Logger logger = LoggerFactory.getLogger(TestJob.class);

    @XxlJob("TestJob")
    public void testJob() {
        logger.info("TestJob任務執(zhí)行了。。。");
    }

}

所以如果順利的話,每隔1s鐘就會打印一句TestJob任務執(zhí)行了。。。

啟動項目,注意修改一下端口,因為調(diào)用中心默認也是8080,本地起會端口沖突

最終執(zhí)行結(jié)果如下,符合預期

圖片圖片

講完概念和使用部分,接下來就來好好講一講Xxl-Job核心的實現(xiàn)原理

從執(zhí)行器啟動說起

前面Demo中使用到了一個很重要的一個類

XxlJobSpringExecutor

這個類就是整個執(zhí)行器啟動的入口

圖片圖片

這個類實現(xiàn)了SmartInitializingSingleton接口

所以經(jīng)過Bean的生命周期,一定會調(diào)用afterSingletonsInstantiated這個方法的實現(xiàn)

這個方法干了很多初始化的事,這里我挑三個重要的講,其余的等到具體的功能的時候再提

1、初始化JobHandler

JobHandler是個什么?

所謂的JobHandler其實就是一個定時任務的封裝

圖片圖片

一個定時任務會對應一個JobHandler對象

當執(zhí)行器執(zhí)行任務的時候,就會調(diào)用JobHandler的execute方法

JobHandler有三種實現(xiàn):

  • MethodJobHandler
  • GlueJobHandler
  • ScriptJobHandler

MethodJobHandler是通過反射來調(diào)用方法執(zhí)行任務

圖片圖片

所以MethodJobHandler的任務的實現(xiàn)就是一個方法,剛好我們demo中的例子任務其實就是一個方法

所以Demo中的任務最終被封裝成一個MethodJobHandler

GlueJobHandler比較有意思,它支持動態(tài)修改任務執(zhí)行的代碼

當你在創(chuàng)建任務的時候,需要指定運行模式為GLUE(Java)

圖片圖片

之后需要在操作按鈕點擊GLUE IDE編寫Java代碼

圖片圖片

代碼必須得實現(xiàn)IJobHandler接口,之后任務執(zhí)行的時候就會執(zhí)行execute方法的實現(xiàn)

如果你需要修改任務的邏輯,只需要重新編輯即可,不需要重啟服務

ScriptJobHandler,通過名字也可以看出,是專門處理一些腳本的

運行模式除了BEAN和GLUE(Java)之外,其余都是腳本模式

而本節(jié)的主旨,所謂的初始化JobHandler就是指,執(zhí)行器啟動的時候會去Spring容器中找到加了@XxlJob注解的Bean

解析注解,然后封裝成一個MethodJobHandler對象,最終存到XxlJobSpringExecutor成員變量的一個本地的Map緩存中

圖片圖片

緩存key就是任務的名字

圖片圖片

至于GlueJobHandler和ScriptJobHandler都是任務觸發(fā)時才會創(chuàng)建

除了上面這幾種,你也自己實現(xiàn)JobHandler,手動注冊到JobHandler的緩存中,也是可以通過調(diào)度中心觸發(fā)的

2、創(chuàng)建一個Http服務器

除了初始化JobHandler之外,執(zhí)行器還會創(chuàng)建一個Http服務器

這個服務器端口號就是通過XxlJobSpringExecutor配置的端口,demo中就是設置的是9999,底層是基于Netty實現(xiàn)的

圖片圖片

這個Http服務端會接收來自調(diào)度中心的請求

當執(zhí)行器接收到調(diào)度中心的請求時,會把請求交給ExecutorBizImpl來處理

圖片圖片

這個類非常重要,所有調(diào)度中心的請求都是這里處理的

ExecutorBizImpl實現(xiàn)了ExecutorBiz接口

當你翻源碼的時候會發(fā)現(xiàn),ExecutorBiz還有一個ExecutorBizClient實現(xiàn)

圖片圖片

ExecutorBizClient的實現(xiàn)就是發(fā)送http請求,所以這個實現(xiàn)類是在調(diào)度中心使用的,用來訪問執(zhí)行器提供的http接口

圖片圖片

3、注冊到調(diào)度中心

當執(zhí)行器啟動的時候,會啟動一個注冊線程,這個線程會往調(diào)度中心注冊當前執(zhí)行器的信息,包括兩部分數(shù)據(jù)

  • 執(zhí)行器的名字,也就是設置的appname
  • 執(zhí)行器所在機器的ip和端口,這樣調(diào)度中心就可以訪問到這個執(zhí)行器提供的Http接口

前面提到每個服務實例都會對應一個執(zhí)行器實例,所以調(diào)用中心會保存每個執(zhí)行器實例的地址

圖片圖片

這里你可以把調(diào)度中心的功能類比成注冊中心

任務觸發(fā)原理

弄明白執(zhí)行器啟動時干了哪些事,接下來講一講Xxl-Job最最核心的功能,那就是任務觸發(fā)的原理

任務觸發(fā)原理我會分下面5個小點來講解

  • 任務如何觸發(fā)?
  • 快慢線程池的異步觸發(fā)任務優(yōu)化
  • 如何選擇執(zhí)行器實例?
  • 執(zhí)行器如何去執(zhí)行任務?
  • 任務執(zhí)行結(jié)果的回調(diào)

1、任務如何觸發(fā)?

調(diào)度中心在啟動的時候,會開啟一個線程,這個線程的作用就是來計算任務觸發(fā)時機,這里我把這個線程稱為調(diào)度線程

這個調(diào)度線程會去查詢xxl_job_info這張表

這張表存了任務的一些基本信息和任務下一次執(zhí)行的時間

調(diào)度線程會去查詢下一次執(zhí)行的時間 <= 當前時間 + 5s的任務

這個5s是XxlJob寫死的,被稱為預讀時間,提前讀出來,保證任務能準時觸發(fā)

舉個例子,假設當前時間是2023-11-29 08:00:10,這里的查詢就會查出下一次任務執(zhí)行時間在2023-11-29 08:00:15之前執(zhí)行的任務

圖片圖片

查詢到任務之后,調(diào)度線程會去將這些任務根據(jù)執(zhí)行時間劃分為三個部分:

  • 當前時間已經(jīng)超過任務下一次執(zhí)行時間5s以上,也就是需要在2023-11-29 08:00:05(不包括05s)之前的執(zhí)行的任務
  • 當前時間已經(jīng)超過任務下一次執(zhí)行時間,但是但不足5s,也就是在2023-11-29 08:00:05和2023-11-29 08:00:10(不包括10s)之間執(zhí)行的任務
  • 還未到觸發(fā)時間,但是一定是5s內(nèi)就會觸發(fā)執(zhí)行的

圖片圖片

對于第一部分的已經(jīng)超過5s以上時間的任務,會根據(jù)任務配置的調(diào)度過期策略來選擇要不要執(zhí)行

圖片圖片

調(diào)度過期策略就兩種,就是字面意思

  • 直接忽略這個已經(jīng)過期的任務
  • 立馬執(zhí)行一次這個過期的任務

對于第二部分的超時時間在5s以內(nèi)的任務,就直接立馬執(zhí)行一次,之后如果判斷任務下一次執(zhí)行時間就在5s內(nèi),會直接放到一個時間輪里面,等待下一次觸發(fā)執(zhí)行

對于第三部分任務,由于還沒到執(zhí)行時間,所以不會立馬執(zhí)行,也是直接放到時間輪里面,等待觸發(fā)執(zhí)行

當這批任務處理完成之后,不論是前面是什么情況,調(diào)度線程都會去重新計算每個任務的下一次觸發(fā)時間,然后更新xxl_job_info這張表的下一次執(zhí)行時間

到此,一次調(diào)度的計算就算完成了

之后調(diào)度線程還會繼續(xù)重復上面的步驟,查任務,調(diào)度任務,更新任務下次執(zhí)行時間,一直死循環(huán)下去,這就實現(xiàn)了任務到了執(zhí)行時間就會觸發(fā)的功能

這里在任務觸發(fā)的時候還有一個很有意思的細節(jié)

由于調(diào)度中心可以是集群的形式,每個調(diào)度中心實例都有調(diào)度線程,那么如何保證任務在同一時間只會被其中的一個調(diào)度中心觸發(fā)一次?

我猜你第一時間肯定想到分布式鎖,但是怎么加呢?

XxlJob實現(xiàn)就比較有意思了,它是基于八股文中常說的通過數(shù)據(jù)庫來實現(xiàn)的分布式鎖的

在調(diào)度之前,調(diào)度線程會嘗試執(zhí)行下面這句sql

圖片圖片

就是這個sql

select * from xxl_job_lock where lock_name = 'schedule_lock' for update

一旦執(zhí)行成功,說明當前調(diào)度中心成功搶到了鎖,接下來就可以執(zhí)行調(diào)度任務了

當調(diào)度任務執(zhí)行完之后再去關閉連接,從而釋放鎖

由于每次執(zhí)行之前都需要去獲取鎖,這樣就保證在調(diào)度中心集群中,同時只有一個調(diào)度中心執(zhí)行調(diào)度任務

最后畫一張圖來總結(jié)一下這一小節(jié)

圖片圖片

2、快慢線程池的異步觸發(fā)任務優(yōu)化

當任務達到了觸發(fā)條件,并不是由調(diào)度線程直接去觸發(fā)執(zhí)行器的任務執(zhí)行

調(diào)度線程會將這個觸發(fā)的任務交給線程池去執(zhí)行

所以上圖中的最后一部分觸發(fā)任務執(zhí)行其實是線程池異步去執(zhí)行的

那么,為什么要使用線程池異步呢?

主要是因為觸發(fā)任務,需要通過Http接口調(diào)用具體的執(zhí)行器實例去觸發(fā)任務

圖片圖片

這一過程必然會耗費時間,如果調(diào)度線程去做,就會耽誤調(diào)度的效率

所以就通過異步線程去做,調(diào)度線程只負責判斷任務是否需要執(zhí)行

并且,Xxl-Job為了進一步優(yōu)化任務的觸發(fā),將這個觸發(fā)任務執(zhí)行的線程池劃分成快線程池和慢線程池兩個線程池

圖片圖片

在調(diào)用執(zhí)行器的Http接口觸發(fā)任務執(zhí)行的時候,Xxl-Job會去記錄每個任務的觸發(fā)所耗費的時間

注意并不是任務執(zhí)行時間,只是整個Http請求耗時時間,這是因為執(zhí)行器執(zhí)行任務是異步執(zhí)行的,所以整個時間不包括任務執(zhí)行時間,這個后面會詳細說

當任務一次觸發(fā)的時間超過500ms,那么這個任務的慢次數(shù)就會加1

如果這個任務一分鐘內(nèi)觸發(fā)的慢次數(shù)超過10次,接下來就會將觸發(fā)任務交給慢線程池去執(zhí)行

所以快慢線程池就是避免那種頻繁觸發(fā)并且每次觸發(fā)時間還很長的任務阻塞其它任務的觸發(fā)的情況發(fā)生

3、如何選擇執(zhí)行器實例?

上一節(jié)說到,當任務需要觸發(fā)的時候,調(diào)度中心會向執(zhí)行器發(fā)送Http請求,執(zhí)行器去執(zhí)行具體的任務

那么問題來了

由于一個執(zhí)行器會有很多實例,那么應該向哪個實例請求?

這其實就跟任務配置時設置的路由策略有關了

圖片圖片

從圖上可以看出xxljob支持多種路由策略

除了分片廣播,其余的具體的算法實現(xiàn)都是通過ExecutorRouter的實現(xiàn)類來實現(xiàn)的

圖片圖片

這里簡單講一講各種算法的原理,有興趣的小伙伴可以去看看內(nèi)部的實現(xiàn)細節(jié)

第一個、最后一個、輪詢、隨機都很簡單,沒什么好說的

一致性Hash講起來比較復雜,你可以先看看這篇文章,再去查看Xxl-Job的代碼實現(xiàn)

https://zhuanlan.zhihu.com/p/470368641

最不經(jīng)常使用(LFU:Least Frequently Used):Xxl-Job內(nèi)部會有一個緩存,統(tǒng)計每個任務每個地址的使用次數(shù),每次都選擇使用次數(shù)最少的地址,這個緩存每隔24小時重置一次

最近最久未使用(LRU:Least Recently Used):將地址存到LinkedHashMap中,它利用LinkedHashMap可以根據(jù)元素訪問(get/put)順序來給元素排序的特性,快速找到最近最久未使用(未訪問)的節(jié)點

故障轉(zhuǎn)移:調(diào)度中心都會去請求每個執(zhí)行器,只要能接收到響應,說明執(zhí)行器正常,那么任務就會交給這個執(zhí)行器去執(zhí)行

忙碌轉(zhuǎn)移:調(diào)度中心也會去請求每個執(zhí)行器,判斷執(zhí)行器是不是正在執(zhí)行當前需要執(zhí)行的任務(任務執(zhí)行時間過長,導致上一次任務還沒執(zhí)行完,下一次又觸發(fā)了),如果在執(zhí)行,說明忙碌,不能用,否則就可以用

分片廣播:XxlJob給每個執(zhí)行器分配一個編號,從0開始遞增,然后向所有執(zhí)行器觸發(fā)任務,告訴每個執(zhí)行器自己的編號和總共執(zhí)行器的數(shù)據(jù)

我們可以通過XxlJobHelper#getShardIndex獲取到編號,XxlJobHelper#getShardTotal獲取到執(zhí)行器的總數(shù)據(jù)量

分片廣播就是將任務量分散到各個執(zhí)行器,每個執(zhí)行器只執(zhí)行一部分任務,加快任務的處理

舉個例子,比如你現(xiàn)在需要處理30w條數(shù)據(jù),有3個執(zhí)行器,此時使用分片廣播,那么此時可將任務分成3分,每份10w條數(shù)據(jù),執(zhí)行器根據(jù)自己的編號選擇對應的那份10w數(shù)據(jù)處理

圖片圖片

當選擇好了具體的執(zhí)行器實例之后,調(diào)用中心就會攜帶一些觸發(fā)的參數(shù),發(fā)送Http請求,觸發(fā)任務

4、執(zhí)行器如何去執(zhí)行任務?

相信你一定記得我前面在說執(zhí)行器啟動是會創(chuàng)建一個Http服務器的時候提到這么一句

當執(zhí)行器接收到調(diào)度中心的請求時,會把請求交給ExecutorBizImpl來處理

所以前面提到的故障轉(zhuǎn)移和忙碌轉(zhuǎn)移請求執(zhí)行器進行判斷,最終執(zhí)行器也是交給ExecutorBizImpl處理的

執(zhí)行器處理觸發(fā)請求是這個ExecutorBizImpl的run方法實現(xiàn)的

圖片圖片

當執(zhí)行器接收到請求,在正常情況下,執(zhí)行器會去為這個任務創(chuàng)建一個單獨的線程,這個線程被稱為JobThread

每個任務在觸發(fā)的時候都有單獨的線程去執(zhí)行,保證不同的任務執(zhí)行互不影響

之后任務并不是直接交給線程處理的,而是直接放到一個內(nèi)存隊列中,線程直接從隊列中獲取任務

圖片圖片

這里我相信你一定有個疑惑

為什么不直接處理,而是交給隊列,從隊列中獲取任務呢?

那就得講講不正常的情況了

如果調(diào)度中心選擇的執(zhí)行器實例正在處理定時任務,那么此時該怎么處理呢?**

這時就跟阻塞處理策略有關了

圖片圖片

阻塞處理策略總共有三種:

  • 單機串行
  • 丟棄后續(xù)調(diào)度
  • 覆蓋之前調(diào)度

單機串行的實現(xiàn)就是將任務放到隊列中,由于隊列是先進先出的,所以就實現(xiàn)串行,這也是為什么放在隊列的原因

丟棄調(diào)度的實現(xiàn)就是執(zhí)行器什么事都不用干就可以了,自然而然任務就丟了

覆蓋之前調(diào)度的實現(xiàn)就很暴力了,他是直接重新創(chuàng)建一個JobThread來執(zhí)行任務,并且嘗試打斷之前的正在處理任務的JobThread,丟棄之前隊列中的任務

打斷是通過Thread#interrupt方法實現(xiàn)的,所以正在處理的任務還是有可能繼續(xù)運行,并不是說一打斷正在運行的任務就終止了

這里需要注意的一點就是,阻塞處理策略是對于單個執(zhí)行器上的任務來生效的,不同執(zhí)行器實例上的同一個任務是互不影響的

比如說,有一個任務有兩個執(zhí)行器A和B,路由策略是輪詢

任務第一次觸發(fā)的時候選擇了執(zhí)行器實例A,由于任務執(zhí)行時間長,任務第二次觸發(fā)的時候,執(zhí)行器的路由到了B,此時A的任務還在執(zhí)行,但是B感知不到A的任務在執(zhí)行,所以此時B就直接執(zhí)行了任務

所以此時你配置的什么阻塞處理策略就沒什么用了

如果業(yè)務中需要保證定時任務同一時間只有一個能運行,需要把任務路由到同一個執(zhí)行器上,比如路由策略就選擇第一個

5、任務執(zhí)行結(jié)果的回調(diào)

當任務處理完成之后,執(zhí)行器會將任務執(zhí)行的結(jié)果發(fā)送給調(diào)度中心

圖片圖片

如上圖所示,這整個過程也是異步化的

  • JobThread會將任務執(zhí)行的結(jié)果發(fā)送到一個內(nèi)存隊列中
  • 執(zhí)行器啟動的時候會開啟一個處發(fā)送任務執(zhí)行結(jié)果的線程:TriggerCallbackThread
  • 這個線程會不停地從隊列中獲取所有的執(zhí)行結(jié)果,將執(zhí)行結(jié)果批量發(fā)送給調(diào)度中心
  • 調(diào)用中心接收到請求時,會根據(jù)執(zhí)行的結(jié)果修改這次任務的執(zhí)行狀態(tài)和進行一些后續(xù)的事,比如失敗了是否需要重試,是否有子任務需要觸發(fā)等等

到此,一次任務的就算真正處理完成了

最后

最后我從官網(wǎng)撈了一張Xxl-Job架構(gòu)圖

圖片圖片

奈何作者不更新吶,導致這個圖稍微有點老了,有點跟現(xiàn)有的架構(gòu)對不上

比如說圖中的自研RPC(xxl-rpc)部分已經(jīng)替換成了Http協(xié)議,這主要是擁抱生態(tài),方便跨語言接入

但是不要緊,大體還是符合現(xiàn)在的整個的架構(gòu)

從架構(gòu)圖中也可以看出來,本文除了日志部分的內(nèi)容沒有提到,其它的整個核心邏輯基本上都講到了

而日志部分其實是個輔助的作用,讓你更方便查看任務的運行情況,對任務的觸發(fā)邏輯是沒有影響的,所以就沒講了

所以從本文的講解再到官方架構(gòu)圖,你會發(fā)現(xiàn)整個Xxl-Job不論是使用還是實現(xiàn)都是比較簡單的,非常的輕量級

責任編輯:武曉燕 來源: 三友的java日記
相關推薦

2023-10-16 22:07:20

Spring配置中心Bean

2022-03-26 17:13:22

ElasticJobxxl-job分布式

2020-07-17 09:33:39

CPU內(nèi)存調(diào)度

2024-02-27 22:31:00

Feign動態(tài)代理核心

2025-02-18 14:08:14

2025-05-26 09:31:23

2022-09-23 13:57:11

xxl-job任務調(diào)度中間件

2024-08-27 09:34:24

2024-01-02 22:47:47

Nacos注冊中心節(jié)點

2023-01-04 09:23:58

2024-09-09 08:11:12

2025-06-27 09:31:25

2024-07-31 08:18:40

2024-12-04 10:47:26

2021-12-26 00:03:27

響應式編程異步

2022-01-27 08:44:58

調(diào)度系統(tǒng)開源

2021-12-26 19:07:51

MySQL存儲容器

2022-12-29 08:32:50

xxl-job緩存Schedule

2023-06-27 07:44:53

xxl-job分布式任務調(diào)度平臺

2024-07-08 23:03:13

點贊
收藏

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

主站蜘蛛池模板: 国产精品日日做人人爱 | 亚洲免费网 | 在线国产一区 | 免费毛片网站在线观看 | 亚洲精品电影在线观看 | 亚洲精品久 | 人妖一区 | 色性av | 午夜免费观看 | 天天插天天射天天干 | 北条麻妃国产九九九精品小说 | 91精品国产综合久久精品图片 | 国产精品久久久久久久模特 | 国产精品精品视频一区二区三区 | 国产视频三级 | av在线一区二区 | 伦理午夜电影免费观看 | 欧美a免费 | 丝袜美腿一区二区三区动态图 | 国产在线精品一区 | 亚洲午夜精品 | av资源中文在线 | 特黄级国产片 | 羞视频在线观看 | 午夜精品一区二区三区在线观看 | 精久久久 | 精品国产18久久久久久二百 | 成人免费黄视频 | 99reav| 色综合网站 | 国产精品久久久久久 | 罗宾被扒开腿做同人网站 | 久草影视在线 | 日韩中文字幕在线免费 | 国产精品99久久久久久动医院 | 久久精品久久精品 | 欧美激情视频一区二区三区免费 | 久草视频在 | 亚洲精品1区2区3区 91免费看片 | 超碰综合 | 中文字幕一区二区三区不卡 |