From 220068cd3ae993dabaf15f00bcefbc53d5ca2ba6 Mon Sep 17 00:00:00 2001 From: xiongxiaoyang <773861846@qq.com> Date: Tue, 31 May 2022 14:03:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=9B=86=E6=88=90=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E4=BB=BB=E5=8A=A1=E8=B0=83=E5=BA=A6=20XXL-JOB?= =?UTF-8?q?=EF=BC=8C=20=E4=BC=98=E5=8C=96=20Elasticsearch=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=90=8C=E6=AD=A5=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 ++ .../novel/core/config/XxlJobConfig.java | 44 +++++++++++ .../core/listener/RabbitQueueListener.java | 2 +- .../xxyopen/novel/core/task/BookToEsTask.java | 78 ++++++++++--------- .../service/impl/EsSearchServiceImpl.java | 6 ++ src/main/resources/application.yml | 15 ++++ 6 files changed, 115 insertions(+), 37 deletions(-) create mode 100644 src/main/java/io/github/xxyopen/novel/core/config/XxlJobConfig.java diff --git a/pom.xml b/pom.xml index 47b6466..675e55a 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ 6.0.0-SNAPSHOT 0.11.5 8.2.0 + 2.3.1 @@ -116,6 +117,12 @@ spring-boot-starter-amqp + + com.xuxueli + xxl-job-core + ${xxl-job.version} + + mysql mysql-connector-java diff --git a/src/main/java/io/github/xxyopen/novel/core/config/XxlJobConfig.java b/src/main/java/io/github/xxyopen/novel/core/config/XxlJobConfig.java new file mode 100644 index 0000000..4084cf2 --- /dev/null +++ b/src/main/java/io/github/xxyopen/novel/core/config/XxlJobConfig.java @@ -0,0 +1,44 @@ +package io.github.xxyopen.novel.core.config; + +import com.xxl.job.core.executor.impl.XxlJobSpringExecutor; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * XXL-JOB 配置类 + * + * @author xiongxiaoyang + * @date 2022/5/31 + */ +@Configuration +@Slf4j +public class XxlJobConfig { + + @Value("${xxl.job.admin.addresses}") + private String adminAddresses; + + @Value("${xxl.job.accessToken}") + private String accessToken; + + @Value("${xxl.job.executor.appname}") + private String appname; + + @Value("${xxl.job.executor.logpath}") + private String logPath; + + @Bean + public XxlJobSpringExecutor xxlJobExecutor() { + log.info(">>>>>>>>>>> xxl-job config init."); + XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor(); + xxlJobSpringExecutor.setAdminAddresses(adminAddresses); + xxlJobSpringExecutor.setAccessToken(accessToken); + xxlJobSpringExecutor.setAppname(appname); + xxlJobSpringExecutor.setLogPath(logPath); + return xxlJobSpringExecutor; + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/xxyopen/novel/core/listener/RabbitQueueListener.java b/src/main/java/io/github/xxyopen/novel/core/listener/RabbitQueueListener.java index 55d82f2..1d0971f 100644 --- a/src/main/java/io/github/xxyopen/novel/core/listener/RabbitQueueListener.java +++ b/src/main/java/io/github/xxyopen/novel/core/listener/RabbitQueueListener.java @@ -21,7 +21,7 @@ import org.springframework.stereotype.Component; * @date 2022/5/25 */ @Component -@ConditionalOnProperty(prefix = "spring.elasticsearch", name = "enable", havingValue = "true") +@ConditionalOnProperty(prefix = "spring", name = {"elasticsearch.enable","amqp.enable"}, havingValue = "true") @RequiredArgsConstructor @Slf4j public class RabbitQueueListener { diff --git a/src/main/java/io/github/xxyopen/novel/core/task/BookToEsTask.java b/src/main/java/io/github/xxyopen/novel/core/task/BookToEsTask.java index a456e38..69704c5 100644 --- a/src/main/java/io/github/xxyopen/novel/core/task/BookToEsTask.java +++ b/src/main/java/io/github/xxyopen/novel/core/task/BookToEsTask.java @@ -6,6 +6,8 @@ import co.elastic.clients.elasticsearch.core.BulkRequest; import co.elastic.clients.elasticsearch.core.BulkResponse; import co.elastic.clients.elasticsearch.core.bulk.BulkResponseItem; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; import io.github.xxyopen.novel.core.constant.DatabaseConsts; import io.github.xxyopen.novel.core.constant.EsConsts; import io.github.xxyopen.novel.dao.entity.BookInfo; @@ -15,7 +17,6 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.List; @@ -40,49 +41,54 @@ public class BookToEsTask { * 每月凌晨做一次全量数据同步 */ @SneakyThrows - @Scheduled(cron = "0 0 0 1 * ?") - public void saveToEs() { + @XxlJob("saveToEsJobHandler") + public ReturnT saveToEs() { - QueryWrapper queryWrapper = new QueryWrapper<>(); - List bookInfos; - long maxId = 0; - for(;;) { - queryWrapper.clear(); - queryWrapper - .orderByAsc(DatabaseConsts.CommonColumnEnum.ID.getName()) - .gt(DatabaseConsts.CommonColumnEnum.ID.getName(), maxId) - .last(DatabaseConsts.SqlEnum.LIMIT_30.getSql()); - bookInfos = bookInfoMapper.selectList(queryWrapper); - if (bookInfos.isEmpty()) { - break; - } - BulkRequest.Builder br = new BulkRequest.Builder(); + try { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List bookInfos; + long maxId = 0; + for (; ; ) { + queryWrapper.clear(); + queryWrapper + .orderByAsc(DatabaseConsts.CommonColumnEnum.ID.getName()) + .gt(DatabaseConsts.CommonColumnEnum.ID.getName(), maxId) + .gt(DatabaseConsts.BookTable.COLUMN_WORD_COUNT, 0) + .last(DatabaseConsts.SqlEnum.LIMIT_30.getSql()); + bookInfos = bookInfoMapper.selectList(queryWrapper); + if (bookInfos.isEmpty()) { + break; + } + BulkRequest.Builder br = new BulkRequest.Builder(); - for (BookInfo book : bookInfos) { - br.operations(op -> op - .index(idx -> idx - .index(EsConsts.BookIndex.INDEX_NAME) - .id(book.getId().toString()) - .document(EsBookDto.build(book)) - ) - ).timeout(Time.of(t -> t.time("10s"))); - maxId = book.getId(); - } + for (BookInfo book : bookInfos) { + br.operations(op -> op + .index(idx -> idx + .index(EsConsts.BookIndex.INDEX_NAME) + .id(book.getId().toString()) + .document(EsBookDto.build(book)) + ) + ).timeout(Time.of(t -> t.time("10s"))); + maxId = book.getId(); + } - BulkResponse result = elasticsearchClient.bulk(br.build()); + BulkResponse result = elasticsearchClient.bulk(br.build()); - // Log errors, if any - if (result.errors()) { - log.error("Bulk had errors"); - for (BulkResponseItem item : result.items()) { - if (item.error() != null) { - log.error(item.error().reason()); + // Log errors, if any + if (result.errors()) { + log.error("Bulk had errors"); + for (BulkResponseItem item : result.items()) { + if (item.error() != null) { + log.error(item.error().reason()); + } } } } - + return ReturnT.SUCCESS; + } catch (Exception e) { + log.error(e.getMessage(), e); + return ReturnT.FAIL; } - } } diff --git a/src/main/java/io/github/xxyopen/novel/service/impl/EsSearchServiceImpl.java b/src/main/java/io/github/xxyopen/novel/service/impl/EsSearchServiceImpl.java index 705f467..d977947 100644 --- a/src/main/java/io/github/xxyopen/novel/service/impl/EsSearchServiceImpl.java +++ b/src/main/java/io/github/xxyopen/novel/service/impl/EsSearchServiceImpl.java @@ -109,6 +109,12 @@ public class EsSearchServiceImpl implements SearchService { BoolQuery boolQuery = BoolQuery.of(b -> { + // 只查有字数的小说 + b.must(RangeQuery.of(m -> m + .field(EsConsts.BookIndex.FIELD_WORD_COUNT) + .gt(JsonData.of(0)) + )._toQuery()); + if (!StringUtils.isBlank(condition.getKeyword())) { // 关键词匹配 b.must((q -> q.multiMatch(t -> t diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 41e220b..2492763 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -58,6 +58,21 @@ spring: # 第一次和第二次重试之间的持续时间 initial-interval: "3s" +# XXL-JOB 配置 +xxl: + job: + admin: + ### 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册; + addresses: http://127.0.0.1:8080/xxl-job-admin + executor: + ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 + appname: xxl-job-executor-novel + ### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; + logpath: logs/xxl-job/jobhandler + ### xxl-job, access token + accessToken: 123 + + --- spring: config: