2 Commits 53b9e66958 ... 2aa87de813

Author SHA1 Message Date
  it_lv 2aa87de813 day11 3 weeks ago
  it_lv 3624156f0c day11 3 weeks ago
23 changed files with 414 additions and 11 deletions
  1. 2 0
      common/service-util/src/main/java/com/atguigu/tingshu/common/config/redis/RedissonConfig.java
  2. 1 1
      common/service-util/src/main/java/com/atguigu/tingshu/common/interceptor/FeignInterceptor.java
  3. 28 0
      service/canal-client-service/pom.xml
  4. 19 0
      service/canal-client-service/src/main/java/com/atguigu/tingshu/CanalClientApp.java
  5. 23 0
      service/canal-client-service/src/main/java/com/atguigu/tingshu/listener/UserListener.java
  6. 21 0
      service/canal-client-service/src/main/java/com/atguigu/tingshu/model/CDCEntity.java
  7. 8 0
      service/canal-client-service/src/main/resources/bootstrap.properties
  8. 2 0
      service/pom.xml
  9. 1 1
      service/service-album/src/main/java/com/atguigu/tingshu/ServiceAlbumApplication.java
  10. 24 2
      service/service-album/src/main/java/com/atguigu/tingshu/album/api/TestController.java
  11. 7 0
      service/service-album/src/main/java/com/atguigu/tingshu/album/service/TestService.java
  12. 2 0
      service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.java
  13. 59 0
      service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/TestServiceImpl.java
  14. 91 0
      service/service-album/src/main/java/com/atguigu/tingshu/album/task/RebuildBloomFilterTask.java
  15. 2 0
      service/service-album/src/main/resources/application.yml
  16. 9 7
      service/service-album/src/test/java/com/atguigu/tingshu/RedissonLockTest.java
  17. 29 0
      service/service-cdc/pom.xml
  18. 19 0
      service/service-cdc/src/main/java/com/atguigu/tingshu/CDCApplicaiton.java
  19. 35 0
      service/service-cdc/src/main/java/com/atguigu/tingshu/listener/UserListener.java
  20. 19 0
      service/service-cdc/src/main/java/com/atguigu/tingshu/model/CDCEntity.java
  21. 8 0
      service/service-cdc/src/main/resources/bootstrap.properties
  22. 2 0
      service/service-user/src/main/java/com/atguigu/tingshu/user/api/UserInfoApiController.java
  23. 3 0
      service/service-user/src/main/java/com/atguigu/tingshu/user/service/impl/UserInfoServiceImpl.java

+ 2 - 0
common/service-util/src/main/java/com/atguigu/tingshu/common/config/redis/RedissonConfig.java

@@ -42,6 +42,8 @@ public class RedissonConfig {
     RedissonClient redissonSingle() {
         Config config = new Config();
 
+        //修改默认看门狗/释放锁锁时间   默认加锁成功后:锁有效10s  底层看门狗执行定时任务延迟时间:10/3s
+        config.setLockWatchdogTimeout(10*1000);
         if (StringUtils.isBlank(host)) {
             throw new RuntimeException("host is  empty");
         }

+ 1 - 1
common/service-util/src/main/java/com/atguigu/tingshu/common/interceptor/FeignInterceptor.java

@@ -14,7 +14,7 @@ public class FeignInterceptor implements RequestInterceptor {
     public void apply(RequestTemplate requestTemplate){
         //  获取请求对象
         RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
-        //异步编排 与 MQ消费者端 为 null
+        //异步编排 定时任务 与 MQ消费者端 为 null
         if(null != requestAttributes) {
             ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)requestAttributes;
             HttpServletRequest request = servletRequestAttributes.getRequest();

+ 28 - 0
service/canal-client-service/pom.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>service</artifactId>
+        <groupId>com.atguigu.tingshu</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>canal-client-service</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.github.xizixuejie</groupId>
+            <artifactId>canal-spring-boot-starter</artifactId>
+            <version>0.0.17</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 19 - 0
service/canal-client-service/src/main/java/com/atguigu/tingshu/CanalClientApp.java

@@ -0,0 +1,19 @@
+package com.atguigu.tingshu;
+
+import io.xzxj.canal.spring.annotation.EnableCanalListener;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+/**
+ * @author: atguigu
+ * @create: 2025-03-21 15:46
+ */
+@EnableCanalListener
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+public class CanalClientApp {
+
+    public static void main(String[] args) {
+        SpringApplication.run(CanalClientApp.class, args);
+    }
+}

+ 23 - 0
service/canal-client-service/src/main/java/com/atguigu/tingshu/listener/UserListener.java

@@ -0,0 +1,23 @@
+package com.atguigu.tingshu.listener;
+
+import com.atguigu.tingshu.model.CDCEntity;
+import io.xzxj.canal.core.annotation.CanalListener;
+import io.xzxj.canal.core.listener.EntryListener;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.Set;
+
+/**
+ * @author: atguigu
+ * @create: 2025-03-21 15:47
+ */
+@Slf4j
+@CanalListener(destination = "tingshuTopic", schemaName = "tingshu_user", tableName = "user_info")
+public class UserListener implements EntryListener<CDCEntity> {
+
+    @Override
+    public void update(CDCEntity before, CDCEntity after, Set<String> fields) {
+        log.info("[cdc]监听到变更数据");
+        EntryListener.super.update(before, after, fields);
+    }
+}

+ 21 - 0
service/canal-client-service/src/main/java/com/atguigu/tingshu/model/CDCEntity.java

@@ -0,0 +1,21 @@
+package com.atguigu.tingshu.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Table;
+
+/**
+ *
+ * @author: atguigu
+ * @create: 2023-11-01 16:22
+ */
+@Data
+@TableName("user_info")
+@Table(name = "user_info")
+public class CDCEntity {
+
+    @Column(name = "id")
+    private Long id;
+}

+ 8 - 0
service/canal-client-service/src/main/resources/bootstrap.properties

@@ -0,0 +1,8 @@
+spring.application.name=service-canal
+spring.profiles.active=dev
+spring.main.allow-bean-definition-overriding=true
+spring.cloud.nacos.discovery.server-addr=192.168.200.6:8848
+spring.cloud.nacos.config.server-addr=192.168.200.6:8848
+spring.cloud.nacos.config.prefix=${spring.application.name}
+spring.cloud.nacos.config.file-extension=yaml
+spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml

+ 2 - 0
service/pom.xml

@@ -20,6 +20,8 @@
         <module>service-order</module>
         <module>service-payment</module>
         <module>service-user</module>
+        <module>canal-client-service</module>
+        <module>service-cdc</module>
     </modules>
 
     <dependencies>

+ 1 - 1
service/service-album/src/main/java/com/atguigu/tingshu/ServiceAlbumApplication.java

@@ -41,7 +41,7 @@ public class ServiceAlbumApplication implements CommandLineRunner {
         RBloomFilter<Long> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
         //2.如果布隆过滤器不存在则创建,完成初始化
         if (!bloomFilter.isExists()) {
-            bloomFilter.tryInit(100000L, 0.03);
+            bloomFilter.tryInit(10000L, 0.03);
         }
     }
 }

+ 24 - 2
service/service-album/src/main/java/com/atguigu/tingshu/album/api/TestController.java

@@ -1,6 +1,8 @@
 package com.atguigu.tingshu.album.api;
 
+import com.atguigu.tingshu.album.service.TestService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -14,11 +16,12 @@ import org.springframework.web.bind.annotation.RestController;
  */
 @Slf4j
 @RestController
-@RequestMapping("/api/test")
+@RequestMapping("/api/album/test")
 public class TestController {
 
     /**
      * SpringCache 将方法上缓存注解参数作为key 方法结果作为Value
+     *
      * @param id
      * @return
      */
@@ -31,11 +34,30 @@ public class TestController {
 
     /**
      * 情况缓存
+     *
      * @param id
      */
     @CacheEvict(value = "userCache", key = "#id")
     @GetMapping("/update/{id}")
-    public void updateUser(@PathVariable("id") Long id){
+    public void updateUser(@PathVariable("id") Long id) {
         log.info("根据ID更新取业务数据");
     }
+
+    @Autowired
+    private TestService testService;
+
+    @GetMapping("/read/{id}")
+    public String read(@PathVariable long id) {
+        String result = testService.read(id);
+        return "读数据成功:" + result;
+    }
+
+
+    @GetMapping("/write/{id}")
+    public String write(@PathVariable long id) {
+        testService.write(id);
+        return "写数据成功";
+    }
+
+
 }

+ 7 - 0
service/service-album/src/main/java/com/atguigu/tingshu/album/service/TestService.java

@@ -0,0 +1,7 @@
+package com.atguigu.tingshu.album.service;
+
+public interface TestService {
+    String read(long id);
+
+    void write(long id);
+}

+ 2 - 0
service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/AlbumInfoServiceImpl.java

@@ -278,6 +278,7 @@ public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo
         albumInfo.setId(id);
         baseMapper.updateById(albumInfo);
 
+
         //2.更新专辑标签关系表
         //2.1 根据专辑ID删除原有专辑标签关系
         albumAttributeValueMapper.delete(
@@ -295,6 +296,7 @@ public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo
                     }).collect(Collectors.toList());
             //批量保存
             albumAttributeValueService.saveBatch(albumAttributeValueList);
+
         }
 
         //4.对专辑中文本内容进行审核 异步审核

+ 59 - 0
service/service-album/src/main/java/com/atguigu/tingshu/album/service/impl/TestServiceImpl.java

@@ -0,0 +1,59 @@
+package com.atguigu.tingshu.album.service.impl;
+
+import com.atguigu.tingshu.album.service.TestService;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RLock;
+import org.redisson.api.RReadWriteLock;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author: atguigu
+ * @create: 2025-03-21 11:31
+ */
+@Slf4j
+@Service
+public class TestServiceImpl implements TestService {
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+
+    @Override
+    public String read(long id) {
+        //1.获取读写锁对象
+        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("lock:" + id);
+        //2.获取读锁
+        RLock lock = readWriteLock.readLock();
+        lock.lock(5, TimeUnit.SECONDS);
+        try {
+            //3.执行读数据业务
+            log.info("读锁加锁成功,执行读数据业务");
+            return "result:" + id;
+        } finally {
+            //4.释放读锁  TODO 故意不释放锁,等5后自动释放
+            //lock.unlock();
+        }
+    }
+
+    @Override
+    public void write(long id) {
+        //1.获取读写锁对象
+        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("lock:" + id);
+        RLock lock = readWriteLock.writeLock();
+
+        //2.获取写锁
+        lock.lock(5, TimeUnit.SECONDS);
+
+        //3.执行写数据业务
+        try {
+            log.info("写锁加锁成功,执行写数据业务");
+        } finally {
+            //4.释放写锁 TODO 故意不释放锁,等5后自动释放
+            //lock.unlock();
+        }
+    }
+}

+ 91 - 0
service/service-album/src/main/java/com/atguigu/tingshu/album/task/RebuildBloomFilterTask.java

@@ -0,0 +1,91 @@
+package com.atguigu.tingshu.album.task;
+
+import cn.hutool.core.collection.CollUtil;
+import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
+import com.atguigu.tingshu.common.constant.RedisConstant;
+import com.atguigu.tingshu.common.constant.SystemConstant;
+import com.atguigu.tingshu.model.album.AlbumInfo;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RBloomFilter;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author: atguigu
+ * @create: 2025-03-21 09:21
+ */
+@Slf4j
+@Component
+public class RebuildBloomFilterTask {
+
+    @Autowired
+    private AlbumInfoMapper albumInfoMapper;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    /**
+     * 重建布隆过滤器 TODO 后续改为xxl-job 定时+手动调度
+     * 周期:每月1号凌晨2点执行
+     */
+    //@Scheduled(cron = "0/10 * * * * ?")
+    @Scheduled(cron = "0 0 2 1 * ?")
+    public void rebuildBloomFilter() {
+        //1.处理扩容重建情况:布隆过滤器中元素数量大于期望数据规模,造成误判率就会上升
+        //1.1 获取"旧"的布隆过滤器对象 得到:期望数据规模、现有元素数量
+        RBloomFilter<Long> oldBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
+        long expectedInsertions = oldBloomFilter.getExpectedInsertions();
+        long count = oldBloomFilter.count();
+        double falseProbability = oldBloomFilter.getFalseProbability();
+        log.info("[专辑服务]触发重建布隆过滤器任务:现有期望数据规模:{},现有实际数据量:{}", expectedInsertions, count);
+        //1.2 如果满足实际元素数量大于期望数据量,需要扩容
+        if (count >= expectedInsertions) {
+            log.info("[专辑服务]布隆过滤器扩容");
+            //1.2.1 创建/初始化"新"的布隆过滤器 名称="旧":new  期望数据规模:原来的2倍
+            RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
+            newBloomFilter.tryInit(expectedInsertions * 2, falseProbability);
+            //1.2.2 将过审专辑ID加入到"新"布隆过滤器内
+            this.addDataToBloomFilter(newBloomFilter);
+            //1.2.3 删除"旧"布隆过滤器 删除配置以及产生位图
+            oldBloomFilter.delete();
+            //1.2.4 对"新"布隆过滤器重命名 改为"旧"的名称,此时数据已经新的了
+            newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
+        } else {
+            log.info("[专辑服务]布隆过滤器重建");
+            //2.不满足扩容条件:重建布隆过滤器.存在一些专辑被删除,被下架,被删除专辑ID仍然存在于布隆过滤器中。
+            //2.1 删除原有布隆过滤器,重新初始化新的
+            oldBloomFilter.delete();
+            RBloomFilter<Long> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
+            newBloomFilter.tryInit(expectedInsertions, falseProbability);
+            //2.2 将过审专辑ID加入到布隆过滤器中
+            this.addDataToBloomFilter(newBloomFilter);
+        }
+    }
+
+
+    /**
+     * 将审核通过专辑ID加入到布隆过滤器
+     *
+     * @param bloomFilter
+     */
+    private void addDataToBloomFilter(RBloomFilter<Long> bloomFilter) {
+        //1.根据审核条件查询过审专辑ID 得到专辑ID列表
+        List<AlbumInfo> albumInfoList = albumInfoMapper
+                .selectList(
+                        new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
+                                .select(AlbumInfo::getId)
+                );
+        if (CollUtil.isNotEmpty(albumInfoList)) {
+            //2.循环将专辑ID加入到布隆过滤器
+            albumInfoList
+                    .stream()
+                    .map(AlbumInfo::getId)
+                    .forEach(bloomFilter::add);
+        }
+    }
+}

+ 2 - 0
service/service-album/src/main/resources/application.yml

@@ -1,3 +1,5 @@
 spring:
   cache:
     type: redis # 缓存类型
+server:
+  port: 8501

+ 9 - 7
service/service-album/src/test/java/com/atguigu/tingshu/RedissonLockTest.java

@@ -7,6 +7,8 @@ import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * @author: atguigu
  * @create: 2025-03-19 10:27
@@ -37,13 +39,13 @@ public class RedissonLockTest {
         //if (flag) {
             try {
                 log.info(Thread.currentThread().getName()+"加锁成功,执行业务逻辑,查询数据库");
-                //TimeUnit.SECONDS.sleep(100);
-                lock.lock();
-                try {
-                    System.out.println(Thread.currentThread().getName()+"再次加锁成功,执行业务");
-                } finally {
-                    lock.unlock();
-                }
+                TimeUnit.SECONDS.sleep(100);
+                //lock.lock();
+                //try {
+                //    System.out.println(Thread.currentThread().getName()+"再次加锁成功,执行业务");
+                //} finally {
+                //    lock.unlock();
+                //}
 
 
                 //tod 执行业务代码

+ 29 - 0
service/service-cdc/pom.xml

@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>service</artifactId>
+        <groupId>com.atguigu.tingshu</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>service-cdc</artifactId>
+
+    <properties>
+        <maven.compiler.source>17</maven.compiler.source>
+        <maven.compiler.target>17</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>io.github.xizixuejie</groupId>
+            <artifactId>canal-spring-boot-starter</artifactId>
+            <version>0.0.17</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 19 - 0
service/service-cdc/src/main/java/com/atguigu/tingshu/CDCApplicaiton.java

@@ -0,0 +1,19 @@
+package com.atguigu.tingshu;
+
+import io.xzxj.canal.spring.annotation.EnableCanalListener;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+/**
+ * @author: atguigu
+ * @create: 2025-03-21 15:46
+ */
+@EnableCanalListener
+@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
+public class CDCApplicaiton {
+
+    public static void main(String[] args) {
+        SpringApplication.run(CDCApplicaiton.class, args);
+    }
+}

+ 35 - 0
service/service-cdc/src/main/java/com/atguigu/tingshu/listener/UserListener.java

@@ -0,0 +1,35 @@
+package com.atguigu.tingshu.listener;
+
+import com.atguigu.tingshu.model.CDCEntity;
+import io.xzxj.canal.core.annotation.CanalListener;
+import io.xzxj.canal.core.listener.EntryListener;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.Set;
+
+/**
+ * @author: atguigu
+ * @create: 2025-03-21 15:47
+ */
+@Slf4j
+@CanalListener(destination = "tingshuTopic", schemaName = "tingshu_user", tableName = "user_info")
+public class UserListener implements EntryListener<CDCEntity> {
+
+    @Autowired
+    private RedisTemplate redisTemplate;
+
+    /**
+     * 监听用户表更新回调方法
+     * @param before
+     * @param after
+     * @param fields
+     */
+    @Override
+    public void update(CDCEntity before, CDCEntity after, Set<String> fields) {
+        log.info("[cdc]监听到变更数据");
+        String redisKey = "user:userinfo:"+after.getId();
+        redisTemplate.delete(redisKey);
+    }
+}

+ 19 - 0
service/service-cdc/src/main/java/com/atguigu/tingshu/model/CDCEntity.java

@@ -0,0 +1,19 @@
+package com.atguigu.tingshu.model;
+
+import lombok.Data;
+
+import javax.persistence.Column;
+import javax.persistence.Table;
+
+/**
+ *
+ * @author: atguigu
+ * @create: 2023-11-01 16:22
+ */
+@Data
+@Table(name = "user_info")
+public class CDCEntity {
+
+    @Column(name = "id")
+    private Long id;
+}

+ 8 - 0
service/service-cdc/src/main/resources/bootstrap.properties

@@ -0,0 +1,8 @@
+spring.application.name=service-canal
+spring.profiles.active=dev
+spring.main.allow-bean-definition-overriding=true
+spring.cloud.nacos.discovery.server-addr=192.168.200.6:8848
+spring.cloud.nacos.config.server-addr=192.168.200.6:8848
+spring.cloud.nacos.config.prefix=${spring.application.name}
+spring.cloud.nacos.config.file-extension=yaml
+spring.cloud.nacos.config.shared-configs[0].data-id=common.yaml

+ 2 - 0
service/service-user/src/main/java/com/atguigu/tingshu/user/api/UserInfoApiController.java

@@ -1,6 +1,7 @@
 package com.atguigu.tingshu.user.api;
 
 import com.atguigu.tingshu.common.cache.GuiGuCache;
+import com.atguigu.tingshu.common.login.GuiGuLogin;
 import com.atguigu.tingshu.common.result.Result;
 import com.atguigu.tingshu.user.service.UserInfoService;
 import com.atguigu.tingshu.vo.user.UserInfoVo;
@@ -38,6 +39,7 @@ public class UserInfoApiController {
      * @param needCheckBuyStateTrackIds
      * @return
      */
+    @GuiGuLogin
     @Operation(summary = "根据专辑ID+声音ID列表查询得到声音购买情况")
     @PostMapping("/userInfo/userIsPaidTrack/{userId}/{albumId}")
     public Result<Map<Long, Integer>> userIsPaidTrack(

+ 3 - 0
service/service-user/src/main/java/com/atguigu/tingshu/user/service/impl/UserInfoServiceImpl.java

@@ -134,12 +134,15 @@ public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> i
      */
     @Override
     public void updateUser(UserInfoVo userInfoVo) {
+        //1.TODO 删除缓存
         Long userId = AuthContextHolder.getUserId();
         UserInfo userInfo = baseMapper.selectById(userId);
         //注意:只允许修改部分信息
         userInfo.setNickname(userInfoVo.getNickname());
         userInfo.setAvatarUrl(userInfoVo.getAvatarUrl());
         baseMapper.updateById(userInfo);
+        //3.TODO 睡眠一段时间 确保并发读线程执行完毕,将"脏"数据写回Redis
+        //4.TODO 再删除一次缓存
     }
 
     /**