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

Springboot配置@Async無效的解決方案

 更新時間:2023年09月27日 09:57:50   作者:唐宋xy  
這篇文章主要介紹了Springboot配置@Async無效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

Springboot配置@Async無效

Springboot中為了同時執(zhí)行多個任務,或者同時查詢,加快查詢則使用多線程查詢,在springboot中,可以直接使用 @Async注解來實現(xiàn)異步任務,可以參考Springboot使用@Async實現(xiàn)異步任務簡單快捷使用,但是異步任務在某些情況下居然無效。

配置正確,代碼不報錯,但是無法使用多線程異步任務,可能是下面的原因?qū)е拢?/strong>

1.沒有在springboot啟動類當中添加注解 @EnableAsync注解。

2.異步方法使用注解@Async的返回值只能為void或者Future。

3.沒有走Spring的代理類。

因為@Transactional和@Async注解的實現(xiàn)都是基于Spring的AOP,而AOP的實現(xiàn)是基于動態(tài)代理實現(xiàn)的。

那么注解失效的原因就很明顯了,有可能因為調(diào)用方法的是對象本身而不是代理對象,沒有經(jīng)過Spring容器,無法使用代理對象調(diào)用。

4.注解的方法必須是 public 方法。編譯時非public方法會報錯

5.如果需要從 類的內(nèi)部 調(diào)用,需要先獲取其代理類

先注入ApplicationContext

@Autowired
private ApplicationContext applicationContext;

然后在方法中通過ApplicationContext對象獲取當前類對象

applicationContext.getBean(Class);

6.調(diào)用的是靜態(tài)(static )方法,也會導致注解失效,因為注解是基于代理對象調(diào)用,而static方法是屬于類的,無法通過spring的代理對象直接調(diào)用

Springboot @Async失效的坑

異步應用場景

為了提高接口的響應性能,當業(yè)務非常復雜的情況下,可以將一部分跟業(yè)務關聯(lián)性不是特別強的邏輯進行異步處理。如日志記錄、短信發(fā)送、增加積分等。

通常而言會將此類業(yè)務邏輯通過異步的方式進行處理,從而加快接口的響應速度,常用的解決方案有:

  • 使用JDK 自定義線程池 讓代碼異步執(zhí)行
  • 在springboot 中 使用@Async注解進行異步處理
  • 使用中間件如mq 消息通知讓下游異步消費 如RocketMQ、KAFKA

使用第一種方式,需要精通線程池運行原理,結(jié)合實際的業(yè)務場景對隊列大小進行合理的設置。隊列設置過大過小都會存在內(nèi)存溢出的風險。

第三種方式是最合理的方式,它能夠通過MQ進行削峰填谷,通過合理的參數(shù)配置,保證數(shù)據(jù)不會丟失。但是架構改動過大,對小型的單體應用來講,工作量過大,成本過高。

在springboot 大行其道的情況下,考慮開發(fā)成本,以及項目時間關系選用第二種方式來解決代碼異步執(zhí)行的問題。

真實業(yè)務場景

線上問題

一個工單的分頁列表,前端控制了每個列表最大的顯示條數(shù)為100條。在業(yè)務流程中存在工單轉(zhuǎn)移的操作,轉(zhuǎn)移一筆工單至少包含以下幾個重要的步驟:

  • 新增工單處理日志,如什么時間點將工單轉(zhuǎn)移給某人
  • 修改工單當前處理人
  • 發(fā)送企業(yè)微信給B端的跟進人(轉(zhuǎn)移人)
  • 發(fā)送im信息給C端的用戶

由于公司采用微服務架構,因此每個業(yè)務模塊拆分的很細,在上述步驟中需要從其他系統(tǒng)中通過rpc調(diào)用接口拿到需要的數(shù)據(jù)才能完成整個業(yè)務流程數(shù)據(jù)的拼裝,如需要從crm系統(tǒng)拿到組織架構信息,獲取轉(zhuǎn)移人的組織架構、需要從udb用戶中心獲取轉(zhuǎn)移人的企業(yè)微信昵稱等。

因此在批量轉(zhuǎn)移的時候,前端會出現(xiàn)調(diào)用超時的問題,原因是dubbo接口默認的超時時間是15秒,由于業(yè)務復雜,導致在15秒內(nèi)執(zhí)行不完業(yè)務邏輯。

解決方案

  • 將sql處理改為批量執(zhí)行,如新增處理日志 (batch insert);修改當前工單,使用case when 的方式一次性修改完成(批量update)
  • 將發(fā)送消息改成異步處理 加快前端接口的響應速度
  • 讓接口提供方提供批量查詢的接口,避免rpc 循環(huán)調(diào)用在網(wǎng)絡上的消耗

優(yōu)化完成之后,接口的響應速度由15秒多,變成了1秒。但是過程中遇到坑了。特此記錄一下

技術實現(xiàn)

優(yōu)化過程

@Async 注解定義為可以放置在方法上和類上,當使用在類上表明類所有的方法都能異步執(zhí)行。

在Springboot中是需要在方法上加上該注解就可以完美的實現(xiàn)異步執(zhí)行。

原始方法偽代碼如下

/**
 * 原始代碼 采用流水式的代碼一步步實現(xiàn) 業(yè)務邏輯
 */
public void doBusiness(Object args){
  //1.  新增工單處理日志,如什么時間點將工單轉(zhuǎn)移給某人
  //2. 修改工單當前處理人
  //3. 發(fā)送企業(yè)微信給B端的跟進人(轉(zhuǎn)移人)
  //4. 發(fā)送im信息給C端的用戶
}

那么異步問題就很好處理了,只需要將方法抽離形成多個子方法, 每個方法執(zhí)行自己的業(yè)務處理邏輯,然后再方法加上@Async注解不就ok了么,偽代碼如下

public void doBusiness(Object args){
 	//2. 修改工單當前處理人
  this.doAsyncBusiness();
}
// 單獨抽離一個異步執(zhí)行的方法 加上@Async注解
@Async
private void doAsyncBusiness(Object args){
  //1.  新增工單處理日志,如什么時間點將工單轉(zhuǎn)移給某人
  //3. 發(fā)送企業(yè)微信給B端的跟進人(轉(zhuǎn)移人)
  //4. 發(fā)送im信息給C端的用戶
}

打完收工,重啟應用,進行測試,然而并沒有像預期中的那樣,接口的響應速度還是15秒左右。接著排查原因,可以肯定的是@Async是可以提供異步方法執(zhí)行。應該是我們使用方式不對導致。

@Async 限制

熟悉Springboot AOP的同學可能會發(fā)現(xiàn)更改后的代碼存在明顯的問題

  • 首先AOP代理機制要求 被代理的方法必須是 public , private 方法不能被代理
  • 其次AOP代理機制會生成一個代理類 執(zhí)行代理方法 注意 this.doAsyncBusiness() 調(diào)用的是本對象的方法 ;
  • 在啟動類上加上@EnableAsync注解

綜上所述,原因我們已經(jīng)通過AOP代理的原理找到了。下面摘自官方文檔的一段話:

  • it must be applied to public methods only
  • self-invocation – calling the async method from within the same class – won’t work

The reasons are simple – 「the method needs to be public」 so that it can be proxied. And 「self-invocation doesn’t work」 because it bypasses the proxy and calls the underlying method directly.

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 利用Intellij Idea連接遠程服務器實現(xiàn)遠程上傳部署功能

    利用Intellij Idea連接遠程服務器實現(xiàn)遠程上傳部署功能

    大家在使用Intellij Idea開發(fā)程序的時候,是不是需要部署到遠程SSH服務器運行呢,當然也可以直接在idea軟件內(nèi)容實現(xiàn)配置部署操作,接下來通過本文給大家分享利用Intellij Idea連接遠程服務器實現(xiàn)遠程上傳部署功能,感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • 詳解Spring 注解之@Import 注入的各種花活

    詳解Spring 注解之@Import 注入的各種花活

    這篇文章主要介紹了詳解Spring 注解之@Import 注入的各種花活,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • Java變量與運算符用法詳解

    Java變量與運算符用法詳解

    這篇文章介紹了Java中的關鍵字、標識符、變量、基本數(shù)據(jù)類型、變量作用域、基本數(shù)據(jù)類型間的運算、字符串、基本數(shù)據(jù)類型與字符串的運算、計算機底層數(shù)據(jù)存儲、運算符的使用、賦值運算符、比較運算符、邏輯運算符、位運算符和條件運算符用法,感興趣的朋友跟隨小編看看吧
    2026-01-01
  • Java之Thread的join方法實例

    Java之Thread的join方法實例

    這篇文章主要介紹了Java之Thread的join方法,實例形式講述了join方法的應用,需要的朋友可以參考下
    2014-10-10
  • RepeatSubmit若依框架如何防止表單重復提交注解

    RepeatSubmit若依框架如何防止表單重復提交注解

    若依框架中的@RepeatSubmit注解用于防止表單重復提交,通過在控制器方法上添加該注解,并在前端頁面和JavaScript代碼中實現(xiàn)雙重校驗,可以確保同一用戶在短時間內(nèi)不會重復提交相同的表單
    2024-11-11
  • 用java生成html文件實現(xiàn)原理及代碼

    用java生成html文件實現(xiàn)原理及代碼

    用printStream來向html文件里輸出數(shù)據(jù),先創(chuàng)建一個StringBuilder對象,通過append方法來為其添加html語句,具體實現(xiàn)如下,感興趣的朋友可以參考下,希望對大家有所幫助
    2013-08-08
  • springboot springmvc拋出全局異常的解決方法

    springboot springmvc拋出全局異常的解決方法

    這篇文章主要為大家詳細介紹了springboot springmvc拋出全局異常的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Java的Hibernate框架中的雙向主鍵關聯(lián)與雙向外鍵關聯(lián)

    Java的Hibernate框架中的雙向主鍵關聯(lián)與雙向外鍵關聯(lián)

    Hibernate想要實現(xiàn)雙向的關聯(lián)就必須在映射文件的兩端同時配置<one-to-one>,另外還要在主映射的一端采用foreign外鍵關聯(lián)屬性,下面我們就一起來看一下Java的Hibernate框架中的雙向主鍵關聯(lián)與雙向外鍵關聯(lián)方法:
    2016-06-06
  • 淺談Java響應式系統(tǒng)

    淺談Java響應式系統(tǒng)

    第一次聽到reactive這個詞還是在幾年前,偶然了解到了Rxjava這個項目,仿佛為我打開了一扇新的大門,Rxjava是ReactiveX的java實現(xiàn),ReactiveX家族除了Rxjava還有RxJS, Rx.NET,RxScala等等。
    2021-06-06
  • Java設計模式之責任鏈模式

    Java設計模式之責任鏈模式

    今天小編就為大家分享一篇關于Java設計模式之責任鏈模式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01

最新評論

临沭县| 无棣县| 当涂县| 宁都县| 石阡县| 靖宇县| 嘉鱼县| 凉城县| 墨江| 奉新县| 色达县| 沧源| 神池县| 瑞安市| 明星| 筠连县| 来安县| 阜城县| 曲阳县| 宜章县| 安国市| 肇东市| 徐州市| 宜昌市| 高雄市| 时尚| 遂川县| 桂林市| 靖远县| 聊城市| 邳州市| 淳安县| 平舆县| 云浮市| 巩义市| 吐鲁番市| 九龙坡区| 伊通| 淮阳县| 通城县| 志丹县|