客戶調用批量查詢接口對Solr核進行查詢時覺得查詢響應時間有些慢,接口的内部實作目前是順序執行每個查詢,再把結果彙總起來傳回給調用方。是以,考慮引入線程池對查詢接口的内部實作進行重構優化。
先聲明一個大小可随之增長的線程池,
private ExecutorService executor = Executors.newCachedThreadPool();//查詢請求處理線程池
然後是主線程方法的代碼:
public List<Map<String, String>> queryEntityList(String entityCode, List<Long> idList) throws ServiceException {
複制代碼
List<Map<String, String>> finalResult = null;
if (idList == null || idList.size() == 0 || StringUtil.isBlank(entityCode)) {//參數合法性校驗
return finalResult;
}
finalResult = new ArrayList<Map<String, String>>();
List<Future<Map<String, String>>> futureList = new ArrayList<Future<Map<String, String>>>();
int threadNum = idList.size();//查詢子線程數目
for (int i = 0; i < threadNum; i++) {
Long itemId = idList.get(i);
Future<Map<String, String>> future = executor.submit(new QueryCallable (entityCode, itemId));
futureList.add(future);
for(Future<Map<String, String>> future : futureList) {
Map<String, String> threadResult = null;
try {
threadResult = future.get();
} catch (Exception e) {
threadResult = null;
}
if (null != threadResult && threadResult.size() > 0) {//結果集不為空
finalResult.add(threadResult);
return finalResult;
}
最後是具體負責處理每個查詢請求的Callable
複制代碼
public class QueryCallable implements Callable<Map<String, String>> {
private String entityCode = "";
private Long itemId = 0L;
public GetEntityListCallable(String entityCode, Long itemId) {
this. entityCode = entityCode;
this.itemId = itemId;
public Map<String, String> call() throws Exception {
Map<String, String> entityMap = null;
entityMap = QueryServiceImpl.this.getEntity(entityCode, itemId);//先去hbase查基本資訊
} catch (Exception e) {
entityMap = null;
return entityMap;
通過線程池的使用,可以減少建立,銷毀程序所帶來的系統開銷,而且線程池中的工作線程可以重複使用,極大地利用現有系統資源,增加了系統吞吐量。
另外,今天也嘗試了另一種合并Solr索引的方法,直接通過底層的Lucene的API進行,而不是送出Http請求,具體方法如下:
java -cp lucene-core-3.4.0.jar:lucene-misc-3.4.0.jar org/apache/lucene/misc/IndexMergeTool ./newindex ./app1/solr/data/index ./app2/solr/data/index
本文轉自Phinecos(洞庭散人)部落格園部落格,原文連結:http://www.cnblogs.com/phinecos/archive/2011/12/29/2306775.html,如需轉載請自行聯系原作者