diff --git a/novel-common/src/main/java/com/java2nb/novel/core/cache/CacheKey.java b/novel-common/src/main/java/com/java2nb/novel/core/cache/CacheKey.java index d284646..75a585a 100644 --- a/novel-common/src/main/java/com/java2nb/novel/core/cache/CacheKey.java +++ b/novel-common/src/main/java/com/java2nb/novel/core/cache/CacheKey.java @@ -55,4 +55,14 @@ public interface CacheKey { * 搜索引擎转换锁 * */ String ES_TRANS_LOCK = "esTransLock"; + + /** + * 上一次搜索引擎是否更新过小说点击量 + * */ + String ES_IS_UPDATE_VISIT = "esIsUpdateVisit"; + + /** + * 累积的小说点击量 + * */ + String BOOK_ADD_VISIT_COUNT = "bookAddVisitCount"; } \ No newline at end of file diff --git a/novel-common/src/main/resources/application-common-dev.yml b/novel-common/src/main/resources/application-common-dev.yml index 3c0f59c..9e48caa 100644 --- a/novel-common/src/main/resources/application-common-dev.yml +++ b/novel-common/src/main/resources/application-common-dev.yml @@ -28,9 +28,6 @@ spring: - - - pic: save: type: 2 #图片保存方式, 1不保存,使用网络图片 ,2本地保存 diff --git a/novel-front/pom.xml b/novel-front/pom.xml index a3c6484..b83ffcb 100644 --- a/novel-front/pom.xml +++ b/novel-front/pom.xml @@ -27,6 +27,11 @@ ${jjwt.version} + + org.springframework.boot + spring-boot-starter-amqp + + io.searchbox diff --git a/novel-front/src/main/java/com/java2nb/novel/controller/BookController.java b/novel-front/src/main/java/com/java2nb/novel/controller/BookController.java index 4545c71..88bacbb 100644 --- a/novel-front/src/main/java/com/java2nb/novel/controller/BookController.java +++ b/novel-front/src/main/java/com/java2nb/novel/controller/BookController.java @@ -12,6 +12,8 @@ import com.java2nb.novel.service.BookService; import com.java2nb.novel.vo.BookVO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -33,6 +35,11 @@ public class BookController extends BaseController{ private final BookService bookService; + private final RabbitTemplate rabbitTemplate; + + @Value("${spring.rabbitmq.enable}") + private Integer enableMq; + /** * 查询首页小说设置列表数据 @@ -105,7 +112,11 @@ public class BookController extends BaseController{ * */ @PostMapping("addVisitCount") public ResultBean addVisitCount(Long bookId){ - bookService.addVisitCount(bookId); + if(enableMq == 1) { + rabbitTemplate.convertAndSend("ADD-BOOK-VISIT-EXCHANGE", null, bookId); + }else { + bookService.addVisitCount(bookId); + } return ResultBean.ok(); } diff --git a/novel-front/src/main/java/com/java2nb/novel/core/config/RabbitConfig.java b/novel-front/src/main/java/com/java2nb/novel/core/config/RabbitConfig.java new file mode 100644 index 0000000..2e86481 --- /dev/null +++ b/novel-front/src/main/java/com/java2nb/novel/core/config/RabbitConfig.java @@ -0,0 +1,59 @@ +package com.java2nb.novel.core.config; + +import org.springframework.amqp.core.*; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author 11797 + */ +@Configuration +@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "enable", havingValue = "1") +public class RabbitConfig { + + + /** + * 更新数据库队列 + */ + @Bean + public Queue updateDbQueue() { + return new Queue("UPDATE-DB-QUEUE", true); + } + + /** + * 更新数据库队列 + */ + @Bean + public Queue updateEsQueue() { + return new Queue("UPDATE-ES-QUEUE", true); + } + + + /** + * 增加点击量交换机 + */ + @Bean + public FanoutExchange addVisitExchange() { + return new FanoutExchange("ADD-BOOK-VISIT-EXCHANGE"); + } + + /** + * 更新搜索引擎队列绑定到增加点击量交换机中 + */ + @Bean + public Binding updateEsBinding() { + + return BindingBuilder.bind(updateEsQueue()).to(addVisitExchange()); + } + + /** + * 更新数据库绑定到增加点击量交换机中 + */ + @Bean + public Binding updateDbBinding() { + return BindingBuilder.bind(updateDbQueue()).to(addVisitExchange()); + } + + +} diff --git a/novel-front/src/main/java/com/java2nb/novel/core/listener/BookVisitAddListener.java b/novel-front/src/main/java/com/java2nb/novel/core/listener/BookVisitAddListener.java new file mode 100644 index 0000000..fd0fadf --- /dev/null +++ b/novel-front/src/main/java/com/java2nb/novel/core/listener/BookVisitAddListener.java @@ -0,0 +1,96 @@ +package com.java2nb.novel.core.listener; + +import com.java2nb.novel.core.cache.CacheKey; +import com.java2nb.novel.core.cache.CacheService; +import com.java2nb.novel.entity.Book; +import com.java2nb.novel.service.BookService; +import com.java2nb.novel.vo.EsBookVO; +import com.rabbitmq.client.Channel; +import io.searchbox.client.JestClient; +import io.searchbox.core.Index; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.core.Message; +import org.springframework.beans.BeanUtils; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import org.springframework.amqp.rabbit.annotation.RabbitListener; + + +import java.text.SimpleDateFormat; + + +/** + * @author 11797 + */ +@Component +@Slf4j +@RequiredArgsConstructor +@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "enable", havingValue = "1") +public class BookVisitAddListener { + + private final BookService bookService; + + private final CacheService cacheService; + + private final JestClient jestClient; + + + + + /** + * 更新数据库 + * 流量削峰,每本小说1个小时更新一次 + */ + @SneakyThrows + @RabbitListener(queues = {"UPDATE-DB-QUEUE"}) + public void updateDb(Long bookId, Channel channel, Message message) { + + log.debug("收到更新数据库消息:" + bookId); + Thread.sleep(1000 * 2); + Integer visitCount = (Integer) cacheService.getObject(CacheKey.BOOK_ADD_VISIT_COUNT+bookId); + if(visitCount == null){ + visitCount = 0 ; + } + cacheService.setObject(CacheKey.BOOK_ADD_VISIT_COUNT+bookId,++visitCount); + if(cacheService.get(CacheKey.ES_IS_UPDATE_VISIT + bookId) == null) { + bookService.addVisitCount(bookId); + } + + } + + /** + * 更新搜索引擎 + * 流量削峰,每本小说1个小时更新一次 + */ + @RabbitListener(queues = {"UPDATE-ES-QUEUE"}) + public void updateEs(Long bookId, Channel channel, Message message) { + + log.debug("收到更新搜索引擎消息:" + bookId); + if (cacheService.get(CacheKey.ES_IS_UPDATE_VISIT + bookId) == null) { + cacheService.set(CacheKey.ES_IS_UPDATE_VISIT + bookId, "1", 60 * 60); + try { + Thread.sleep(1000 * 5); + Book book = bookService.queryBookDetail(bookId); + EsBookVO esBookVO = new EsBookVO(); + BeanUtils.copyProperties(book, esBookVO, "lastIndexUpdateTime"); + esBookVO.setLastIndexUpdateTime(new SimpleDateFormat("yyyy/MM/dd HH:mm").format(book.getLastIndexUpdateTime())); + Index action = new Index.Builder(esBookVO).index("novel").type("book").id(book.getId().toString()).build(); + jestClient.execute(action); + cacheService.set(CacheKey.ES_IS_UPDATE_VISIT + bookId, "1", 60 * 60); + }catch (Exception e){ + cacheService.del(CacheKey.ES_IS_UPDATE_VISIT + bookId); + log.error("更新搜索引擎失败"+bookId); + } + + + + + } + + + } + + +} diff --git a/novel-front/src/main/java/com/java2nb/novel/mapper/FrontBookMapper.java b/novel-front/src/main/java/com/java2nb/novel/mapper/FrontBookMapper.java index b5a0744..c51c7ef 100644 --- a/novel-front/src/main/java/com/java2nb/novel/mapper/FrontBookMapper.java +++ b/novel-front/src/main/java/com/java2nb/novel/mapper/FrontBookMapper.java @@ -16,7 +16,7 @@ public interface FrontBookMapper extends BookMapper { List searchByPage(BookSP params); - void addVisitCount(@Param("bookId") Long bookId, @Param("date") Date date); + void addVisitCount(@Param("bookId") Long bookId); List listRecBookByCatId(@Param("catId") Integer catId); diff --git a/novel-front/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java b/novel-front/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java index d3fd623..803ad08 100644 --- a/novel-front/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java +++ b/novel-front/src/main/java/com/java2nb/novel/service/impl/BookServiceImpl.java @@ -480,7 +480,7 @@ public class BookServiceImpl implements BookService { @Override public void addVisitCount(Long bookId) { - bookMapper.addVisitCount(bookId, new Date()); + bookMapper.addVisitCount(bookId); } @Override diff --git a/novel-front/src/main/resources/application.yml b/novel-front/src/main/resources/application.yml index f191056..8c6aa6a 100644 --- a/novel-front/src/main/resources/application.yml +++ b/novel-front/src/main/resources/application.yml @@ -7,6 +7,18 @@ spring: include: alipay + rabbitmq: + enable: 0 + host: 127.0.0.1 + username: guest + password: guest + virtual-host: /novel-plus + template: + # 缺省的交换机名称,此处配置后,发送消息如果不指定交换机就会使用这个 + exchange: novel.exchange + publisher-confirms: false + + elasticsearch: #是否开启搜索引擎,1:开启,0:不开启 enable: 0 diff --git a/novel-front/src/main/resources/mybatis/mapping/BookMapper.xml b/novel-front/src/main/resources/mybatis/mapping/BookMapper.xml index 5833f22..a43f85d 100644 --- a/novel-front/src/main/resources/mybatis/mapping/BookMapper.xml +++ b/novel-front/src/main/resources/mybatis/mapping/BookMapper.xml @@ -35,7 +35,7 @@ - update book set visit_count = visit_count + 1 , update_time = #{date} + update book set visit_count = visit_count + 1 where id = #{bookId}