一場HttpClient呼叫未關閉流引發的問題
最近生產環境出現了一個問題,就是Job服務日誌好端端的不列印日誌了,服務也沒有掛, 現在將此次問題解決過程記錄下來~
問題描述
生產環境有一臺Job伺服器,是專門用來跑所有定時任務的,然後有一天發現定時任務好像沒有執行,所以上Job伺服器檢視日誌,結果發現的情況是:
最後列印的是昨天晚上九點半的,到我看的時候就一直沒有日誌,沒有日誌就沒有執行Job;當時為了快速解決問題就重啟了伺服器,Job就正常執行了;後來第二天上去看的時候居然又停止了, 但是Job的JVM是還在的,並沒有掛掉,就是沒有日誌,看起來就是被阻塞了一樣;
這個時候又把生成環境重啟讓他先正常執行,然後立馬去測試環境看看能不能重現, 結果測試環境的日誌也是一樣
問題程式碼
//允許非同步執行 Schedule
@EnableAsync
@Component
public class TestSchedule {
private static final Logger LOGGER = LoggerFactory.getLogger(LotterySchedule.class);
// 使用執行緒池myAsync來執行這個Job
@Async("myAsync")
@Scheduled(cron = "0/1 * * * * ?")
public void testDoGet(){
LOGGER. info("\ntestDoGet:"+Thread.currentThread());
//業務程式碼:裡面呼叫了 String json = HttpUtil.doGet(url);來呼叫第三方介面
HttpUtil.doGet("www.baidu.com")
}
//這裡沒有用非同步執行,單執行緒執行
@Scheduled(cron = "0/1 * * * * ?")
public void testPrint(){
LOGGER.info("\ntestPrint:"+Thread.currentThread());
}
}
然後看看執行緒池的程式碼
@Configuration
@EnableAsync
public class ExecutorConfig {
/** Set the ThreadPoolExecutor's core pool size. */
private int corePoolSize = 10;
/** Set the ThreadPoolExecutor's maximum pool size. */
private int maxPoolSize = 25;
/** Set the capacity for the ThreadPoolExecutor's BlockingQueue. */
private int queueCapacity = 10;
@Bean
public Executor myAsync() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix("MyJobExecutor-");
// rejection-policy:當pool已經達到max size的時候,如何處理新任務
// CALLER_RUNS:不在新執行緒中執行任務,而是有呼叫者所在的執行緒來執行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
1.檢視JVM情況
jps 查詢Jvm程序號
查詢Jvm jstat -gc 21738 5000
發現Jvm好像沒有出現頻繁GC,GC處理異常的情況,而且Jvm啟動也配置了:+HeapDumpOnOutOfMemoryError;但是沒有看到記憶體溢位的Dump檔案;排除 Jvm異常的情況
2.檢視執行緒棧分析
jps 查詢Jvm程序號
jstack -l 22741 查詢執行緒棧資訊
"MyJobExecutor-2" #25 prio=5 os_prio=31 tid=0x00007fc7f7374800 nid=0xa203 waiting on condition [0x0000700004def000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000742196c58> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:380)
at org.apache.http.pool.AbstractConnPool.access$200(AbstractConnPool.java:69)
at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:246)
- locked <0x00000007969b6910> (a org.apache.http.pool.AbstractConnPool$2)
at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:193)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:303)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:279)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:191)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at com.xxx.util.HttpUtil.doGet(HttpUtil.java:97)
at com.xxx.util.HttpUtil.doGet(HttpUtil.java:70)
省略
at
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$392/226041624.proceedWithInvocation(Unknown Source)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.bfc.service.impl.LotteryHbkuai3MainServiceImpl$$EnhancerBySpringCGLIB$$4d3de61.publishPreByJob(<generated>)
at com.bfc.job.LotterySchedule.publishByJob(LotterySchedule.java:45)
at com.bfc.job.LotterySchedule$$FastClassBySpringCGLIB$$75ac0373.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$$Lambda$391/524684837.call(Unknown Source)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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)
Locked ownable synchronizers:
- <0x0000000741db91a0> (a java.util.concurrent.ThreadPoolExecutor$Worker)
"MyJobExecutor-1" #24 prio=5 os_prio=31 tid=0x00007fc7f5ff7800 nid=0xa403 waiting on condition [0x0000700004cec000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000742196c58> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:380)
at org.apache.http.pool.AbstractConnPool.access$200(AbstractConnPool.java:69)
at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:246)
- locked <0x00000007968318d8> (a org.apache.http.pool.AbstractConnPool$2)
at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:193)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:303)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:279)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:191)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
at com.xxx.util.HttpUtil.doGet(HttpUtil.java:97)
at com.xxx.util.HttpUtil.doGet(HttpUtil.java:70)
at
省略
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.transaction.interceptor.TransactionInterceptor$$Lambda$392/226041624.proceedWithInvocation(Unknown Source)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
at com.bfc.service.impl.LotteryHbkuai3MainServiceImpl$$EnhancerBySpringCGLIB$$4d3de61.publishPreByJob(<generated>)
at com.bfc.job.LotterySchedule.publishByJob(LotterySchedule.java:45)
at com.bfc.job.LotterySchedule$$FastClassBySpringCGLIB$$75ac0373.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$$Lambda$391/524684837.call(Unknown Source)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
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)
Locked ownable synchronizers:
- <0x0000000741da4a28> (a java.util.concurrent.ThreadPoolExecutor$Worker)
分析問題
通過棧資訊可以發現,基本上所有的執行緒都被阻塞了,都在wait;
重點看 MyJobExecutor-"
開頭的執行緒都在wait同一個lock,並且程式碼發生的地方是 HttpUtil.doGet
方法;
這麼看來好像是HttpUtil.doGet 發生了阻塞;然後分析問題程式碼,結果發現這個程式碼是這樣的
private static PoolingHttpClientConnectionManager connMgr;
private static RequestConfig requestConfig;
private static final int MAX_TIMEOUT = 7000;
private static CloseableHttpClient httpClient ;
static {
// 設定連線池
connMgr = new PoolingHttpClientConnectionManager();
// 設定連線池大小
connMgr.setMaxTotal(8);
connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
RequestConfig.Builder configBuilder = RequestConfig.custom();
// 設定連線超時
configBuilder.setConnectTimeout(MAX_TIMEOUT);
// 設定讀取超時
configBuilder.setSocketTimeout(MAX_TIMEOUT);
// 設定從連線池獲取連線例項的超時
configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
// 在提交請求之前 測試連線是否可用
configBuilder.setStaleConnectionCheckEnabled(true);
requestConfig = configBuilder.build();
httpClient = HttpClients.custom().setConnectionManager(connMgr).build();
}
/**
* 傳送 GET 請求(HTTP),不帶輸入資料
* @param url
* @return
*/
public static String doGet(String url) {
return doGet(url, new HashMap<String, Object>());
}
/**
* 傳送 GET 請求(HTTP),K-V形式
* @param url
* @param params
* @return
*/
public static String doGet(String url, Map<String, Object> params) {
String apiUrl = url;
StringBuffer param = new StringBuffer();
int i = 0;
for (String key : params.keySet()) {
if (i == 0) {
param.append("?");
}else {
param.append("&");
}
param.append(key).append("=").append(params.get(key));
i++;
}
apiUrl += param;
String result = null;
// HttpClient httpclient = new DefaultHttpClient();
try {
HttpGet httpPost = new HttpGet(apiUrl);
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = IOUtils.toString(instream, "UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
相關推薦
一場HttpClient呼叫未關閉流引發的問題
最近生產環境出現了一個問題,就是Job服務日誌好端端的不列印日誌了,服務也沒有掛, 現在將此次問題解決過程記錄下來~
問題描述
生產環境有一臺Job伺服器,是專門用來跑所有定時任務的,然後有一天發現定時任務好像沒有執行,所以上Job伺服器檢視日誌,結果發現的情況是: 最後
玩轉OpenCV 4.0(一):呼叫Dis光流演算法示例
玩轉OpenCV 4.0(一):呼叫Dis光流演算法示例
呼叫DIS光流的原始碼如下:
對應CMakelists如下:
呼叫DIS光流的原始碼如下:
#include "opencv2/core/utility.hpp"
new DefaultHttpClient過時處理建議和HTTP呼叫後關閉流處理
最近寫新的呼叫程式碼時候,發現專案中new DefaultHttpClient()例項過期很久了,翻了翻另一個生產專案呼叫端的程式碼也是如此,於是查閱了些資料,用新版本程式碼替換了手上專案的程式碼並且正常測試完、生產上也正常執行完,算是一次補習,特記錄下替換過程和呼叫完後的處理。
1:來看下原來的呼叫程式碼
繼承的愛恨情仇——一場鉆石引發的血案
pytho ID 這不 block c中 height 地方 頭發 16px 最近在看PHP手冊,發現了一個稀奇古怪的新玩意——trait。
這引起了我極大的興趣,由於PHP面向對象的部分有很大程度和Java類似,我就自覺不自覺地和Java對比著來
python資料查詢操作之 一場缺少db.commit()引發的血案……
---恢復內容開始---
最近大作業用到了python操作資料庫的內容。涉及的庫是pymmysql,我就不詳細介紹這個庫的操作了,直接奔入主題--->開整
背景:
涉及程式中一個實時檢視資料表中state欄位==1的功能,我把這個功能單
Java訪問許可權控制的使用不當,活生生地引發了一場血淋漓的慘案
人在什麼面前最容易失去抵抗力?
美色,算是一個,比如說西施的貢獻薄就是忍辱負重、以身報國、助越滅吳;金錢,算是另外一個,我們古人常說“錢乃身外之物,生不帶來死不帶去”,但我們又都知道“有錢能使鬼推磨”。
除去美色和金錢,我認為還有一個,就是讀者的認可——“二哥,你的文章真的很棒,我特別喜歡。希望能多多更新
小碼農的職場人生一:由張小平離職引發的一些吐槽
文 ▏村長好忙(訂閱號ID:xiejun_asp)
9月27日刷爆朋友圈的一篇文章 《離職能直接影響中國登月的人才,只配呆在國企底層》,雖然存在誇大其詞且很多細節不實,但是還是讓張小平離職登上了微博熱搜榜。引發了我一丟丟的小感觸,忍不住來說說我這幾年所經歷的職場。
01
—
個人成長
不
一場由一個s引發的鬱悶
最近想轉業從事android開發。因為2年前研究過。所以搭建環境什麼的都是從原始地址下載的基本沒有什麼困難。跑書店看到一本名為《第一行程式碼》的書。想買,但是發現網上有PDF版的(昨天發現其實竟然還有word版的)。發現上邊第二章有
記一場由於錯誤使用final宣告方法和CGLib引發的問題
前言:
近期發現某系統在業務高峰時,訪問量回突然下降,開發測試並抓包後發現是呼叫獲取城市列表功能時發生異常所致。下面是發現和解決問題的大概步驟:
1:分析程式碼,發現出問題的介面查詢的所有資料均已快取到redis中,然後查系統日誌,發現在這個時間點有大量的redis訪問超時。
2:問題比
Gitlab:一場“刪庫”血案引發的反思
過年期間,一條Gitlab誤刪資料的新聞佔領了各大科技網站的頭條。一切令人驚歎感慨,一切又讓人似曾相似。回首2016年,網路重大異常事件其實並不罕見。
<< 2016.03全球三分之二網站伺服器用的開源加密工具OpenSSL爆出“水牢漏洞”。<<
Android 4.0 中由ProGuard引發的一場血案
案件還原:
修改Android 4.0原始碼中的Setting,新增一項功能之後,在eng模式下編譯,一切正常,遂提交程式碼到伺服器。第二天,傳來噩耗,Setting上新新增的功能無法使用,一點選則報錯。
案件分析:
上傳程式碼之前,已經在本地編譯測試過,咋會有錯呢??!!管
小米華為強勢互懟!一場由“非常嚇人的技術”而引發的“血案”……
咳咳,眾位小夥伴們想必已經對小米在5月底的新品釋出會期待不已了吧!不過大家知道麼,在這麼重要的釋
遇到一個因socket未關閉引發的檔案控制代碼用完問題
“愛提踢斯”專案最近遇到一個問題,當FTP伺服器磁碟沒有空間時,裝置會不斷復位——這是測試人員反饋的。我們拿到log後,看到一個通訊所用的檔案開啟失敗。不斷列印Too many open file,然後超時裝置復位。同時我們看到資料庫檔案開啟失敗,無法寫入資料。一個現象,看
robotframework當執行用例只打開一次瀏覽器的情況下關閉之前未關閉的父視窗
小編起初想了很多方法去關閉之前開啟的視窗,例如,close browser,window.close();試了以後發現window.close();這個只能關閉當前的子視窗,這樣就不能完成接下來的用例測試了。後來嘗試萬能的js來嘗試解決這個問題,沒想到竟然成功了,不多說直接
一場由mknod引發的扯淡
我們註冊完字元、塊驅動裝置後,一般會用mknod去建立,應用層與驅動的管道。例如mtd的字元驅動,我們會用mknod /dev/mtdchar1 c 30 0,建立/dev/mtdchar1來對映mtd第一個字元裝置。
由於程式碼沒法紅字,程式碼中有color:#ff
一場precision引發的血案
Accelerated C++ 中文版中 第三章 3.1那個示例程式碼
#include <iomanip>
#include <ios>
#include <iostream>
#include <string>
using
IOUtils.closeQuietly:在finally中關閉流時不需要再catch一遍IOException
在使用 stream 的時,往往要 try catch IOException。eric教導我要把流的關閉放到 finally 中
一場由fork引發的超時,讓我們重新探討了Redis的抖動問題
摘要:一次由fork引發的時延抖動問題。
背景介紹
華為雲資料庫GaussDB(for Redis) 是一款基於計算儲存分離架構,相容Redis生態的雲原生NoSQL資料庫;它依靠共享儲存池實現了強一致,支援持久化落盤儲存,保證資料的安全可靠。其核心特點是:存算分離、強一致、低成本、超大容量。
GaussDB
今晚一場巔峰你對編程的認識分享會,再晚就不等你了
今晚一場巔峰你對編程的認識分享會 再晚就不等你了 本文出自 “知乎技術” 博客,請務必保留此出處http://liuzhiying.blog.51cto.com/5850988/1929819今晚一場巔峰你對編程的認識分享會,再晚就不等你了
以電競的名義,一場遊戲公益杯背後的思考
三星顯示器 在人類社會的發展秩序中,公益一直是連接人性與社會文明的紐帶。隨著社會的不斷進步以及新興事物的影響,這種契合關系形成的影響力除了在大眾群體層面持續發揚之外,在如今的各個領域也已經成為新的潮流,誕生了一些新模式、新打法。 6月13日,京東遊戲公益杯在北京舉行,電競和公益兩個看似毫不相幹的概念被捆綁