我已经实现了一个从mariadb数据库插入/更新solr索引的解决方案。
集成流包含以下组件:
一个简单的java应用程序,cli执行的入口点
充当rest客户机的java类
使用服务类的servlet
一个服务类,它实现从mariadb读取记录并插入/更新到solr索引中。
实现的流程如下所示:
java应用程序>rest客户端>servlet>服务>dao等
public final class BatchSolrApp {
private BatchSolrApp() {
//I am capturing start time using localtime API
BatchSolrClient batchSolrIndexingClient = new BatchSolrClient();
int statusCode = batchSolrIndexingClient.updateSolrIndex();
//This line returns before batch processing completes,
//所以我无法在这里捕获完成时间!}
public static void main(String[] args) {
try {
new BatchSolrApp();
} catch (Exception exception) {
//log.error('xxx'+exception.getMessage());
}
}
}
/**
* API Client to call batch solr reindex service via servlet.
*/
public class BatchSolrClient {
public int updateSolrIndex() {
HttpClient httpClient = httpLibCustom.createProvider(loggerHttpClient).createHttpClient();
String xxxUri = "www.xxx.org/aaa/bbbb?action=batchIndex&csrfToken=fakeCsrfToken";
HttpUrl xxxHttpUri = HttpUrl.parse(xxxUri);
Request request = new Request.Builder().url(xxxHttpUri).get().build();
HttpAPIResponse httpAPIResponse = null;
Response response = null;
try {
httpAPIResponse = httpClient.executeHttpRequest(request);
if (httpAPIResponse != null) {
response = httpAPIResponse.getResponse();
if (response != null) {
return response.code();
}
}
} catch (
Exception excResponse) {
logger.error("Exception xxxxxx : \n" +
exceptionStackTraceToString(excResponse));
return 206;
}
return 202;
}
}
public class BatchSolrServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
HashMap<String, String> params = SomeServletUtils.getServletParams(req,
resp, this);
ServletUtils.processRequest(this, req, resp, () -> new BatchSolrService(params));
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
doPost(req, resp);
}
}
/**
* Service to execute Batch Solr Indexing
*/
public class BatchSolrService extends SomeAbstractClass {
public BatchSolrIndexingService(HashMap<String, String> params) {
processRequest();
}
protected AbstractResponse processRequest() throws ServerException {
CustomJSONResponse response = new CustomJSONResponse(this.getFunction());
try {
List<String> productIdList = fetchAllProductIds();
if (productIdList != null && !productIdList.isEmpty()) {
//This read the records from MariaDB, creates SOLR docs from them and insert/add to SOLR
//Next line Uses the following logic amongst other code
//EmbeddedSolrServer server = SolrService.getSolrServer();
// server.add(doc)
boolean batchUpdateOutcome = XXXSolrService.addProductBatchToSolr(productIdList);
}
} catch (Exception batchIndexException) {
logger.error("XXX " +exceptionStackTraceToString(batchIndexException));
}
response.setStatusCode(201);
response.setSuccess();
return response;
super.setError("Error during batch solr indexing request handling.", 400);
return errorResponse;
}
}
上面的实现很有效,但我想对其进行改进。
此时,应用程序中的main()方法在批处理过程完成之前返回。但是,我希望集中跟踪批处理的进度,并相应地记录消息。由于从mariadb迁移到solr的记录量很大,批处理需要几个小时。
主应用程序在命令行上执行,摘录如下:
C:\XXXX\SSSS\AppHome\WEB-INF\lib >
java - cp "batchUtils.jar;*" a.b.c.d.BatchSolrApp
上面的jar将在部署新版本的应用程序后由operations手动执行,同时也没有问题。但是,简单的线程方法是受欢迎的。jar文件位于webapp的war文件的lib中!
请说明如何改进当前的解决方案,以便:
但是,我想集中跟踪批处理的进度,并相应地记录消息?
我可以跟踪批次的开始和完成时间。我现在通过在batchsolrapp中捕获开始时间和在batchsolrservice中捕获完成时间(在遍历所有记录并更新solr之后)来实现这一点?
如何从我的服务>客户端>主应用程序中最好地处理和传播http状态代码?
当从mariadb读取一些错误记录时,如何最好地处理异常。目前,我正在捕获异常,记录并移动到下一个记录。
我对一些建议和设计投入持开放态度。我想保留当前的main()java应用程序servlet组件。
采用servlet的原因是,现有的ui功能通过servlet与solr交互,并且实现cli入口点导致了solr索引的锁定。所以,我们想要一个进入solr引擎的单点,真的!
暂无答案!
目前还没有任何答案,快来回答吧!