0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

效率加倍,高并發(fā)場(chǎng)景下的接口請(qǐng)求合并方案

jf_ro2CN3Fa ? 來(lái)源:芋道源碼 ? 2023-01-13 10:09 ? 次閱讀


前言

請(qǐng)求合并到底有什么意義呢?我們來(lái)看下圖。

281af012-92e3-11ed-bfe3-dac502259ad0.png

假設(shè)我們3個(gè)用戶(用戶id分別是1、2、3),現(xiàn)在他們都要查詢自己的基本信息,請(qǐng)求到服務(wù)器,服務(wù)器端請(qǐng)求數(shù)據(jù)庫(kù),發(fā)出3次請(qǐng)求。我們都知道數(shù)據(jù)庫(kù)連接資源是相當(dāng)寶貴的,那么我們?cè)趺幢M可能節(jié)省連接資源呢?

這里把數(shù)據(jù)庫(kù)換成被調(diào)用的遠(yuǎn)程服務(wù),也是同樣的道理。

我們改變下思路,如下圖所示。

28311838-92e3-11ed-bfe3-dac502259ad0.png

我們?cè)诜?wù)器端把請(qǐng)求合并,只發(fā)出一條SQL查詢數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)返回后,服務(wù)器端處理返回?cái)?shù)據(jù),根據(jù)一個(gè)唯一請(qǐng)求ID,把數(shù)據(jù)分組,返回給對(duì)應(yīng)用戶。

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

技術(shù)手段

  • LinkedBlockQueue 阻塞隊(duì)列
  • ScheduledThreadPoolExecutor 定時(shí)任務(wù)線程池
  • CompleteableFuture future 阻塞機(jī)制(Java 8 的 CompletableFuture 并沒(méi)有 timeout 機(jī)制,后面優(yōu)化,使用了隊(duì)列替代)

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

代碼實(shí)現(xiàn)

查詢用戶的代碼

publicinterfaceUserService{

MapqueryUserByIdBatch(ListuserReqs);
}
@Service
publicclassUserServiceImplimplementsUserService{

@Resource
privateUsersMapperusersMapper;

@Override
publicMapqueryUserByIdBatch(ListuserReqs){
//全部參數(shù)
ListuserIds=userReqs.stream().map(UserWrapBatchService.Request::getUserId).collect(Collectors.toList());
QueryWrapperqueryWrapper=newQueryWrapper<>();
//用in語(yǔ)句合并成一條SQL,避免多次請(qǐng)求數(shù)據(jù)庫(kù)的IO
queryWrapper.in("id",userIds);
Listusers=usersMapper.selectList(queryWrapper);
Map>userGroup=users.stream().collect(Collectors.groupingBy(Users::getId));
HashMapresult=newHashMap<>();
userReqs.forEach(val->{
ListusersList=userGroup.get(val.getUserId());
if(!CollectionUtils.isEmpty(usersList)){
result.put(val.getRequestId(),usersList.get(0));
}else{
//表示沒(méi)數(shù)據(jù)
result.put(val.getRequestId(),null);
}
});
returnresult;
}
}

合并請(qǐng)求的實(shí)現(xiàn)

packagecom.springboot.sample.service.impl;

importcom.springboot.sample.bean.Users;
importcom.springboot.sample.service.UserService;
importorg.springframework.stereotype.Service;

importjavax.annotation.PostConstruct;
importjavax.annotation.Resource;
importjava.util.*;
importjava.util.concurrent.*;

/***
*zzq
*包裝成批量執(zhí)行的地方
**/
@Service
publicclassUserWrapBatchService{
@Resource
privateUserServiceuserService;

/**
*最大任務(wù)數(shù)
**/
publicstaticintMAX_TASK_NUM=100;


/**
*請(qǐng)求類,code為查詢的共同特征,例如查詢商品,通過(guò)不同id的來(lái)區(qū)分
*CompletableFuture將處理結(jié)果返回
*/
publicclassRequest{
//請(qǐng)求id唯一
StringrequestId;
//參數(shù)
LonguserId;
//TODOJava8的CompletableFuture并沒(méi)有timeout機(jī)制
CompletableFuturecompletableFuture;

publicStringgetRequestId(){
returnrequestId;
}

publicvoidsetRequestId(StringrequestId){
this.requestId=requestId;
}

publicLonggetUserId(){
returnuserId;
}

publicvoidsetUserId(LonguserId){
this.userId=userId;
}

publicCompletableFuturegetCompletableFuture(){
returncompletableFuture;
}

publicvoidsetCompletableFuture(CompletableFuturecompletableFuture){
this.completableFuture=completableFuture;
}
}

/*
LinkedBlockingQueue是一個(gè)阻塞的隊(duì)列,內(nèi)部采用鏈表的結(jié)果,通過(guò)兩個(gè)ReenTrantLock來(lái)保證線程安全
LinkedBlockingQueue與ArrayBlockingQueue的區(qū)別
ArrayBlockingQueue默認(rèn)指定了長(zhǎng)度,而LinkedBlockingQueue的默認(rèn)長(zhǎng)度是Integer.MAX_VALUE,也就是無(wú)界隊(duì)列,在移除的速度小于添加的速度時(shí),容易造成OOM。
ArrayBlockingQueue的存儲(chǔ)容器是數(shù)組,而LinkedBlockingQueue是存儲(chǔ)容器是鏈表
兩者的實(shí)現(xiàn)隊(duì)列添加或移除的鎖不一樣,ArrayBlockingQueue實(shí)現(xiàn)的隊(duì)列中的鎖是沒(méi)有分離的,即添加操作和移除操作采用的同一個(gè)ReenterLock鎖,
而LinkedBlockingQueue實(shí)現(xiàn)的隊(duì)列中的鎖是分離的,其添加采用的是putLock,移除采用的則是takeLock,這樣能大大提高隊(duì)列的吞吐量,
也意味著在高并發(fā)的情況下生產(chǎn)者和消費(fèi)者可以并行地操作隊(duì)列中的數(shù)據(jù),以此來(lái)提高整個(gè)隊(duì)列的并發(fā)性能。
*/
privatefinalQueuequeue=newLinkedBlockingQueue();

@PostConstruct
publicvoidinit(){
//定時(shí)任務(wù)線程池,創(chuàng)建一個(gè)支持定時(shí)、周期性或延時(shí)任務(wù)的限定線程數(shù)目(這里傳入的是1)的線程池
ScheduledExecutorServicescheduledExecutorService=Executors.newScheduledThreadPool(1);

scheduledExecutorService.scheduleAtFixedRate(()->{
intsize=queue.size();
//如果隊(duì)列沒(méi)數(shù)據(jù),表示這段時(shí)間沒(méi)有請(qǐng)求,直接返回
if(size==0){
return;
}
Listlist=newArrayList<>();
System.out.println("合并了["+size+"]個(gè)請(qǐng)求");
//將隊(duì)列的請(qǐng)求消費(fèi)到一個(gè)集合保存
for(inti=0;i//后面的SQL語(yǔ)句是有長(zhǎng)度限制的,所以還要做限制每次批量的數(shù)量,超過(guò)最大任務(wù)數(shù),等下次執(zhí)行
if(i//拿到我們需要去數(shù)據(jù)庫(kù)查詢的特征,保存為集合
ListuserReqs=newArrayList<>();
for(Requestrequest:list){
userReqs.add(request);
}
//將參數(shù)傳入service處理,這里是本地服務(wù),也可以把userService看成RPC之類的遠(yuǎn)程調(diào)用
Mapresponse=userService.queryUserByIdBatch(userReqs);
//將處理結(jié)果返回各自的請(qǐng)求
for(Requestrequest:list){
Usersresult=response.get(request.requestId);
request.completableFuture.complete(result);//completableFuture.complete方法完成賦值,這一步執(zhí)行完畢,下面future.get()阻塞的請(qǐng)求可以繼續(xù)執(zhí)行了
}
},100,10,TimeUnit.MILLISECONDS);
//scheduleAtFixedRate是周期性執(zhí)行schedule是延遲執(zhí)行initialDelay是初始延遲period是周期間隔后面是單位
//這里我寫(xiě)的是初始化后100毫秒后執(zhí)行,周期性執(zhí)行10毫秒執(zhí)行一次
}

publicUsersqueryUser(LonguserId){
Requestrequest=newRequest();
//這里用UUID做請(qǐng)求id
request.requestId=UUID.randomUUID().toString().replace("-","");
request.userId=userId;
CompletableFuturefuture=newCompletableFuture<>();
request.completableFuture=future;
//將對(duì)象傳入隊(duì)列
queue.offer(request);
//如果這時(shí)候沒(méi)完成賦值,那么就會(huì)阻塞,直到能夠拿到值
try{
returnfuture.get();
}catch(InterruptedExceptione){
e.printStackTrace();
}catch(ExecutionExceptione){
e.printStackTrace();
}
returnnull;
}
}

控制層調(diào)用

/***
*請(qǐng)求合并
**/
@RequestMapping("/merge")
publicCallablemerge(LonguserId){
returnnewCallable(){
@Override
publicUserscall()throwsException{
returnuserBatchService.queryUser(userId);
}
};
}

Callable是什么可以參考:

  • https://blog.csdn.net/baidu_19473529/article/details/123596792

模擬高并發(fā)查詢的代碼

packagecom.springboot.sample;

importorg.springframework.web.client.RestTemplate;

importjava.util.Random;
importjava.util.concurrent.CountDownLatch;

publicclassTestBatch{
privatestaticintthreadCount=30;

privatefinalstaticCountDownLatchCOUNT_DOWN_LATCH=newCountDownLatch(threadCount);//為保證30個(gè)線程同時(shí)并發(fā)運(yùn)行

privatestaticfinalRestTemplaterestTemplate=newRestTemplate();

publicstaticvoidmain(String[]args){


for(inti=0;i//循環(huán)開(kāi)30個(gè)線程
newThread(newRunnable(){
publicvoidrun(){
COUNT_DOWN_LATCH.countDown();//每次減一
try{
COUNT_DOWN_LATCH.await();//此處等待狀態(tài),為了讓30個(gè)線程同時(shí)進(jìn)行
}catch(InterruptedExceptione){
e.printStackTrace();
}

for(intj=1;j<=?3;j++){
intparam=newRandom().nextInt(4);
if(param<=0){
param++;
}
StringresponseBody=restTemplate.getForObject("http://localhost:8080/asyncAndMerge/merge?userId="+param,String.class);
System.out.println(Thread.currentThread().getName()+"參數(shù)"+param+"返回值"+responseBody);
}
}
}).start();

}
}
}

測(cè)試效果

283d32f8-92e3-11ed-bfe3-dac502259ad0.png284d3d4c-92e3-11ed-bfe3-dac502259ad0.png

要注意的問(wèn)題

  • Java 8 的 CompletableFuture 并沒(méi)有 timeout 機(jī)制
  • 后面的SQL語(yǔ)句是有長(zhǎng)度限制的,所以還要做限制每次批量的數(shù)量,超過(guò)最大任務(wù)數(shù),等下次執(zhí)行(本例中加了MAX_TASK_NUM判斷)

使用隊(duì)列的超時(shí)解決Java 8 的 CompletableFuture 并沒(méi)有 timeout 機(jī)制

核心代碼

packagecom.springboot.sample.service.impl;

importcom.springboot.sample.bean.Users;
importcom.springboot.sample.service.UserService;
importorg.springframework.stereotype.Service;

importjavax.annotation.PostConstruct;
importjavax.annotation.Resource;
importjava.util.*;
importjava.util.concurrent.*;

/***
*zzq
*包裝成批量執(zhí)行的地方,使用queue解決超時(shí)問(wèn)題
**/
@Service
publicclassUserWrapBatchQueueService{
@Resource
privateUserServiceuserService;

/**
*最大任務(wù)數(shù)
**/
publicstaticintMAX_TASK_NUM=100;


/**
*請(qǐng)求類,code為查詢的共同特征,例如查詢商品,通過(guò)不同id的來(lái)區(qū)分
*CompletableFuture將處理結(jié)果返回
*/
publicclassRequest{
//請(qǐng)求id
StringrequestId;

//參數(shù)
LonguserId;
//隊(duì)列,這個(gè)有超時(shí)機(jī)制
LinkedBlockingQueueusersQueue;


publicStringgetRequestId(){
returnrequestId;
}

publicvoidsetRequestId(StringrequestId){
this.requestId=requestId;
}

publicLonggetUserId(){
returnuserId;
}

publicvoidsetUserId(LonguserId){
this.userId=userId;
}

publicLinkedBlockingQueuegetUsersQueue(){
returnusersQueue;
}

publicvoidsetUsersQueue(LinkedBlockingQueueusersQueue){
this.usersQueue=usersQueue;
}
}

/*
LinkedBlockingQueue是一個(gè)阻塞的隊(duì)列,內(nèi)部采用鏈表的結(jié)果,通過(guò)兩個(gè)ReenTrantLock來(lái)保證線程安全
LinkedBlockingQueue與ArrayBlockingQueue的區(qū)別
ArrayBlockingQueue默認(rèn)指定了長(zhǎng)度,而LinkedBlockingQueue的默認(rèn)長(zhǎng)度是Integer.MAX_VALUE,也就是無(wú)界隊(duì)列,在移除的速度小于添加的速度時(shí),容易造成OOM。
ArrayBlockingQueue的存儲(chǔ)容器是數(shù)組,而LinkedBlockingQueue是存儲(chǔ)容器是鏈表
兩者的實(shí)現(xiàn)隊(duì)列添加或移除的鎖不一樣,ArrayBlockingQueue實(shí)現(xiàn)的隊(duì)列中的鎖是沒(méi)有分離的,即添加操作和移除操作采用的同一個(gè)ReenterLock鎖,
而LinkedBlockingQueue實(shí)現(xiàn)的隊(duì)列中的鎖是分離的,其添加采用的是putLock,移除采用的則是takeLock,這樣能大大提高隊(duì)列的吞吐量,
也意味著在高并發(fā)的情況下生產(chǎn)者和消費(fèi)者可以并行地操作隊(duì)列中的數(shù)據(jù),以此來(lái)提高整個(gè)隊(duì)列的并發(fā)性能。
*/
privatefinalQueuequeue=newLinkedBlockingQueue();

@PostConstruct
publicvoidinit(){
//定時(shí)任務(wù)線程池,創(chuàng)建一個(gè)支持定時(shí)、周期性或延時(shí)任務(wù)的限定線程數(shù)目(這里傳入的是1)的線程池
ScheduledExecutorServicescheduledExecutorService=Executors.newScheduledThreadPool(1);

scheduledExecutorService.scheduleAtFixedRate(()->{
intsize=queue.size();
//如果隊(duì)列沒(méi)數(shù)據(jù),表示這段時(shí)間沒(méi)有請(qǐng)求,直接返回
if(size==0){
return;
}
Listlist=newArrayList<>();
System.out.println("合并了["+size+"]個(gè)請(qǐng)求");
//將隊(duì)列的請(qǐng)求消費(fèi)到一個(gè)集合保存
for(inti=0;i//后面的SQL語(yǔ)句是有長(zhǎng)度限制的,所以還要做限制每次批量的數(shù)量,超過(guò)最大任務(wù)數(shù),等下次執(zhí)行
if(i//拿到我們需要去數(shù)據(jù)庫(kù)查詢的特征,保存為集合
ListuserReqs=newArrayList<>();
for(Requestrequest:list){
userReqs.add(request);
}
//將參數(shù)傳入service處理,這里是本地服務(wù),也可以把userService看成RPC之類的遠(yuǎn)程調(diào)用
Mapresponse=userService.queryUserByIdBatchQueue(userReqs);
for(RequestuserReq:userReqs){
//這里再把結(jié)果放到隊(duì)列里
Usersusers=response.get(userReq.getRequestId());
userReq.usersQueue.offer(users);
}

},100,10,TimeUnit.MILLISECONDS);
//scheduleAtFixedRate是周期性執(zhí)行schedule是延遲執(zhí)行initialDelay是初始延遲period是周期間隔后面是單位
//這里我寫(xiě)的是初始化后100毫秒后執(zhí)行,周期性執(zhí)行10毫秒執(zhí)行一次
}

publicUsersqueryUser(LonguserId){
Requestrequest=newRequest();
//這里用UUID做請(qǐng)求id
request.requestId=UUID.randomUUID().toString().replace("-","");
request.userId=userId;
LinkedBlockingQueueusersQueue=newLinkedBlockingQueue<>();
request.usersQueue=usersQueue;
//將對(duì)象傳入隊(duì)列
queue.offer(request);
//取出元素時(shí),如果隊(duì)列為空,給定阻塞多少毫秒再隊(duì)列取值,這里是3秒
try{
returnusersQueue.poll(3000,TimeUnit.MILLISECONDS);
}catch(InterruptedExceptione){
e.printStackTrace();
}
returnnull;
}
}
...省略..

@Override
publicMapqueryUserByIdBatchQueue(ListuserReqs){
//全部參數(shù)
ListuserIds=userReqs.stream().map(UserWrapBatchQueueService.Request::getUserId).collect(Collectors.toList());
QueryWrapperqueryWrapper=newQueryWrapper<>();
//用in語(yǔ)句合并成一條SQL,避免多次請(qǐng)求數(shù)據(jù)庫(kù)的IO
queryWrapper.in("id",userIds);
Listusers=usersMapper.selectList(queryWrapper);
Map>userGroup=users.stream().collect(Collectors.groupingBy(Users::getId));
HashMapresult=newHashMap<>();
//數(shù)據(jù)分組
userReqs.forEach(val->{
ListusersList=userGroup.get(val.getUserId());
if(!CollectionUtils.isEmpty(usersList)){
result.put(val.getRequestId(),usersList.get(0));
}else{
//表示沒(méi)數(shù)據(jù),這里要new,不然加入隊(duì)列會(huì)空指針
result.put(val.getRequestId(),newUsers());
}
});
returnresult;
}

...省略...

小結(jié)

請(qǐng)求合并,批量的辦法能大幅節(jié)省被調(diào)用系統(tǒng)的連接資源,本例是以數(shù)據(jù)庫(kù)為例,其他RPC調(diào)用也是類似的道理。缺點(diǎn)就是請(qǐng)求的時(shí)間在執(zhí)行實(shí)際的邏輯之前增加了等待時(shí)間,不適合低并發(fā)的場(chǎng)景。

代碼地址

  • https://gitee.com/apple_1030907690/spring-boot-kubernetes/tree/v1.0.5

參考

  • https://www.cnblogs.com/oyjg/p/13099998.html


審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8366

    瀏覽量

    150556
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8869

    瀏覽量

    84966
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    3739

    瀏覽量

    64176

原文標(biāo)題:效率加倍,高并發(fā)場(chǎng)景下的接口請(qǐng)求合并方案

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    測(cè)試聊并發(fā)-入門(mén)篇

    服務(wù)端接口的性能測(cè)試中,我們面臨的挑戰(zhàn)不僅僅是處理單個(gè)請(qǐng)求效率,更在于如何在多用戶同時(shí)訪問(wèn)時(shí)保持系統(tǒng)的穩(wěn)定性和響應(yīng)速度。并發(fā)編程和測(cè)試,作為性能測(cè)試的核心,對(duì)于評(píng)估系統(tǒng)在
    的頭像 發(fā)表于 10-15 15:23 ?87次閱讀
    測(cè)試聊<b class='flag-5'>并發(fā)</b>-入門(mén)篇

    使用帶有DVFS的DC/DC轉(zhuǎn)換器的Vin、高效率電源解決方案

    電子發(fā)燒友網(wǎng)站提供《使用帶有DVFS的DC/DC轉(zhuǎn)換器的Vin、高效率電源解決方案.pdf》資料免費(fèi)下載
    發(fā)表于 10-10 10:28 ?0次下載
    使用帶有DVFS的DC/DC轉(zhuǎn)換器的<b class='flag-5'>高</b>Vin、高<b class='flag-5'>效率</b>電源解決<b class='flag-5'>方案</b>

    并發(fā)物聯(lián)網(wǎng)云平臺(tái)是什么

    并發(fā)物聯(lián)網(wǎng)云平臺(tái)是一種能夠處理大量設(shè)備同時(shí)連接并進(jìn)行數(shù)據(jù)交換的云計(jì)算平臺(tái)。這種平臺(tái)通常被設(shè)計(jì)用來(lái)應(yīng)對(duì)來(lái)自數(shù)以萬(wàn)計(jì)甚至數(shù)十億計(jì)的物聯(lián)網(wǎng)設(shè)備的并發(fā)請(qǐng)求,保證系統(tǒng)的穩(wěn)定性和響應(yīng)速度。 首先
    的頭像 發(fā)表于 08-13 13:50 ?185次閱讀

    并發(fā)系統(tǒng)的藝術(shù):如何在流量洪峰中游刃有余

    尤為重要。用戶對(duì)在線服務(wù)的需求和期望不斷提高,系統(tǒng)的并發(fā)處理能力成為衡量其性能和用戶體驗(yàn)的關(guān)鍵指標(biāo)之一。并發(fā)系統(tǒng)不僅僅是大型互聯(lián)網(wǎng)企業(yè)的專利,對(duì)于任何希望在市場(chǎng)中占據(jù)一席之地的公司來(lái)說(shuō),能夠處理大量
    的頭像 發(fā)表于 08-05 13:43 ?180次閱讀
    <b class='flag-5'>高</b><b class='flag-5'>并發(fā)</b>系統(tǒng)的藝術(shù):如何在流量洪峰中游刃有余

    為何什么risc-v芯片比arm的效率高

    并不是絕對(duì)的,而是取決于具體的應(yīng)用場(chǎng)景、設(shè)計(jì)優(yōu)化等因素。 綜上所述,RISC-V芯片在某些情況可能相對(duì)于ARM架構(gòu)芯片表現(xiàn)出更高的效率,這主要得益于RISC-V設(shè)計(jì)的模塊化、開(kāi)源特性和在寄存器數(shù)目、指令數(shù)目等方面的優(yōu)勢(shì)。然而,
    發(fā)表于 04-28 09:38

    鴻蒙OS開(kāi)發(fā)實(shí)例:【工具類封裝-http請(qǐng)求

    ;@ohos.promptAction';** **封裝HTTP接口請(qǐng)求類,提供格式化的響應(yīng)信息輸出功能。 使用 DevEco Studio 3.1.1 Release 及以上版本,API 版本為 api 9 及以上
    的頭像 發(fā)表于 03-27 22:32 ?1222次閱讀
    鴻蒙OS開(kāi)發(fā)實(shí)例:【工具類封裝-http<b class='flag-5'>請(qǐng)求</b>】

    Golang根據(jù)job數(shù)量動(dòng)態(tài)控制每秒?yún)f(xié)程的最大創(chuàng)建數(shù)量方法簡(jiǎn)析

    需求:第三方的接口,限制接口請(qǐng)求的QPS,每秒5次
    的頭像 發(fā)表于 12-24 14:21 ?639次閱讀

    什么場(chǎng)景需要jvm調(diào)優(yōu)

    JVM調(diào)優(yōu)是指對(duì)Java虛擬機(jī)進(jìn)行性能優(yōu)化和資源管理,以提高應(yīng)用程序的運(yùn)行效率和吞吐量。JVM調(diào)優(yōu)的場(chǎng)景有很多,下面將詳細(xì)介紹各種不同的場(chǎng)景。
    的頭像 發(fā)表于 12-05 11:14 ?1270次閱讀

    redis并發(fā)能力直接相關(guān)概念有哪些

    Redis是一種高性能的開(kāi)源內(nèi)存數(shù)據(jù)庫(kù),具有出色的并發(fā)能力。為了實(shí)現(xiàn)并發(fā),需要有一些相關(guān)概念和技術(shù)。下面是關(guān)于Redis并發(fā)能力的詳細(xì)解
    的頭像 發(fā)表于 12-05 10:34 ?709次閱讀

    多線程并發(fā)查詢oracle數(shù)據(jù)庫(kù)

    數(shù)據(jù)庫(kù)的原理、使用場(chǎng)景、實(shí)現(xiàn)方法以及可能遇到的問(wèn)題和解決方案。 一、多線程并發(fā)查詢的原理 在傳統(tǒng)的單線程查詢方式中,當(dāng)一個(gè)查詢請(qǐng)求發(fā)起時(shí),數(shù)據(jù)庫(kù)會(huì)按照順序執(zhí)行查詢語(yǔ)句并返回結(jié)果。如果查
    的頭像 發(fā)表于 11-17 14:22 ?3400次閱讀

    Linux場(chǎng)景數(shù)據(jù)包是如何在協(xié)議層傳輸?shù)?/a>

    所有互聯(lián)網(wǎng)服務(wù),均依賴于TCP/IP協(xié)議棧。懂得數(shù)據(jù)是如何在協(xié)議棧傳輸?shù)?,將?huì)幫助你提升互聯(lián)網(wǎng)程序的性能和解決TCP相關(guān)問(wèn)題的能力。 我們講述在Linux場(chǎng)景數(shù)據(jù)包是如何在協(xié)議層傳輸?shù)摹?1、發(fā)送
    的頭像 發(fā)表于 11-11 11:33 ?1029次閱讀
    Linux<b class='flag-5'>場(chǎng)景</b><b class='flag-5'>下</b>數(shù)據(jù)包是如何在協(xié)議層傳輸?shù)? />    </a>
</div>                            <div   id=

    api網(wǎng)關(guān) kong 教程入門(mén)

    統(tǒng)一權(quán)限控制、接口請(qǐng)求訪問(wèn)日志統(tǒng)計(jì) 安全,是保護(hù)內(nèi)部服務(wù)而設(shè)計(jì)的一道屏障 開(kāi)源-最大好處 當(dāng)然也有一個(gè)很大的缺點(diǎn),api-gw很可能成為性能瓶頸,因?yàn)樗械?b class='flag-5'>請(qǐng)求都經(jīng)過(guò)這里,可以通過(guò)橫向擴(kuò)展和限流解決這個(gè)問(wèn)題。 在眾多API GATEWAY框架中,Mashape開(kāi)源的高性
    的頭像 發(fā)表于 11-10 11:39 ?656次閱讀
    api網(wǎng)關(guān) kong 教程入門(mén)

    服務(wù)器并發(fā)的概念

    自己調(diào)整系統(tǒng)的相關(guān)參數(shù) 并發(fā)的概念是什么?什么是并發(fā)? 對(duì)于服務(wù)器并發(fā)的概念,下面幾點(diǎn)是錯(cuò)誤的定義 ①服務(wù)器處理客戶端請(qǐng)求的數(shù)量:沒(méi)有時(shí)間、空間等限制,因此不能作為
    的頭像 發(fā)表于 11-10 10:05 ?4220次閱讀
    服務(wù)器<b class='flag-5'>并發(fā)</b>的概念

    輻射騷擾整改思路及方法:方案合并與原理探究 ?

    輻射騷擾整改思路及方法:方案合并與原理探究 ?|深圳比創(chuàng)達(dá)電子EMC
    的頭像 發(fā)表于 11-09 11:22 ?567次閱讀
    輻射騷擾整改思路及方法:<b class='flag-5'>方案</b><b class='flag-5'>合并</b>與原理探究 ?

    并發(fā)內(nèi)存池項(xiàng)目實(shí)現(xiàn)

    本項(xiàng)目實(shí)現(xiàn)了一個(gè)并發(fā)內(nèi)存池,參考了Google的開(kāi)源項(xiàng)目tcmalloc實(shí)現(xiàn)的簡(jiǎn)易版;其功能就是實(shí)現(xiàn)高效的多線程內(nèi)存管理。由功能可知,并發(fā)指的是高效的多線程,而內(nèi)存池則是實(shí)現(xiàn)內(nèi)存管
    的頭像 發(fā)表于 11-09 11:16 ?627次閱讀
    <b class='flag-5'>高</b><b class='flag-5'>并發(fā)</b>內(nèi)存池項(xiàng)目實(shí)現(xiàn)