spring?batch線上異常定位記錄
前言
最近線上spring batch的一個問題圍繞博主近兩周時間,甚是擾神。具體現(xiàn)象為,spring batch執(zhí)行中莫名其妙線程就卡住了,不往下走了。下面會詳細(xì)描述整個問題的排查過程
環(huán)境說明
spring batch分區(qū)環(huán)境,共6個分片,兩臺實(shí)例,分別6個線程處理,由xxljob任務(wù)調(diào)度觸發(fā)日切job,配置由apollo管理。
排查過程
1.xxljob長連接導(dǎo)致
why?因?yàn)槲覀冇许?xiàng)目是老項(xiàng)目,任務(wù)調(diào)度使用的quartz,原來的批處理沒啥毛病。
然后修改了dayEndjob的觸發(fā)執(zhí)行改為異步,發(fā)現(xiàn)問題依舊。
2.定位JpaPagingItemReader的問題
盯著BATCH_STEP_EXECUTION看了很久,發(fā)現(xiàn)其他的step_execution都是啟動中的狀態(tài),其中兩個step_execution是讀取中,并且和其他step_execution明顯區(qū)別version版本一直在增加,初步判斷有線程一直在修改.但是日志一點(diǎn)動靜都沒有,如果是線程阻塞了,肯定也不存在線程修改數(shù)據(jù)庫數(shù)據(jù)。然后在apollo把日志級別調(diào)整成DEBUG級別(spring boot線上日志級別動態(tài)調(diào)整),發(fā)現(xiàn)輸出大量的如下日志信息
java.lang.IllegalStateException: Transaction already active
at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:42)
at org.springframework.batch.item.database.JpaPagingItemReader.doReadPage(JpaPagingItemReader.java:197)
at org.springframework.batch.item.database.AbstractPagingItemReader.doRead(AbstractPagingItemReader.java:108)
at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:88)
at org.springframework.batch.item.support.SynchronizedItemStreamReader.read(SynchronizedItemStreamReader.java:55)
at sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133)
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy126.read(Unknown Source)
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91)
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:87)
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:116)
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:374)
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:110)
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:272)
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81)
at org.springframework.batch.repeat.support.TaskExecutorRepeatTemplate$ExecutingRunnable.run(TaskExecutorRepeatTemplate.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)3.確定JpaPagingItemReader的問題
因?yàn)轫?xiàng)目使用了jpa。故而數(shù)據(jù)讀取器用用了JpaPagingItemReader,從異常信息找到JpaPagingItemReader文件后發(fā)現(xiàn),JpaPagingItemReader根據(jù)配置的transacted=true,編程式的開啟了事務(wù),而提交事務(wù)和回滾事務(wù)并沒有作try,catch處理,而一旦拋出了如上事務(wù)異常,因?yàn)镕aultTolerantChunkProvider 讀取數(shù)據(jù)實(shí)現(xiàn)如下

就會進(jìn)入一個一直拋異常的死循環(huán),至此所有問題都清晰明了了。
解決問題
參照J(rèn)paPagingItemReader既有的實(shí)現(xiàn),自定義一個CustomJpaPagingItemReader閱讀器,去掉事務(wù)部分代碼,或者實(shí)例化JpaPagingItemReader的時候設(shè)置transacted為false。這個參數(shù)主要用途我猜測是為了讓用戶自己選擇查詢出來的對象是否為entityManager管理的游離態(tài)。我們項(xiàng)目用不著,就直接去掉事務(wù)部分了。一般如果查詢沒問題,不會有如上情況,這個bug也是隱藏的深,死循環(huán)后info日志級別下沒有任何輸出,就和線程阻塞似的。解決這個問題后感覺神清氣爽啊
以上就是spring batch線上異常定位記錄的詳細(xì)內(nèi)容,更多關(guān)于spring batch線上異常定位的資料請關(guān)注腳本之家其它相關(guān)文章!
- 如何使用Spring Batch進(jìn)行批處理任務(wù)管理
- 使用Spring?Batch實(shí)現(xiàn)大數(shù)據(jù)處理的操作方法
- 使用Spring Batch實(shí)現(xiàn)批處理任務(wù)的詳細(xì)教程
- SpringBoot整合Spring Batch示例代碼
- SpringBatch結(jié)合SpringBoot簡單使用實(shí)現(xiàn)工資發(fā)放批處理操作方式
- Spring?Batch實(shí)現(xiàn)批量處理
- Spring?Batch批處理框架操作指南
- SpringBatch數(shù)據(jù)寫入實(shí)現(xiàn)
相關(guān)文章
SpringBoot讀取properties或者application.yml配置文件中的數(shù)據(jù)
這篇文章主要介紹了SpringBoot讀取properties或者application.yml配置文件中的數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Java線程池ThreadPoolExecutor源碼深入分析
ThreadPoolExecutor作為java.util.concurrent包對外提供基礎(chǔ)實(shí)現(xiàn),以內(nèi)部線程池的形式對外提供管理任務(wù)執(zhí)行,線程調(diào)度,線程池管理等等服務(wù)2022-08-08
實(shí)現(xiàn)quartz定時器及quartz定時器原理介紹
Quartz是一個大名鼎鼎的Java版開源定時調(diào)度器,功能強(qiáng)悍,使用方便,下面我們看看如何使用它2013-12-12
解決org.apache.ibatis.binding.BindingException:?Invalid?boun
這篇文章主要介紹了解決org.apache.ibatis.binding.BindingException:?Invalid?bound?statement?(not?found)問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05
java實(shí)現(xiàn)字符串和日期類型相互轉(zhuǎn)換的方法
這篇文章主要介紹了java實(shí)現(xiàn)字符串和日期類型相互轉(zhuǎn)換的方法,涉及java針對日期與字符串的轉(zhuǎn)換與運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-02-02

