给webflux增加缓存

栏目: ASP.NET · 发布时间: 7年前

内容简介:上一篇中已经给用户管理增加了页面,看上去比较low,但是不犯该大家学习。今天增加redis来作为缓存。当用户访问量增大的时候,并发量也会增大,同一时间数据库查询的压力也会增大。尽管mongodb的查询速度已经很快了,但是也会出现性能瓶颈,一般会通过集群来解决。另一方面就是增加缓存,使得不用每次查询都要经过数据库。提高响应速度。关于redis的安装,我之前的文章中已经讲过了,可关注我的公众号

上一篇中已经给用户管理增加了页面,看上去比较low,但是不犯该大家学习。今天增加 redis 来作为缓存。

1 为什么要做缓存

当用户访问量增大的时候,并发量也会增大,同一时间数据库查询的压力也会增大。尽管 mongodb 的查询速度已经很快了,但是也会出现性能瓶颈,一般会通过集群来解决。另一方面就是增加缓存,使得不用每次查询都要经过数据库。提高响应速度。

2 缓存策略

  • 在查询方法中先从缓存中取,如果没有则查询数据库
  • 在删除方法中,同时删除缓存中的值
  • 在更新操作中,同步修改缓存中的值

3 添加依赖

关于redis的安装,我之前的文章中已经讲过了,可关注我的公众号 mike啥都想搞 在教程中查看。补充:

之前我们讲了如和设置redis的密码,可是都不生效。是因为启动方式不对,需要指定备至文件

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连接:

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 的话感觉操作比较麻烦,谁如果有好的写法可以一起交流下。

填坑: User 对象需要实现Serializable,否则redis存储会失败。


以上所述就是小编给大家介绍的《给webflux增加缓存》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Programming Python

Programming Python

Mark Lutz / O'Reilly Media / 2006-8-30 / USD 59.99

Already the industry standard for Python users, "Programming Python" from O'Reilly just got even better. This third edition has been updated to reflect current best practices and the abundance of chan......一起来看看 《Programming Python》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具