如何改进我的java应用程序,将数百万条记录从mariadb数据库迁移到solr服务器

bybem2ql  于 2021-10-10  发布在  Java
关注(0)|答案(0)|浏览(206)

我已经实现了一个从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引擎的单点,真的!

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题