关于Solr定时更新的那些事

关于Solr定时更新的那些事

Solr这个东西,本身已经是完美的存在了。但是。。。这个完美也只是暂时的。
就目前而言,我们经常遇到的定时更新问题,有大触早就解决了,不知道的去问度娘去。

然而,我们通常会给Solr添加权限控制。这里就会遇到一个问题,就是权限,因为目前定时更新支持的版本是solr5以及solr6的,然而,我看了一下这两个版本都不支持权限控制状态下的定时更新。

我有尝试在properties中添加server={username}:{password}@{url}的方式,然而并没有什么卵用,查看了一下log日志,依然报的是401权限错误。

我查看了他的源码,发现他底层依然是调用http请求来更新solr
这里写图片描述
截屏自
https://github.com/mbonaci/solr-data-import-scheduler/blob/master/org/apache/solr/handler/dataimport/scheduler/HttpPostScheduler.java

因为Solr搜索可以直接get获取,由此,我猜想可否get更新数据。

尝试讲log日志中的fullURL复制到地址栏执行,发现的确可行,由此我直接想到用定时器,定时执行一次这个URL。

首先spring boot启用定时器
这里写图片描述

需要引用到的配置文件

solr.dataImportUrl1=http://admin:admin@127.0.0.1:8983/solr/project
solr.dataImportUrl2=http://admin:admin@127.0.0.1:8983/solr/project2

由spring boot管理HTTP连接池

// HttpConnectionManager.java

import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.net.ssl.SSLContext;
import java.security.NoSuchAlgorithmException;

/**
 * Http 连接池,用于solr更新,主要是模仿浏览器操作
 **/
@Component
public class HttpConnectionManager {

    PoolingHttpClientConnectionManager cm = null;

    @PostConstruct
    public void init() {
        LayeredConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }


        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        cm.setMaxTotal(200);
        cm.setDefaultMaxPerRoute(20);
    }

    public CloseableHttpClient getHttpClient() {
        CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(cm)
                .build();

        /*CloseableHttpClient httpClient = HttpClients.createDefault();//如果不采用连接池就是这种方式获取连接*/
        return httpClient;
    }
}

然后添加定时器
这里写图片描述

// SolrDeltaImport.java
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * Solr增量更新定时器管理
 **/
@Component
public class SolrDeltaImport {
    @Autowired
    private static final Logger log = LoggerFactory.getLogger(SolrClientConfiguration.class);

    @Autowired
    private HttpConnectionManager connManager;
    @Value("${solr.dataImportUrl1}")
    private String dataImportUrl1;
    @Value("${solr.dataImportUrl2}")
    private String dataImportUrl2;

    @Scheduled(cron = "0 0/2 * * * ?")// 每2分钟执行一次
    public void sendDeltaImport(){
        this.deltaImport(dataImportUrl1);
        this.deltaImport(dataImportUrl2);
    }

    /**
     * 增量更新发送请求,并接受结果
     */
    private void deltaImport(String url) {
        // 通过连接池获取客户端,节省了资源
        CloseableHttpClient client = connManager.getHttpClient();
        // 生成HTTP客户端
        // HttpClient client = new DefaultHttpClient();
        // 接受返回结果
        CloseableHttpResponse response = null;
        try {
            // 设置地址
            HttpPost post = new HttpPost(String.format("%s/dataimport?command=delta-import&clean=false&commit=true", url));
            // 发送请求
            response = client.execute(post);
            // 接受回传结果
            if (response.getStatusLine().getStatusCode() == 200) {
                log.debug("===> Solr增量更新成功");
            } else {
                log.error(String.format("===> Solr增量更新失败[%s]", response.getStatusLine().getStatusCode()));
            }
        } catch (Exception ex) {
            log.error("===> Solr增量更新发送请求异常", ex);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

url基本是这样的
这里写图片描述
http://{username}:{password}@{solrUrl}:{solrPort}/{webapp}/{Core}/{params}
例如:
http://admin:admin1234@127.0.0.1:8983/solr/solrProject/dataimport?commit=true&clean=false&command=delta-import
这个是简化后的URL

这个链接应该可以直接地址访问
这里写图片描述

之后也可以自行查询一下看看有无效果

这之后就是运行项目了,项目部署之后会每隔2分钟发一次请求,更新数据,也可以自行设置时间。

增量更新会了,全量更新直接照葫芦画瓢就是咯
http://admin:admin1234@127.0.0.1:8983/solr/solrProject/dataimport?commit=true&clean=true&command=full-import

// SolrDeltaImport.java

    @Scheduled(cron = "0 0 0/1 * * ?")// 每一小时执行一次
    public void sendFullImport(){
        this.fullImport(dataImportUrl1);
        this.fullImport(dataImportUrl2);
    }

    /**
     * 全量更新发送请求,并接受结果
     */
    private void fullImport(String url) {
        // 通过连接池获取客户端,节省了资源
        CloseableHttpClient client = connManager.getHttpClient();
        // 生成HTTP客户端
        // HttpClient client = new DefaultHttpClient();
        // 接受返回结果
        CloseableHttpResponse response = null;
        try {
            // 设置地址
            HttpPost post = new HttpPost(String.format("%s/dataimport?command=full-import&clean=true&commit=true", url));
            // 发送请求
            response = client.execute(post);
            // 接受回传结果
            if (response.getStatusLine().getStatusCode() == 200) {
                log.debug("===> Solr全量更新成功");
            } else {
                log.error(String.format("===> Solr全量更新失败[%s]", response.getStatusLine().getStatusCode()));
            }
        } catch (Exception ex) {
            log.error("===> Solr全量更新发送请求异常", ex);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

当然,因为是全量更新,statusMessages显示的不是Indexing completed,而是Processed。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值