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

spring-boot項目啟動遲緩異常排查解決記錄

 更新時間:2022年02月25日 16:16:35   作者:kl  
這篇文章主要為大家介紹了spring-boot項目啟動遲緩異常排查解決記錄,突然在本地啟動不起來了,表象特征就是在本地IDEA上運行時,進程卡住也不退出,應用啟動時加載相關組件的日志也不輸出

問題背景

一個spring boot開發(fā)的項目,spring boot版本是1.5.7,攜帶的spring版本是4.1.3。開發(fā)反饋,突然在本地啟動不起來了,表象特征就是在本地IDEA上運行時,進程卡住也不退出,應用啟動時加載相關組件的日志也不輸出。癥狀如下圖:

問題分析

因為沒有有用的日志信息,所以不能從日志這個層面上排查問題。但是像這種沒有輸出日志的話,一般情況下,肯定是程序內(nèi)部啟動流程卡在什么地方了,只能通過打印下當前線程堆棧信息了解下。一般情況下,在服務器環(huán)境,我們會使用java工具包中的jstack 工具來查看:如jstack pid(應用java進程)。

但是,在IDEA本地開發(fā)的話,IDEA內(nèi)置了一個工具,可以直接查看當前應用的線程上線文信息,如:

注意下面那個箭頭指向的像照相機一樣的圖標,故圖思意,就是打印當前線程快照的的意思。點擊后,就出現(xiàn)了右邊那些線程上下文信息了,可以看到有很多的線程,我們主要關注下main線程,線程狀態(tài)確實是waiting的,接著點擊箭頭所指向的main線程,可以看到如下內(nèi)容:

"main@1" prio=5 tid=0x1 nid=NA waiting
java.lang.Thread.State: WAITING
at sun.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
at org.springframework.boot.autoconfigure.BackgroundPreinitializer.onApplicationEvent(BackgroundPreinitializer.java:63)
at org.springframework.boot.autoconfigure.BackgroundPreinitializer.onApplicationEvent(BackgroundPreinitializer.java:45)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:158)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.finished(EventPublishingRunListener.java:115)
at org.springframework.boot.SpringApplicationRunListeners.callFinishedListener(SpringApplicationRunListeners.java:79)
at org.springframework.boot.SpringApplicationRunListeners.finished(SpringApplicationRunListeners.java:72)
at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:745)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:134)
- locked(a java.util.concurrent.atomic.AtomicBoolean)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:175)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:98)
at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:64)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:325)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:296)
at cn.keking.project.customerManagement.KekingCustomerManagement.main(KekingCustomerManagement.java:36)

可以看到是通過CountDownLatch.await()阻塞了線程,接著看下面那行,所在代碼塊如下:

private static final CountDownLatch preinitializationComplete = new CountDownLatch(1);
@Override
public void onApplicationEvent(SpringApplicationEvent event) {
   if (event instanceof ApplicationEnvironmentPreparedEvent) {
      if (preinitializationStarted.compareAndSet(false, true)) {
         performPreinitialization();
      }
   }
   if (event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) {
      try {
         preinitializationComplete.await();
      }
      catch (InterruptedException ex) {
         Thread.currentThread().interrupt();
      }
   }
}

這是spring boot中的一個安全初始化資源的一個類,代碼所示為監(jiān)聽SpringApplicationEvent事件,可以肯定的是,它的邏輯執(zhí)行到了 preinitializationComplete.await();這里,導致了線程阻塞了。正常情況下,spring會觸發(fā)ApplicationEnvironmentPreparedEvent事件完成資源的初始化,這里先不深究Spring為什么這么做,主要通過程序邏輯看下為什么卡這里了,在preinitializationComplete.await();所在行打個斷點,看下event對象里的信息,如下:

原來event是一個Spring上下文初始化失敗的異常事件對象,對象里包含了具體的異常信息,如箭頭所指,關鍵異常信息如:

NoSuchMethodError:"org.springframework.util.ObjectUtils.

unwrapOptional(Ljava/lang/Object;)Ljava/lang/Object;"

假設問題

通過上面的分析,基本定位到Spring boot應用啟動卡住這個表象背后的真實原因了,而且也定位到了異常信息。

出現(xiàn)NoSuchMethodError異常,是因為調(diào)用方法的時候,找不到方法了。一般出現(xiàn)在兩個有關聯(lián)的jar包,但是版本對不上了,也就是常說的jar版本依賴沖突。查看了下,ObjectUtils是spring-core包里的一個類,當前的4.1.3版本確實沒有這個unwrapOptional方法,spring-core-5.x的版本才新增了這個方法。因為之前的依賴是沒有問題,為什么現(xiàn)在spring上下文會調(diào)用5.x的版本的方法呢?

所以先假設近期有開發(fā)在pom.xml里添加了新的的依賴,導致了這個問題。

小心求證

有了找問題的方向就好辦了,因為代碼都是git管理維護的,所以查看下pom.xml文件近期的提交記錄即可,查看后,確實發(fā)現(xiàn)了近期對pom.xml有改動,添加了一個依賴:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.6.RELEASE</version>
</dependency>

這里還涉及到一點Maven依賴優(yōu)先級的問題,在pom.xml里直接這樣添加的依賴優(yōu)先于其他jar中pom.xml依賴的,也就是說,即使spring boot1.5.7自帶了Spring-context.4.1.3,但是這樣指定后,應用最后依賴的還是5.1.6的版本。具體的Maven依賴關系,可以參考我的博文《關于Maven的使用,這些你都了解了么?》。結合之前的分析,八九不離十了就是因為加了這個依賴導致的問題,spring-context.5.1.6配合spring-core.4.1.3肯定得出問題啊。直接移除這個依賴,然后啟動系統(tǒng)一切正常,日志打印了Spring加載上線文的信息。

問題總結

定位這個問題的關鍵在于要了解java中線程堆棧的知識,在沒有足夠異常日志情況下通過線程快照排查問題。在定位到問題后,如NoSuchMethodError這樣的異常,需要平時的經(jīng)驗積累來假設問題的真實原因,然后在追本溯源驗明問題所在根本原因。找問題本質(zhì)一定要這種循序漸進的思路。舉例,出現(xiàn)這種問題,如果你直接去搜索引擎搜:“Spring boot應用啟動卡住了”,是搜不出來什么東西的,但是當你發(fā)現(xiàn)了是由于jar沖突。去搜索引擎搜索:

“NoSuchMethodError:"org.springframework.util.ObjectUtils.

unwrapOptional(Ljava/lang/Object;)Ljava/lang/Object;"”。

就會有很多的內(nèi)容,很容易解決問題。

以上就是spring-boot項目啟動遲緩異常排查解決記錄的詳細內(nèi)容,更多關于spring-boot項目啟動遲緩異常排查的資料請關注腳本之家其它相關文章!

相關文章

  • Spring Boot高級教程之使用Redis實現(xiàn)session共享

    Spring Boot高級教程之使用Redis實現(xiàn)session共享

    這篇文章主要為大家詳細介紹了Spring Boot高級教程之使用Redis實現(xiàn)session共享,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • SpringBoot+Vue+Flowable模擬實現(xiàn)請假審批流程

    SpringBoot+Vue+Flowable模擬實現(xiàn)請假審批流程

    這篇文章主要為大家詳細介紹了如何利用SpringBoot+Vue+Flowable模擬實現(xiàn)一個請假審批流程,文中的示例代碼講解詳細,需要的可以參考一下
    2022-08-08
  • springboot使用定時器@Scheduled不管用的解決

    springboot使用定時器@Scheduled不管用的解決

    這篇文章主要介紹了springboot使用定時器@Scheduled不管用的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java如何在不存在文件夾的目錄下創(chuàng)建文件

    Java如何在不存在文件夾的目錄下創(chuàng)建文件

    這篇文章主要介紹了Java如何在不存在文件夾的目錄下創(chuàng)建文件,代碼簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-08-08
  • JAVA DOM解析XML文件過程詳解

    JAVA DOM解析XML文件過程詳解

    這篇文章主要介紹了JAVA DOM解析XML文件過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • 簡單講解奇偶排序算法及在Java數(shù)組中的實現(xiàn)

    簡單講解奇偶排序算法及在Java數(shù)組中的實現(xiàn)

    這篇文章主要介紹了奇偶排序算法及Java數(shù)組的實現(xiàn),奇偶排序的時間復雜度為O(N^2),需要的朋友可以參考下
    2016-04-04
  • Spring設計模式中代理模式詳細講解

    Spring設計模式中代理模式詳細講解

    如何實現(xiàn)在不修改源碼的基礎上實現(xiàn)代碼功能的增強呢?spring為我們提供了代理模式。所謂的代理模式通俗來說就是一個中介,它給某一個對象提供一個代理對象,并由代理對象控制原對象的引用,從而實現(xiàn)在不修改源碼的基礎上實現(xiàn)代碼功能的增強
    2023-01-01
  • 一文帶你了解Java中的ForkJoin

    一文帶你了解Java中的ForkJoin

    這篇文章主要介紹了一文帶你了解Java中的ForkJoin,F(xiàn)orkJoinTask本身的依賴關系并不復雜,它與異步任務計算FutureTask一樣均實現(xiàn)了Future接口,下文更多相關資料,需要的小伙伴可以參考一下
    2022-04-04
  • Java中String的split切割字符串方法實例及擴展

    Java中String的split切割字符串方法實例及擴展

    最近在項目中遇到一個小問題,一個字符串分割成一個數(shù)組,下面這篇文章主要給大家介紹了關于Java中String的split切割字符串方法的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • SpringSecurity JWT基于令牌的無狀態(tài)認證實現(xiàn)

    SpringSecurity JWT基于令牌的無狀態(tài)認證實現(xiàn)

    Spring Security中實現(xiàn)基于JWT的無狀態(tài)認證是一種常見的做法,本文就來介紹一下SpringSecurity JWT基于令牌的無狀態(tài)認證實現(xiàn),感興趣的可以了解一下
    2025-04-04

最新評論

莫力| 慈溪市| 海兴县| 华坪县| 虹口区| 大方县| 牟定县| 台湾省| 阿坝| 左权县| 万全县| 大港区| 巴楚县| 中卫市| 静海县| 隆德县| 大宁县| 九龙城区| 虹口区| 天气| 甘谷县| 华阴市| 泸溪县| 北票市| 车险| 广安市| 扬州市| 高尔夫| 株洲县| 常熟市| 蒙自县| 秭归县| 无极县| 淮滨县| 故城县| 英山县| 三都| 广饶县| 鄂托克旗| 洪雅县| 华亭县|