給webflux增長緩存

上一篇中已經給用戶管理增長了頁面,看上去比較low,可是不犯該你們學習。今天增長redis來做爲緩存。

1 爲何要作緩存

當用戶訪問量增大的時候,併發量也會增大,同一時間數據庫查詢的壓力也會增大。儘管mongodb的查詢速度已經很快了,可是也會出現性能瓶頸,通常會經過集羣來解決。另外一方面就是增長緩存,使得不用每次查詢都要通過數據庫。提升響應速度。java

2 緩存策略

  • 在查詢方法中先從緩存中取,若是沒有則查詢數據庫
  • 在刪除方法中,同時刪除緩存中的值
  • 在更新操做中,同步修改緩存中的值

3 添加依賴

關於redis的安裝,我以前的文章中已經講過了,可關注個人公衆號mike啥都想搞在教程中查看。補充:
以前咱們講了如和設置redis的密碼,但是都不生效。是由於啓動方式不對,須要指定備至文件react

redis-server.exe redis.windows.conf
<!-- Spring Boot 響應式 Redis 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

設置redis鏈接:web

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=mike123
spring.redis.timeout=5000

4 改造service中的方法

package com.mike.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.mike.dao.UserDao;
import com.mike.po.User;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * The class UserService.java
 */
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    public Mono<User> saveOrUpdateUser(User user){
        //刪除緩存
        if (redisTemplate.hasKey("user_"+user.getId())) {
            redisTemplate.delete("user_"+user.getId());
        }
        return userDao.save(user);
    }
    
    public Mono<User> findById(String id){
        redisTemplate.opsForValue().set("test","test");
        //先查找緩存
        boolean hashKey = redisTemplate.hasKey("user_"+id);
        if (hashKey) {
            User u = (User) redisTemplate.opsForValue().get("user_"+id);
            return Mono.create(rs -> rs.success(u));
        }
        Mono<User> m = userDao.findById(id);
        if (m!=null) { //更新緩存
            m.subscribe(u -> {
                redisTemplate.opsForValue().set("user_"+u.getId(), u);
            });
        }
        return m;
    }
    
    public Flux<User> findAll(){
        return userDao.findAll().cache();
    }
    
    public  void deleteById(String id){
        // 使用mongoTemplate來作刪除   直接使用提供的刪除方法不行
        Query query = Query.query(Criteria.where("id").is(id));
        mongoTemplate.remove(query, User.class);
        //userDao.deleteById(id);  這樣沒法刪除,不知道爲何
        
        //同時刪除緩存
        if (redisTemplate.hasKey("user_"+id)) {
            redisTemplate.delete("user_"+id);
        }
    }
}

總結

通常咱們會和@cacheable註解配合使用,可是在webflux中,咱們須要手動編程來實現redis的數據存儲。緣由是Mono / Flux 對象沒有實現 Serializable。上面用的是同步操做redis,還有一個異步操做ReactiveRedisTemplate,可是由於咱們操做緩存的時候要先進行key的判斷後在執行後續操做,這是同步過程。使用ReactiveRedisTemplate的話感受操做比較麻煩,誰若是有好的寫法能夠一塊兒交流下。redis

填坑: User 對象須要實現Serializable,不然redis存儲會失敗。spring

相關文章
相關標籤/搜索