From e4dd5bcb71524f8d05b25e1f0a5f0dbfb4724b28 Mon Sep 17 00:00:00 2001
From: xiongxiaoyang <773861846@qq.com>
Date: Mon, 25 May 2020 21:06:51 +0800
Subject: [PATCH] =?UTF-8?q?=E5=BC=95=E5=85=A5rabbitmq=E6=B5=81=E9=87=8F?=
 =?UTF-8?q?=E5=89=8A=E5=B3=B0=EF=BC=8C=E7=B4=AF=E7=A7=AF=E7=82=B9=E5=87=BB?=
 =?UTF-8?q?=E9=87=8F=E5=90=8E=E7=BB=9F=E4=B8=80=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java2nb/novel/core/cache/CacheKey.java    | 10 ++
 .../main/resources/application-common-dev.yml |  3 -
 novel-front/pom.xml                           |  5 +
 .../novel/controller/BookController.java      | 13 ++-
 .../novel/core/config/RabbitConfig.java       | 59 ++++++++++++
 .../core/listener/BookVisitAddListener.java   | 96 +++++++++++++++++++
 .../java2nb/novel/mapper/FrontBookMapper.java |  2 +-
 .../novel/service/impl/BookServiceImpl.java   |  2 +-
 .../src/main/resources/application.yml        | 12 +++
 .../resources/mybatis/mapping/BookMapper.xml  |  2 +-
 10 files changed, 197 insertions(+), 7 deletions(-)
 create mode 100644 novel-front/src/main/java/com/java2nb/novel/core/config/RabbitConfig.java
 create mode 100644 novel-front/src/main/java/com/java2nb/novel/core/listener/BookVisitAddListener.java

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 @@
             <version>${jjwt.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-amqp</artifactId>
+        </dependency>
+
 
         <dependency>
             <groupId>io.searchbox</groupId>
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<BookVO> searchByPage(BookSP params);
 
-    void addVisitCount(@Param("bookId") Long bookId, @Param("date") Date date);
+    void addVisitCount(@Param("bookId") Long bookId);
 
     List<Book> 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 @@
     </select>
 
     <update id="addVisitCount" >
-        update book set visit_count = visit_count + 1 , update_time = #{date}
+        update book set visit_count = visit_count + 1
         where id = #{bookId}
     </update>